贪吃蛇编程代码讲解(贪吃蛇编程代码简易版)
求,贪吃蛇 C语言代码 及其每一步的讲解
/* 贪吃蛇程序 by champking */
#define N 200
#include graphics.h
#include stdlib.h
#include dos.h
#define LEFT 0x4b00
#define RIGHT 0x4d00
#define DOWN 0x5000
#define UP 0x4800
#define ESC 0x011b
int i,key;
int score = 0;/*得分*/
int gamespeed = 100000;/*游戏速度自己调整*/
struct Food
{
int x;/*食物的横坐标*/
int y;/*食物的纵坐标*/
int yes;/*判断是否要出现食物的变量*/
}food;/*食物的结构体*/
struct Snake
{
int x[N];
int y[N];
int node;/*蛇的节数*/
int direction;/*蛇移动方向*/
int life;/* 蛇的生命,0活着,1死亡*/
}snake;
void Init(void);/*图形驱动*/
void Close(void);/*图形结束*/
void DrawK(void);/*开始画面*/
void GameOver(void);/*结束游戏*/
void GamePlay(void);/*玩游戏具体过程*/
void PrScore(void);/*输出成绩*/
/*主函数*/
void main(void)
{
Init();/*图形驱动*/
DrawK();/*开始画面*/
GamePlay();/*玩游戏具体过程*/
Close();/*图形结束*/
}
/*图形驱动*/
void Init(void)
{
int gd = DETECT, gm;
initgraph(gd, gm, "c:\\tc");
cleardevice();
}
/*开始画面,左上角坐标为(50,40),右下角坐标为(610,460)的围墙*/
void DrawK(void)
{
/*setbkcolor(LIGHTGREEN);*/
setcolor(11);
setlinestyle(SOLID_LINE, 0, THICK_WIDTH);/*设置线型*/
for(i = 50; i = 600; i += 10)/*画围墙*/
{
rectangle(i, 40, i + 10, 49); /*上边*/
rectangle(i, 451, i + 10, 460);/*下边*/
}
for(i = 40; i = 450; i += 10)
{
rectangle(50, i, 59, i + 10); /*左边*/
rectangle(601, i, 610, i + 10);/*右边*/
}
}
/*玩游戏具体过程*/
void GamePlay(void)
{
randomize();/*随机数发生器*/
food.yes = 1;/*1表示需要出现新食物,0表示已经存在食物*/
snake.life = 0;/*活着*/
snake.direction = 1;/*方向往右*/
snake.x[0] = 100; snake.y[0] = 100;/*蛇头*/
snake.x[1] = 110; snake.y[1] = 100;
snake.node = 2;/*节数*/
PrScore();/*输出得分*/
while(1)/*可以重复玩游戏,压ESC键结束*/
{
while(!kbhit())/*在没有按键的情况下,蛇自己移动身体*/
{
if(food.yes == 1)/*需要出现新食物*/
{
food.x = rand() % 400 + 60;
food.y = rand() % 350 + 60;
while(food.x % 10 != 0)/*食物随机出现后必须让食物能够在整格内,这样才可以让蛇吃到*/
food.x++;
while(food.y % 10 != 0)
food.y++;
food.yes = 0;/*画面上有食物了*/
}
if(food.yes == 0)/*画面上有食物了就要显示*/
{
setcolor(GREEN);
rectangle(food.x, food.y, food.x + 10, food.y - 10);
}
for(i = snake.node - 1; i 0; i--)/*蛇的每个环节往前移动,也就是贪吃蛇的关键算法*/
{
snake.x[i] = snake.x[i-1];
snake.y[i] = snake.y[i-1];
}
/*1,2,3,4表示右,左,上,下四个方向,通过这个判断来移动蛇头*/
switch(snake.direction)
{
case 1: snake.x[0] += 10; break;
case 2: snake.x[0] -= 10; break;
case 3: snake.y[0] -= 10; break;
case 4: snake.y[0] += 10; break;
}
for(i = 3; i snake.node; i++)/*从蛇的第四节开始判断是否撞到自己了,因为蛇头为两节,第三节不可能拐过来*/
{
if(snake.x[i] == snake.x[0] snake.y[i] == snake.y[0])
{
GameOver();/*显示失败*/
snake.life = 1;
break;
}
}
if(snake.x[0]55||snake.x[0]595||snake.y[0]55||
snake.y[0]455)/*蛇是否撞到墙壁*/
{
GameOver();/*本次游戏结束*/
snake.life=1; /*蛇死*/
}
if(snake.life == 1)/*以上两种判断以后,如果蛇死就跳出内循环,重新开始*/
break;
if(snake.x[0] == food.x snake.y[0] == food.y)/*吃到食物以后*/
{
setcolor(0);/*把画面上的食物东西去掉*/
rectangle(food.x, food.y, food.x + 10, food.y - 10);
snake.x[snake.node] =- 20; snake.y[snake.node] =- 20;
/*新的一节先放在看不见的位置,下次循环就取前一节的位置*/
snake.node++;/*蛇的身体长一节*/
food.yes = 1;/*画面上需要出现新的食物*/
score += 10;
PrScore();/*输出新得分*/
}
setcolor(4);/*画出蛇*/
for(i = 0; i snake.node; i++)
rectangle(snake.x[i], snake.y[i], snake.x[i] + 10,
snake.y[i] - 10);
delay(gamespeed);
setcolor(0);/*用黑色去除蛇的的最后一节*/
rectangle(snake.x[snake.node-1], snake.y[snake.node-1],
snake.x[snake.node-1] + 10, snake.y[snake.node - 1] - 10);
} /*endwhile(!kbhit)*/
if(snake.life == 1)/*如果蛇死就跳出循环*/
break;
key = bioskey(0);/*接收按键*/
if(key == ESC)/*按ESC键退出*/
break;
else
if(key == UPsnake.direction!=4)
/*判断是否往相反的方向移动*/
snake.direction=3;
else
if(key == RIGHT snake.direction != 2)
snake.direction=1;
else
if(key == LEFT snake.direction != 1)
snake.direction = 2;
else
if(key == DOWN snake.direction != 3)
snake.direction = 4;
}/*endwhile(1)*/
}
/*游戏结束*/
void GameOver(void)
{
cleardevice();
PrScore();
setcolor(RED);
settextstyle(0, 0, 4);
outtextxy(200, 200, "GAME OVER");
getch();
}
/*输出成绩*/
void PrScore(void)
{
char str[10];
setfillstyle(SOLID_FILL, YELLOW);
bar(50, 15, 220, 35);
setcolor(6);
settextstyle(0,0,2);
sprintf(str, "score:%d", score);
outtextxy(55, 20, str);
}
/*图形结束*/
void Close(void)
{
getch();
closegraph();
}
如何用慧编程做贪吃蛇代码
用慧编程做贪吃蛇代码过程如下:
1、我们需要建立四个头文件,然后分别设置蛇的状态,上下左右,这是蛇能够有方向可走的前提,然后我们再设置蛇身的节点,定义一个简单的函数,这样蛇的全身以及他的行走方向就弄完了。
2、贪吃蛇不能穿墙代码。
3、第二步,一个函数这个函数的目的是贪吃蛇不能穿墙,很简单的代码分别设置长宽的最大位移,在内部范围内设置为一即可通过,否则不能穿墙。贪吃蛇随机生成一个食物。
4、设置一个随机函数。这样贪吃蛇代码就做好了。
慧编程是一款面向STEAM教育领域的积木式和代码编程软件,基于图形化编程开发。
C语言的贪吃蛇源代码
?
//******友情提示:如想速度快点,请改小_sleep(500)函数中参数*****??
#include?stdio.h??
#include?stdlib.h??
#include?conio.h??
#include?string.h??
#include?time.h??
const?int?H?=?8;???//地图的高??
const?int?L?=?16;??//地图的长??
char?GameMap[H][L];???//游戏地图??
int??key;??//按键保存??
int??sum?=?1,?over?=?0;??//蛇的长度,?游戏结束(自吃或碰墙)??
int??dx[4]?=?{0,?0,?-1,?1};??//左、右、上、下的方向??
int??dy[4]?=?{-1,?1,?0,?0};??
struct?Snake???//蛇的每个节点的数据类型??
{??
?int?x,?y;??//左边位置??
?int?now;???//保存当前节点的方向,?0,1,2,3分别为左右上下??
}Snake[H*L];??
const?char?Shead?=?'@';??//蛇头??
const?char?Sbody?=?'#';??//蛇身??
const?char?Sfood?=?'*';??//食物??
const?char?Snode?=?'.';??//'.'在地图上标示为空??
void?Initial();??//地图的初始化??
void?Create_Food();?//在地图上随机产生食物??
void?Show();???//刷新显示地图??
void?Button();??//取出按键,并判断方向??
void?Move();???//蛇的移动??
void?Check_Border();??//检查蛇头是否越界??
void?Check_Head(int?x,?int?y);???//检查蛇头移动后的位置情况??
int?main()???
{??
?Initial();??
?Show();??
?return?0;??
}??
void?Initial()??//地图的初始化??
{??
?int?i,?j;??
?int?hx,?hy;??
?system("title?贪吃蛇");??//控制台的标题??
?memset(GameMap,?'.',?sizeof(GameMap));??//初始化地图全部为空'.'??
?system("cls");??
?srand(time(0));???//随机种子??
?hx?=?rand()%H;????//产生蛇头??
?hy?=?rand()%L;??
?GameMap[hx][hy]?=?Shead;??
?Snake[0].x?=?hx;??Snake[0].y?=?hy;??
?Snake[0].now?=?-1;??
?Create_Food();???//随机产生食物??
?for(i?=?0;?i??H;?i++)???//地图显示??
?{???
??for(j?=?0;?j??L;?j++)??
???printf("%c",?GameMap[i][j]);??
??printf("\n");??
?}??
?????
?printf("\n小小C语言贪吃蛇\n");??
?printf("按任意方向键开始游戏\n");??
????
?getch();???//先接受一个按键,使蛇开始往该方向走??
?Button();??//取出按键,并判断方向??
}??
void?Create_Food()??//在地图上随机产生食物??
{??
?int?fx,?fy;??
?while(1)??
?{??
??fx?=?rand()%H;??
?????fy?=?rand()%L;??
?????
??if(GameMap[fx][fy]?==?'.')??//不能出现在蛇所占有的位置??
??{???
???GameMap[fx][fy]?=?Sfood;??
??????break;??
??}??
?}??
}??
void?Show()??//刷新显示地图??
{??
?int?i,?j;??
?while(1)??
?{????
??_sleep(500);?//延迟半秒(1000为1s),即每半秒刷新一次地图??
??Button();???//先判断按键在移动??
??Move();??
??if(over)??//自吃或碰墙即游戏结束??
??{???
???printf("\n**游戏结束**\n");??
???printf("?????_\n");??
???getchar();??
??????break;??
??}??
??system("cls");???//清空地图再显示刷新吼的地图??
??for(i?=?0;?i??H;?i++)???
??{???
???for(j?=?0;?j??L;?j++)??
????printf("%c",?GameMap[i][j]);??
???printf("\n");??
??}??
?????
??printf("\n小小C语言贪吃蛇\n");??
??printf("按任意方向键开始游戏\n");??
?}??
}??
void?Button()??//取出按键,并判断方向??
{??
?if(kbhit()?!=?0)?//检查当前是否有键盘输入,若有则返回一个非0值,否则返回0??
?{???
??while(kbhit()?!=?0)??//可能存在多个按键,要全部取完,以最后一个为主??
??????key?=?getch();?//将按键从控制台中取出并保存到key中??
??switch(key)??
??{???//左??
???case?75:??Snake[0].now?=?0;??
??????????break;??
????????????//右??
????????????case?77:??Snake[0].now?=?1;???????
??????????break;??
????????????//上??
???case?72:??Snake[0].now?=?2;??
??????????break;??
????????????//下??
???case?80:??Snake[0].now?=?3;??
??????????break;??
??}??
?}??
}??
void?Move()???//蛇的移动??
{??
?int?i,?x,?y;??
????int?t?=?sum;??//保存当前蛇的长度??
?//记录当前蛇头的位置,并设置为空,蛇头先移动??
?x?=?Snake[0].x;??y?=?Snake[0].y;??GameMap[x][y]?=?'.';??
?Snake[0].x?=?Snake[0].x?+?dx[?Snake[0].now?];??
?Snake[0].y?=?Snake[0].y?+?dy[?Snake[0].now?];??
?Check_Border();???//蛇头是否越界??
?Check_Head(x,?y);??//蛇头移动后的位置情况,参数为:?蛇头的开始位置??
?if(sum?==?t)??//未吃到食物即蛇身移动哦??
????for(i?=?1;?i??sum;?i++)??//要从蛇尾节点向前移动哦,前一个节点作为参照??
?{??
??if(i?==?1)???//尾节点设置为空再移动??
???GameMap[?Snake[i].x?][?Snake[i].y?]?=?'.';??
?????
??if(i?==?sum-1)??//为蛇头后面的蛇身节点,特殊处理??
??{??
???Snake[i].x?=?x;??
?????????Snake[i].y?=?y;??
??????Snake[i].now?=?Snake[0].now;??
??}??
??else???//其他蛇身即走到前一个蛇身位置??
??{??
???Snake[i].x?=?Snake[i+1].x;??
?????????Snake[i].y?=?Snake[i+1].y;??
??????Snake[i].now?=?Snake[i+1].now;??
??}??
??????
??GameMap[?Snake[i].x?][?Snake[i].y?]?=?'#';?//移动后要置为'#'蛇身???
?}??
}??
void?Check_Border()??//检查蛇头是否越界??
{??
?if(Snake[0].x??0?||?Snake[0].x?=?H??
?||?Snake[0].y??0?||?Snake[0].y?=?L)??
?????over?=?1;??
}??
void?Check_Head(int?x,?int?y)??//检查蛇头移动后的位置情况??
{??
????
?if(GameMap[?Snake[0].x?][?Snake[0].y?]?==?'.')??//为空??
??GameMap[?Snake[0].x?][?Snake[0].y?]?=?'@';??
?else?
??if(GameMap[?Snake[0].x?][?Snake[0].y?]?==?'*')??//为食物??
??{??
???GameMap[?Snake[0].x?][?Snake[0].y?]?=?'@';????
???Snake[sum].x?=?x;???//新增加的蛇身为蛇头后面的那个??
??????Snake[sum].y?=?y;??
??????Snake[sum].now?=?Snake[0].now;??
?????????GameMap[?Snake[sum].x?][?Snake[sum].y?]?=?'#';???
???sum++;??
???Create_Food();??//食物吃完了马上再产生一个食物??
??}??
??else?
???over?=?1;??
}
怎样用vb编写贪吃蛇游戏
1、向上前进的时候,对代码进行一个详解。
2、向上前进时,x坐标不动,y坐标-1,如果下一个有食物 下一个位置的坐标和食物的坐标相同。把食物转化成蛇的身体。
3、如果蛇吃到了食物,就开始加速,并且食物的得分+2。
4、如果没有吃到食物,蛇可以正常往前走,恢复原来的方块。
5、向下前进时,x坐标不动,y坐标+1。
6、如果有食物就把食物转化为身体。
7、如果没有吃到食物,蛇可以正常往前走,恢复原来的方块。
c语言贪吃蛇代码
基本思路:
蛇每吃一个食物蛇身子就增加一格,用UP, DOWN, LEFT, RIGHT控制蛇头的运动,而蛇身子跟着蛇头走,每后一格蛇身子下一步走到上一格蛇身子的位置,以此类推。
#include stdio.h
#include conio.h
#include windows.h
#define BEG_X 2
#define BEG_Y 1
#define WID 20
#define HEI 20
HANDLE hout;
typedef enum {UP, DOWN, LEFT, RIGHT} DIR;
typedef struct Snake_body
{
COORD pos;//蛇身的位置
struct Snake_body *next;//下一个蛇身
struct Snake_body *prev;//前一个蛇身
}SNAKE, *PSNAKE;
PSNAKE head = NULL;//蛇头
PSNAKE tail = NULL;//蛇尾
//画游戏边框的函数
void DrawBorder()
{
int i, j;
COORD pos = {BEG_X, BEG_Y};
for(i = 0; i HEI; ++i)
{
SetConsoleCursorPosition(hout, pos);
for(j = 0; j WID; ++j)
{
if(i == 0)//第一行
{
if(j == 0)
printf("┏");
else if(j == WID - 1)
printf("┓");
else
printf("━");
}
else if(i == HEI - 1)//最后一行
{
if(j == 0)
printf("┗");
else if(j == WID - 1)
printf("┛");
else
printf("━");
}
else if(j == 0 || j == WID - 1)//第一列或最后一列
printf("┃");
else
printf(" ?");
}
++pos.Y;
}
}
//添加蛇身的函数
void AddBody(COORD pos)
{
PSNAKE pnew = (PSNAKE)calloc(1, sizeof(SNAKE));
pnew-pos = pos;
if(!head)
{
head = tail = pnew;
}
else
{
pnew-next = head;//新创建蛇身的next指向原先的蛇头
head-prev = pnew;//原先的蛇头的prev指向新创建的蛇身
head = pnew;//把新创建的蛇身作为新的蛇头
}
SetConsoleCursorPosition(hout, head-pos);
printf("◎");
}
//蛇身移动的函数
void MoveBody(DIR dir)
{
PSNAKE ptmp;
COORD pos = head-pos;
switch(dir)
{
case UP:
if(head-pos.Y BEG_Y + 1)
--pos.Y;
else
return;
break;
case DOWN:
if(head-pos.Y BEG_Y + HEI - 2)
++pos.Y;
else
return;
break;
case LEFT:
if(head-pos.X BEG_X + 2)
pos.X -= 2;
else
return;
break;
case RIGHT:
if(head-pos.X BEG_X + (WID - 2) * 2)
pos.X += 2;
else
return;
break;
}
AddBody(pos);//添加了一个新的蛇头
ptmp = tail;//保存当前的蛇尾
tail = tail-prev;
if(tail)
tail-next = NULL;
SetConsoleCursorPosition(hout, ptmp-pos);
printf(" ?");
free(ptmp);
}
int main()
{
int ctrl;
DIR dir = RIGHT;//初始蛇的方向是向右的
COORD pos = {BEG_X + 2, BEG_Y + HEI / 2};
system("color 0E");
system("mode con cols=90 lines=30");
hout = GetStdHandle(STD_OUTPUT_HANDLE);
printf(" ? ?------------贪吃蛇的移动------------");
DrawBorder();
//自定义几个蛇的身体
AddBody(pos);
pos.X += 2;
AddBody(pos);
pos.X += 2;
AddBody(pos);
pos.X += 2;
AddBody(pos);
pos.X += 2;
AddBody(pos);
pos.X += 2;
AddBody(pos);
pos.X += 2;
AddBody(pos);
//控制蛇的移动
while(ctrl = getch())
{
switch(ctrl)
{
case 'w':
if(dir == DOWN)
continue;
dir = UP;
break;
case 's':
if(dir == UP)
continue;
dir = DOWN;
break;
case 'a':
if(dir == RIGHT)
continue;
dir = LEFT;
break;
case 'd':
if(dir == LEFT)
continue;
dir = RIGHT;
break;
case 'q':
return 0;
}
MoveBody(dir);
}
return 0;
}
扩展资料:
实现逻辑
1,可以设置光标,就能实现制定位置打印制定符号。
2,涉及一个结构体,包含两个元素坐标元素和一个结构体指针。
3,结构体串联形成链表,遍历获取成员坐标,打印符号得到蛇身。
4,不断的加头,去尾,重新遍历坐标,再打印形成蛇的移动。
5,食物产生的位置判定,不能越界,也不能与蛇身体重合。
6,蛇的转向判定,一条规则,不允许倒退。
7,转向的实现,跟行进方向决定新的关节坐标(当前头的上下左右)
8,死亡检测,是否头节点坐标是否与墙壁重合,是否与身体其他关节重合。
9,加速减速,设置刷新休眠时间实现。
参考资料来源:百度百科-C语言