• 欢迎访问搞代码网站,推荐使用最新版火狐浏览器和Chrome浏览器访问本网站!
  • 如果您觉得本站非常有看点,那么赶紧使用Ctrl+D 收藏搞代码吧

C语言循环链表实现贪吃蛇游戏

c语言 搞代码 4年前 (2022-01-06) 26次浏览 已收录 0个评论

这篇文章主要为大家详细介绍了C语言循环链表实现贪吃蛇,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

本文实例为大家分享了C语言表实现贪吃蛇游戏的具体代码,供大家参考,具体内容如下

总体思想

利用循环链表将一条蛇的坐标进行存储,然后利用gotoxy()函数(可以将光标定位到指定的位置),此时根据蛇的坐标进行输出“@”,输出多几个既可以产生一条蛇。通过遍历循环链表进行蛇的移动,对循环链表的插入元素,产生蛇变长的效果。下面为各功能实现的函数

1.贪吃蛇地图函数map()
2.蛇的移动move(),up(),left()等函数
3.产生食物food()和吃到食物eat_food()
4.蛇吃到食物时产生的变长效果snake_link()函数
5.判断蛇的死亡,分别为撞墙hit_wall()和自杀suicide()

1.贪吃蛇地图函数map()

游戏地图采用的是应该封闭的区域,采用一个数组a[25][50],将此数组初始化为0,将游戏墙的边缘赋值为1,当数组为0,输出” “,数组为1,输出“#”,产生一个地图。

代码如下:

 void map() //创建蛇的地图 { int a[25][50] = {0}; int i,j; for(i = 0; i <50; i++) { a[0][i] = 1; a[24][i] =1; } for(i = 0; i <25; i++) { a[i][0] = 1; a[i][49] =1; } for(i = 0; i <25; i++) for(j = 0; j <50; j++) { if(j%50 == 0) printf("\n"); if(a[i][j] == 0) { printf(" "); } else { printf("#"); } } }

2.蛇的移动move(),up(),left()等函数

move()函数主要对蛇的上下左右进行更改在此采用switch函数进行解决(下面代码中ch为全局变量)
代码如下

 void move(struct snake *p) //蛇的移动函数 { while(1) { ch = getch(); switch(ch) { case 'W':p = up(p);break; case 'A':p = left(p);break; case 'D':p = right(p);break; case 'S':p = down(p);break; } } }

让蛇动起来的即我们主要对蛇的坐标进行更改,此时蛇头移动一次我们就利用gotoxy()函数进行输出“@”,然后在蛇尾输出“ ”,循环往复就可以产生蛇移动的效果,蛇的上下左右则只需在移动一个方向的时候对单一的坐标x或y进行更改,然后对更改的坐标保存进循环链表即可。移动函数则主要有up(),left()等,因为做法差不多,在此只对up()函数进行展示

代码如下

 struct snake *up(struct snake *p) //向上移动 { int x; int y; x = p->pre->x;   //将蛇头坐标赋值给x,y y = p->pre->y; while(p)   //对循环链表的遍历,即蛇的遍历 { Sleep(SNAKE_SPEED); //蛇移动的速度 y--;   //向上移动则只需将纵坐标进行减,就可以实现蛇向上移动的效果 gotoxy(p->x,p->y);  //定位到蛇尾,输出“ ”即蛇尾消失 printf(" "); gotoxy(x, y);  //定位到蛇头输出,"@",结合上面的蛇尾消失又进行蛇头打印,产生蛇移动的效果 printf("@"); suicide(p,x,y);  //判断蛇头是否撞到蛇身 p = p->next;  //将蛇头的坐标变为下一个 p->pre->x = x;  //此时将前一个蛇头变成蛇尾,通过不断的遍历产生不断移动的效果 p->pre->y = y; food();   //产生食物 eat_food(p,x,y);  //判断是否吃到食物 hit_wall(y);  //判断是否撞墙 if(kbhit()) break; //判断是否有按键输入,有就进行蛇移动方向的改变 } return p; }

3.产生食物food()和吃到食物eat_food()

食物和吃到食物,产生食物则采用了产生随机数,产生一个食物的x,y坐标分别存放在全局变量food_xy[2]数组里面,最后利用gotoxy(food_xy[0],food_xy[1])随机产生食物
代码如下

 void food()   //产生食物 { int i; if(!flag)   //根据flag的值来判断地图上是否有食物 { srand( (unsigned)time( NULL ) ); for( i = 0; i = 49 || food_xy[1] == 1) food_xy[1] =rand()%24+2; } gotoxy(food_xy[0],food_xy[1]); //打印食物 printf("*"); flag = 1; } }

吃到食物eat_food(),则我们只需判断蛇头是否和食物的坐标重叠,若重叠则表明蛇吃到了食物

代码如下

 void eat_food(struct snake *p,int x, int y)  //蛇吃到食物,即主要是对蛇头的x,y坐标和 {       //food_xy的坐标进行匹配对比,若相同即调 if(x == food_xy[0] && y == food_xy[1])  //snake_link函数即可 { p = snake_link(p); flag = 0;     //表明食物被吃,准备重新产生食物 printSnake(p); gotoxy(8,0); score = score + 1;    //得分 printf("%d",score); } }

4.蛇吃到食物时产生的变长效果snake_link()函数

蛇的变长,当蛇吃到食物的时候,此时我们将食物的坐标变成蛇头,然后进行重新的打印蛇,即可以有蛇变成的效果产生,实质为对循环链表进行元素的插入。

即通过这样将食物的坐标插进去循环链表,达到蛇变成的效果
代码如下

 struct snake *snake_link(struct snake *p) //蛇的连接 { struct snake *q; q = (struct snake *)malloc(sizeof(struct snake)); //即主要是实现了对循环链表的插入元素,再 q->x = food_xy[0];    //进行打印蛇,即可有吃到食物蛇变长的结果 q->y = food_xy[1]; q->pre = p->pre; p->pre->next = q; p->pre = q; q->next = p; return p; }

5.判断蛇的死亡,分别为撞墙hit_wall()和自杀suicide()

撞墙,则只需判断蛇头的单一坐标x轴或者y轴是否与墙壁的坐标是否相等,若相等则说明蛇撞墙了
代码如下

 void hit_wall(int n) //判断蛇是否撞墙,即对蛇的单一坐标x或者y进行判断,若等于墙壁的值,即游戏结束 { if(ch == 'W'|| ch == 'S' ) if(n == 1 || n == 25)  //墙壁的坐标值 { gotoxy(0,26); printf("游戏结束!"); printf("你的得分:%d",score); exit(0); } if(ch == 'A'|| ch == 'D' ) if(n == 0 || n == 49) { gotoxy(0,26); printf("游戏结束!"); printf("你的得分:%d",score); exit(0); } }

自杀suicide()即蛇头是否有撞到了蛇身,做法是把蛇头的坐标拿出来,与蛇身的坐标进行对比如果相等,说明蛇头撞到了蛇身,本质上是循环链表的值进行匹配,遍历

代码如下

 void suicide(struct snake *p, int x, int y) //自杀,即撞到自己本身的时候游戏结束 { struct snake *q;    //把蛇头坐标传递进来,然后与其自己身体坐标做对比若有相等则表明,蛇头撞到了蛇身 q = p; while(q != p->next)   //即对循环链表的遍历匹配 { if(p->x == x && p->y == y) { gotoxy(0,26); printf("游戏结束!"); printf("你的得分:%d",score); exit(0); } else p = p->next; } }

到此蛇的基本功能已经讲完,以下是全部代码。

全部代码如下

 #include  #include  #include  #include  #include  #define SNAKE_SPEED 200 //蛇移动的速度 int score = 0;  //成绩得分 int flag = 0;  //用于判断地图上是否存在食物,0为不存在食物 int food_xy[2];  //定位食物的位置 char ch;  //用来决定蛇的移动方向 struct snake //定义一条循环链表的蛇 { int x; int y; struct snake *next; struct snake *pre; }; void HideCursor()//把蛇移动的时候产生的光标进行隐藏,隐藏光标函数 { CONSOLE_CURSOR_INFO cursor; cursor.bVisible = FALSE; cursor.dwSize = sizeof(cursor); HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE); SetConsoleCursorInfo(handle, &cursor); } void gotoxy(int x, int y) //定位光标函数,用来实现蛇的移动,和食物的出现(传送x,y可以将光标定位到x,y) { HideCursor(); COORD coord = {x,y}; SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord); } void map() //创建蛇的地图 { int a[25][50] = {0}; int i,j; for(i = 0; i <50; i++) { a[0][i] = 1; a[24][i] =1; } for(i = 0; i <25; i++) { a[i][0] = 1; a[i][49] =1; } for(i = 0; i <25; i++) for(j = 0; j pre = NULL; for( i = 0; i x = 25 - i; p->y = 13; p->pre = head->pre; head->pre = p; q->next = p; q = p; p = (struct snake *)malloc(sizeof(struct snake)); } q->next = head; return head; } void printSnake(struct snake *p) //打印蛇,利用gotoxy()来对蛇进行打印,只需遍历一次循环链表即可将坐标可视化为一条蛇 { struct snake *q; q = p; while(q != p->next)  //循环链表的遍历 { gotoxy(p->x,p->y);  //根据坐标和定位光标函数来打@,实现输出蛇 printf("@"); p = p->next; } gotoxy(p->x,p->y); printf("@"); gotoxy(0,0); printf("你的得分:");  //初始化得分 } void food()   //产生食物 { int i; if(!flag)   //根据flag的值来判断地图上是否有食物 { srand( (unsigned)time( NULL ) ); for( i = 0; i = 49 || food_xy[1] == 1) food_xy[1] =rand()%24+2; } gotoxy(food_xy[0],food_xy[1]); //打印食物 printf("*"); flag = 1; } } struct snake *snake_link(struct snake *p) //蛇的连接 { struct snake *q; q = (struct snake *)malloc(sizeof(struct snake)); //即主要是实现了对循环链表的插入元素,再进行打印蛇,即可有吃到食物蛇变长的结果 q->x = food_xy[0]; q->y = food_xy[1]; q->pre = p->pre; p->pre->next = q; p->pre = q; q->next = p; return p; } void eat_food(struct snake *p,int x, int y)  //蛇吃到食物,即主要是对蛇头的x,y坐标和food_xy的坐标进行匹配对比,若相同即调用snake_link函数即可 { if(x == food_xy[0] && y == food_xy[1]) { p = snake_link(p); flag = 0; printSnake(p); gotoxy(8,0); score = score + 1; printf("%d",score); } } void hit_wall(int n) //判断蛇是否撞墙,即对蛇的单一坐标x或者y进行判断,若等于墙壁的值,即游戏结束 { if(ch == 'W'|| ch == 'S' ) if(n == 1 || n == 25) { gotoxy(0,26); printf("游戏结束!"); printf("你的得分:%d",score); exit(0); } if(ch == 'A'|| ch == 'D' ) if(n == 0 || n == 49) { gotoxy(0,26); printf("游戏结束!"); printf("你的得分:%d",score); exit(0); } } void suicide(struct snake *p, int x, int y) //自杀,即撞到自己本身的时候游戏结束 { struct snake *q;    //把蛇头坐标传递进来,然后与其自己身体坐标做对比若有相等则表明,蛇头撞到了蛇身 q = p; while(q != p->next)   //即对循环链表的遍历匹配 { if(p->x == x && p->y == y) { gotoxy(0,26); printf("游戏结束!"); printf("你的得分:%d",score); exit(0); } else p = p->next; } } struct snake *up(struct snake *p) //向上移动 { int x; int y; x = p->pre->x;   //将蛇头坐标赋值给x,y y = p->pre->y; while(p)   //对循环链表的遍历,即蛇的遍历 { Sleep(SNAKE_SPEED); //蛇移动的速度 y--;   //向上移动则只需将纵坐标进行减,就可以实现蛇向上移动的效果 gotoxy(p->x,p->y);  //定位到蛇尾,输出“ ”即蛇尾消失 printf(" "); gotoxy(x, y);  //定位到蛇头输出,"@",结合上面的蛇尾消失又进行蛇头打印,产生蛇移动的效果 printf("@"); suicide(p,x,y);  //判断蛇头是否撞到蛇身 p = p->next;  //将蛇头的坐标变为下一个 p->pre->x = x;  //此时将前一个蛇头变成蛇尾,通过不断的遍历产生不断移动的效果 p->pre->y = y; food();   //产生食物 eat_food(p,x,y);  //判断是否吃到食物 hit_wall(y);  //判断是否撞墙 if(kbhit()) break; //判断是否有按键输入,有就进行蛇移动方向的改变 } return p; } struct snake *left(struct snake *p) /<div style="color:transparent">来源gaodai^.ma#com搞#代!码网</div>/向左移动 { int x; int y; x = p->pre->x; y = p->pre->y; while(p) { Sleep(SNAKE_SPEED); x--; gotoxy(p->x,p->y); printf(" "); gotoxy(x, y); printf("@"); suicide(p,x,y); p = p->next; p->pre->x = x; p->pre->y = y; food(); eat_food(p,x,y); hit_wall(x); if(kbhit()) break; } return p; } struct snake *down(struct snake *p) //向下移动 { int x; int y; x = p->pre->x; y = p->pre->y; while(p) { Sleep(SNAKE_SPEED); y++; gotoxy(p->x,p->y); printf(" "); gotoxy(x, y); printf("@"); suicide(p,x,y); p = p->next; p->pre->x = x; p->pre->y = y; food(); eat_food(p,x,y); hit_wall(y); if(kbhit()) break; } return p; } struct snake *right(struct snake *p) //向右移动 { int x; int y; x = p->pre->x; y = p->pre->y; while(p) { Sleep(SNAKE_SPEED); x++; gotoxy(p->x,p->y); printf(" "); gotoxy(x, y); printf("@"); suicide(p,x,y); p = p->next; p->pre->x = x; p->pre->y = y; food(); eat_food(p,x,y); hit_wall(x); if(kbhit()) break; } return p; } void move(struct snake *p) //蛇的移动函数 { while(1) { ch = getch(); switch(ch) { case 'W':p = up(p);break; case 'A':p = left(p);break; case 'D':p = right(p);break; case 'S':p = down(p);break; } } } int main() { struct snake *p; map(); //产生地图 p = createSnake(); // 初始化蛇 printSnake(p); // 打印蛇 move(p); //移动蛇 return 0; }

更多有趣的经典小游戏实现专题,分享给大家:

C++经典小游戏汇总

python经典小游戏汇总

python俄罗斯方块游戏集合

JavaScript经典游戏 玩不停

java经典小游戏汇总

javascript经典小游戏汇总

以上就是C语言循环链表实现贪吃蛇游戏的详细内容,更多请关注gaodaima搞代码网其它相关文章!


搞代码网(gaodaima.com)提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发送到邮箱[email protected],我们会在看到邮件的第一时间内为您处理,或直接联系QQ:872152909。本网站采用BY-NC-SA协议进行授权
转载请注明原文链接:C语言循环链表实现贪吃蛇游戏

喜欢 (0)
[搞代码]
分享 (0)
发表我的评论
取消评论

表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址