对于贪吃蛇程序的拓展

news/2025/2/27 20:39:49/文章来源:https://www.cnblogs.com/66-57/p/18741930

对csdn作者的贪吃蛇程序进行了拓展增加了蛇头碰到蛇身为输以及给蛇身加点颜色。
原代码:

include <stdio.h>

include <stdlib.h>

include <windows.h>

include <time.h>

include <conio.h>``

/*大一上的时候C语言入门学的一个小游戏。还是挺有意思的,有兴趣的同学可以继续优化下:比如蛇头碰到蛇身就判定为输 /给蛇身加点颜色等。
*/
//1.2食物结构体

define MAPHEIGHT 25

define MAPWIDTH 60

define SNAKESIZE 50 //蛇的最大节数

struct FOOD
{
int x;
int y;
}food;

define SNAKESIZE 50 //蛇的最大节数

struct
{ //每一节蛇的坐标
int x[SNAKESIZE];
int y[SNAKESIZE];
int len; //蛇长
int speed; //
}snake;
///全局变量
int key='w';//初始化移动方向
int changFlag = 0;//蛇变化标记
//模块化设计
//
//1.画地图
void gotoxy(int x,int y); //实现的函数声明
void drawMap();
void createFood();
int snakeStatus();
void drawMap()

{
srand((unsigned)time(NULL)); //随机函数种子
//1.圈地
//1.1 左右边框
for(int i=0;i<=MAPHEIGHT;i++)
{
gotoxy(0,i);
printf("■");
gotoxy(MAPWIDTH,i);
printf("■");
}
for(int i=0;i<=MAPWIDTH;i+=2) //上下 ■占用两个字符
{
gotoxy(i,0);
printf("■");
gotoxy(i,MAPHEIGHT);
printf("■");
}
//2.画蛇 ■
//2.1确定蛇的属性
snake.len=3;
snake.speed =100;
snake.x[0]=MAPWIDTH/2; //开始蛇头放屏幕中间
snake.y[0]=MAPHEIGHT/2;
//2.2画蛇头
gotoxy(snake.x[0],snake.y[0]);
printf("■"); //一节 x=2
//画身体
for(int k =1;k<snake.len;k++)
{
snake.x[k]=snake.x[k-1]+2;
snake.y[k]=snake.y[k-1];
gotoxy(snake.x[k],snake.y[k]);
printf("■");
}
//3.画食物 ● //3.1确定坐标
food.x=rand()%(MAPWIDTH-4)+2; //边框的宽度是2 占用两个字符 两边边框就是4
food.y=rand()%(MAPHEIGHT-2)+1; //上下各占一个
if(food.x%2!=0)
{
food.x=food.x+1;
}
//3.2 画出来就可以
gotoxy(food.x,food.y);
printf("●");

}
//2.food
void createFood()
{
//蛇头坐标等于食物坐标,就是吃了
if(snake.x[0]food.x && snake.y[0]food.y)
{
srand((unsigned int)time(NULL));
//产生的食物不能在蛇的身上,并且坐标要是偶数 因为蛇头的宽度是偶数
while(1)
{
int flag=1;
food.x=rand()%(MAPWIDTH-4)+2;
food.y=rand()%(MAPHEIGHT-2)+1;
//产生的食物不能在蛇身上
for(int k=0;k<snake.len;k++)
{
if(snake.x[k]food.x&&snake.y[k]food.y)
{
flag = 0; //不合适的标志
break;
}
}
if(flag&&food.x%2==0)
{

         break;}}gotoxy(food.x,food.y);//产生新的食物

printf("●");
snake.len++;
changFlag =1;//蛇的标记是1
}
//gotoxy(food.x,food.y);//产生新的食物
// printf("●");

}
void keyDown() //3.按键操作
{
//无按键的处理 原方向
if(_kbhit())
{//有按键
fflush(stdin);
key=_getch();
}
//擦除
if(!changFlag)
{
gotoxy(snake.x[snake.len-1],snake.y[snake.len-1]);
printf(" ");//两个空格擦掉尾巴。
}
//后面的蛇身
for(int i =snake.len-1;i>0;i--)
{
snake.x[i]=snake.x[i-1];
snake.y[i]=snake.y[i-1];

}
//移动方向的处理
switch(key)
{
case 'W': //往上走 y--
case 'w':
snake.y[0]--;
break;
case 'S':
case 's':
snake.y[0]++;
break;
case 'A':
case 'a':
snake.x[0]-=2;
break;
case 'd':
case 'D':
snake.x[0]+=2;
break;
}
//画蛇头
gotoxy(snake.x[0],snake.y[0]);
printf("■");
changFlag=0;
gotoxy(MAPHEIGHT+2,0); //移动不能一直看着光标
}
int snakeStatus() //4.蛇的状态:判断是否结束游戏
{
if (snake.x[0]0||snake.x[0]MAPWIDTH||snake.y[0]0||snake.y[0]MAPHEIGHT)
{
return 0;
//蛇头不能撞自己
for(int k=1;k<snake.len;k++)
{
if(snake.x[0]== snake.x[k]&& snake.y[k]==snake.y[0])
return 0;
}

}
return 1;
}
void gotoxy(int x,int y) //5.光标移动
{
//调用win32 API去设置控制台的光标位置
//1.找到控制台的这个窗口
HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);
//2.光标的结构体
COORD coord;
//3.设置光标
coord.X =x;
coord.Y =y;
//4.同步到控制台 Set Console Cursor Position
SetConsoleCursorPosition(handle,coord);
}

int main(){

drawMap();
while(1)
{
createFood();
Sleep(snake.speed);//延时
keyDown();
if(!snakeStatus())
{
break;
}
}
gotoxy(MAPWIDTH/2,MAPHEIGHT/2);
printf("You lose!");

system("pause"); //

return 0;
}
原代码地址:https://blog.csdn.net/TTKunn/article/details/140923996

修改后的代码:

include <stdio.h>

include <stdlib.h>

include <windows.h>

include <time.h>

include <conio.h>

define MAPHEIGHT 25

define MAPWIDTH 60

define SNAKESIZE 50 //蛇的最大节数

// 食物结构体
struct FOOD {
int x;
int y;
} food;

// 蛇结构体
struct {
int x[SNAKESIZE];
int y[SNAKESIZE];
int len; //蛇长
int speed; //速度
} snake;

// 全局变量
int key = 'w'; //初始化移动方向
int changFlag = 0; //蛇变化标记

// 函数声明
void gotoxy(int x, int y);
void drawMap();
void createFood();
int snakeStatus();
void keyDown();
void setColor(int color);
int selectDifficulty();

// 设置控制台文本颜色
void setColor(int color) {
HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleTextAttribute(handle, color);
}

// 选择游戏难度
int selectDifficulty() {
int choice;
printf("请选择游戏难度:\n");
printf("1. 简单(慢)\n");
printf("2. 普通(中)\n");
printf("3. 困难(快)\n");
printf("请输入你的选择(1-3):");
scanf("%d", &choice);
switch (choice) {
case 1:
return 200; // 慢速
case 2:
return 100; // 中速
case 3:
return 50; // 快速
default:
printf("输入无效,默认选择普通难度。\n");
return 100;
}
}

// 画地图
void drawMap() {
srand((unsigned)time(NULL)); //随机函数种子
//1.圈地
//1.1 左右边框
for (int i = 0; i <= MAPHEIGHT; i++) {
gotoxy(0, i);
printf("■");
gotoxy(MAPWIDTH, i);
printf("■");
}
for (int i = 0; i <= MAPWIDTH; i += 2) { //上下 ■占用两个字符
gotoxy(i, 0);
printf("■");
gotoxy(i, MAPHEIGHT);
printf("■");
}
//2.画蛇 ■
//2.1确定蛇的属性
snake.len = 3;
snake.speed = selectDifficulty(); // 根据难度设置速度
snake.x[0] = MAPWIDTH / 2; //开始蛇头放屏幕中间
snake.y[0] = MAPHEIGHT / 2;
//2.2画蛇头
gotoxy(snake.x[0], snake.y[0]);
setColor(10); // 设置蛇头颜色为绿色
printf("■"); //一节 x=2
//画身体
for (int k = 1; k < snake.len; k++) {
snake.x[k] = snake.x[k - 1] + 2;
snake.y[k] = snake.y[k - 1];
gotoxy(snake.x[k], snake.y[k]);
setColor(12); // 设置蛇身颜色为红色
printf("■");
}
//3.画食物 ● //3.1确定坐标
food.x = rand() % (MAPWIDTH - 4) + 2; //边框的宽度是2 占用两个字符 两边边框就是4
food.y = rand() % (MAPHEIGHT - 2) + 1; //上下各占一个
if (food.x % 2 != 0) {
food.x = food.x + 1;
}
//3.2 画出来就可以
gotoxy(food.x, food.y);
setColor(14); // 设置食物颜色为黄色
printf("●");
}

// 创建食物
void createFood() {
//蛇头坐标等于食物坐标,就是吃了
if (snake.x[0] == food.x && snake.y[0] == food.y) {
srand((unsigned int)time(NULL));
//产生的食物不能在蛇的身上,并且坐标要是偶数 因为蛇头的宽度是偶数
while (1) {
int flag = 1;
food.x = rand() % (MAPWIDTH - 4) + 2;
food.y = rand() % (MAPHEIGHT - 2) + 1;
//产生的食物不能在蛇身上
for (int k = 0; k < snake.len; k++) {
if (snake.x[k] == food.x && snake.y[k] == food.y) {
flag = 0; //不合适的标志
break;
}
}
if (flag && food.x % 2 == 0) {
break;
}
}
gotoxy(food.x, food.y); //产生新的食物
setColor(14); // 设置食物颜色为黄色
printf("●");
snake.len++;
changFlag = 1; //蛇的标记是1
}
}

// 按键操作
void keyDown() {
//无按键的处理 原方向
if (_kbhit()) { //有按键
fflush(stdin);
key = _getch();
}
//擦除
if (!changFlag) {
gotoxy(snake.x[snake.len - 1], snake.y[snake.len - 1]);
printf(" "); //两个空格擦掉尾巴。
}
//后面的蛇身
for (int i = snake.len - 1; i > 0; i--) {
snake.x[i] = snake.x[i - 1];
snake.y[i] = snake.y[i - 1];
}
//移动方向的处理
switch (key) {
case 'W': //往上走 y--
case 'w':
snake.y[0]--;
break;
case 'S':
case 's':
snake.y[0]++;
break;
case 'A':
case 'a':
snake.x[0] -= 2;
break;
case 'd':
case 'D':
snake.x[0] += 2;
break;
}
//画蛇头
gotoxy(snake.x[0], snake.y[0]);
setColor(10); // 设置蛇头颜色为绿色
printf("■");
//画蛇身
for (int k = 1; k < snake.len; k++) {
gotoxy(snake.x[k], snake.y[k]);
setColor(12); // 设置蛇身颜色为红色
printf("■");
}
changFlag = 0;
gotoxy(MAPHEIGHT + 2, 0); //移动不能一直看着光标
}

// 蛇的状态:判断是否结束游戏
int snakeStatus() {
// 判断蛇头是否撞到墙壁
if (snake.x[0] == 0 || snake.x[0] == MAPWIDTH || snake.y[0] == 0 || snake.y[0] == MAPHEIGHT) {
return 0;
}
// 判断蛇头是否撞到蛇身
for (int k = 1; k < snake.len; k++) {
if (snake.x[0] == snake.x[k] && snake.y[0] == snake.y[k]) {
return 0;
}
}
return 1;
}

// 光标移动
void gotoxy(int x, int y) {
//调用win32 API去设置控制台的光标位置
//1.找到控制台的这个窗口
HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);
//2.光标的结构体
COORD coord;
//3.设置光标
coord.X = x;
coord.Y = y;
//4.同步到控制台 Set Console Cursor Position
SetConsoleCursorPosition(handle, coord);
}

int main() {
drawMap();
while (1) {
createFood();
Sleep(snake.speed); //延时
keyDown();
if (!snakeStatus()) {
break;
}
}
gotoxy(MAPWIDTH / 2, MAPHEIGHT / 2);
setColor(12); // 设置游戏结束文字颜色为红色
printf("You lose!");
setColor(7); // 恢复默认颜色
system("pause"); //
return 0;
}

代码说明:

  1. 蛇头撞到蛇身为输:在 snakeStatus 函数中,添加了一个循环来检查蛇头是否与蛇身的任何一部分相撞。如果相撞,返回 0,表示游戏结束。
    2.添加蛇身颜色:使用 setColor 函数来设置蛇头和蛇身的颜色。蛇头设置为绿色(颜色代码 10),蛇身设置为红色(颜色代码 12),食物设置为黄色(颜色代码 14)。
  2. 恢复默认颜色:在游戏结束时,将控制台文本颜色恢复为默认颜色(颜色代码 7)。
    4.选择游戏难度:
    在游戏开始时,玩家可以选择难度级别(简单、普通、困难)。
    难度级别决定了蛇的移动速度:
    简单:蛇速较慢(200ms)。
    普通:蛇速中等(100ms)。
    困难:蛇速较快(50ms)。
    实现方式:
    新增 selectDifficulty 函数,用于提示玩家选择难度并返回对应的速度值。
    在 drawMap 函数中调用 selectDifficulty,将返回的速度值赋给 snake.speed。
    游戏体验:
    玩家可以根据自己的水平选择适合的难度,增加游戏的趣味性和挑战性。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/890818.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

2352732 项目创新

一、项目及来源 我选取的项目是一个用Java语言开发的拼图小游戏,来自https://www.cnblogs.com/get-elaina/p/17854791.html 该拼图游戏实现了拼图的打乱功能和移动功能,用户可以通过↑ ↓ ← → 键来对图片进行移动,并记录下用户所使用的步数,当用户将拼图复位后,游戏步数…

spring @conditional介绍及使用

💖简介 @Conditional 是 Spring 框架中用于条件化注册 Bean的核心注解,它允许开发者根据特定条件决定是否将某个Bean注册到 Spring 容器中。这一机制在实现多环境配置、模块化加载、动态依赖管理等场景中非常有用。 📖作用条件控制:根据预设条件(如环境变量、类路径、系…

7.1.2 AlexNet

本质和主要改进见下因为模型更大了,所以要用丢弃法做正则;\(\text{ReLu}\)则比\(\text{Sigmoid}\)更能支撑更深的网络(解决了梯度消失);最大汇聚层则让输出更大,梯度更大,训练更容易 还有一些主要区别如下步长也很大的原因也是当时的算力其实不是很够池化层更大了就允许…

学生信息管理项目更改

一、来源:原先的作品来自于大二上同寝室计科同学的期末大作业项目 二、运行环境基于intelij为运行软件,maven做框架依赖,tomacat浏览器展示,mysql数据库 运行截图由于代码较多,此处只展示部分代码 1、addStudent.jsp 点击查看代码 <%@ page language="java" …

Linux相关杂记

Windows通过ssh远程linux的Ubuntu 1.在Ubuntu上安装SSH服务 sudo apt update sudo apt insall openssh-server2.启动ssh sudo systemctl start ssh3.设置开机自启 sudo systemctl enable ssh2.获取Ubuntu的IP地址 ip a3.windows上使用SSH客户端 ssh 用户名@IP地址#####愿你一寸…

笔记本外接显示器,左右位置设置

笔记本电脑扩展的显示器 如何左右分屏或上下分屏显示? 留意屏幕布局。 若笔记本屏幕在左而外接显示器在右,则无需调整;反之,则需用鼠标选中2号屏,按住左键拖动至1号屏的左侧。

题解:P4586 [FJOI2015] 最小覆盖双圆问题

写了这么久终于过了,发篇题解记录一下。 第一次写黑题题解,写的不好请见谅。 目录本题思路 三点定圆 最小圆覆盖 关于最小圆覆盖时间复杂度 回到本题 二分法划分点集 总时间复杂度 最小覆盖双圆问题代码本题思路 首先,这道题叫做最小覆盖双圆问题,这道题涉及到一个叫做最小…

sed undefined label on MacOS, FreeBSD

A quick fix is to prepend your string expression with an empty string: For example: instead of sed -i s/foo/bar/g text.txt write: sed -i s/foo/bar/g text.txtThis should work across different OS (Linux, MacOS, Windows) --dopexxx来源:http://stackoverflow.…

软工作业1:自我介绍+软工5问

这个作业属于哪个课程 软工23级这个作业要求在哪里 自我介绍+软工五问这个作业的目标 熟悉博客园以及Github的相关操作,了解软件工程相关内容1.自我介绍兴趣爱好:羽乒人,爱听歌,电影,楷书,行楷 编程语言:C,JAVA 目标:后端开发2.软工五问软件工程在对就业上的帮助的具体…

对“推箱子”小游戏代码的改进

一.代码来源 https://www.cnblogs.com/heyu123/p/14844284.html 二.运行环境 DEV--C++ 三.原代码及其运行结果 原代码: int map[8][8]={{1,1,1,1,1,1,1,1},//0 空地 {1,0,0,0,1,0,0,1},//1 墙 {1,0,1,0,1,4,3,1},//3 目的地 {1,0,0,0,0,4,3,1},//4 箱子 {1,0,1,0,1,4,3,1},//5…

软件开发与创新课程设计作业——软件逆向设计

一、来源:软件工程2班李鹏飞去年的大作业`点击查看代码 #include <iostream> #include <string> #include <fstream> using namespace std;//定义客户类型 enum eGuestType // 在高版本VS中,需要用enum class,在低版本的vs中,直接用enum也可以 {e_member…

LVI_SAM 虚拟机安装复现(一)

0. 前言 高能警告:LVI_SAM 的安装步骤是繁琐的,一个坑接着一个坑,请预留48+小时的安装时间,和80%以上的san值。非战斗人员请尽快撤离。 预备知识:虚拟机安装步骤,ROS基本概念,Makefile工作原理 没有预备知识的话,也没关系,本文也不会给你解释的( 本文是第一大步骤,即…