#include<stdio.h>#include<Windows.h>#include<stdlib.h>#include<time.h>#include<conio.h>#include<math.h>///定义gotoxy(int x,int y)函数,可以使光标直接移动到(x,y)处//这里其实也能用二维数组将光标一个一个打到指定位置(不难,感兴趣可以尝试),但只能向后移动,//所以,蛇每动一次就要用system("cls")清一下屏还原光标,导致画面太闪,体验感极差,影响操作//下面是windows里面的函数,不是重点,不用细看,可以忽略。int wherex() { CONSOLE_SCREEN_BUFFER_INFO pBuffer;GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &pBuffer); return (pBuffer.dwCursorPosition.X+1); }//获取光标的位置int wherey() { CONSOLE_SCREEN_BUFFER_INFO pBuffer; GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &pBuffer);return (pBuffer.dwCursorPosition.Y+1); }//设置光标的位置void gotoxy(int x,int y) { COORD c; c.X=x-1; c.Y=y-1; SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE),c); }///定义完成。可以直接使用/定义结构体struct s{char name[4];struct s *next;int x;int y;};#define S struct s//一些其他函数void println(S *a);//打印蛇身void sheweizhi(S *a,int x, int y);//重置坐标void jiaohuan(int *a,int *b);/交换数字void jiayi(S*shewei);///蛇身加一int panduan1(S*a ,int x,int y);对其进一步完善int panduan2(S*a ,int x,int y);对其进一步完善int main(){int x=9,y=10;/记录位置char fangxiang='d',fangxiangcheck='d';蛇默认移动方向S *head,*sheshen,*shewei;srand((int)time(NULL));///设置时间种子,使其真正随机int shiwux=11,shiwuy=10;/使下面的循环能够进去将蛇初始化(先设置蛇尾以防止打印时蛇头被蛇尾的空格覆盖)初始化蛇尾shewei=(S *)malloc(sizeof(S));//开设一个链表的起始点strcpy(shewei->name," ");//设置蛇尾样子shewei->x=5;shewei->y=10;//设置蛇尾坐标/初始化蛇身sheshen=(S *)malloc(sizeof(S));//动态分配空间shewei->next=sheshen;//连接strcpy(sheshen->name,"□");//设置蛇身样子sheshen->x =7; sheshen->y=10;//初始化蛇身坐标//初始化蛇头head=(S *)malloc(sizeof(S));sheshen->next=head;//连接strcpy(head->name,"■");//设置蛇头样子head->x=9;head->y=10;//设置蛇头坐标head->next=NULL;///链表结束jiayi(shewei); jiayi(shewei); /初始化蛇长度//初始化完成while(1)///建立循环,开始游戏{println(shewei);//打印蛇此时的蛇//暂停程序,暂停200毫秒,参数可修改Sleep(200);///不能乱放,比如放在println上面,会有延迟//循环监听程序if(kbhit()){fangxiang=getch();}/核心所在,在循环中监听有无字符输入///检查,让程序更加强壮,减少BUGif(fabs((double)(fangxiang-fangxiangcheck))==3||fabs((double)(fangxiang-fangxiangcheck))==4)fangxiang=fangxiangcheck;if(fangxiang!='w'&&fangxiang!='d'&&fangxiang!='a'&&fangxiang!='s')fangxiang=fangxiangcheck;检查完成判断方向switch(fangxiang){case 'w':y-=1;break;case 's': y+=1;break;case 'a': x-=2;break;case 'd': x+=2;break;}fangxiangcheck=fangxiang;///sheweizhi(shewei,x,y);/重置蛇位置if(head->x==shiwux&&head->y==shiwuy)/判断是否吃到食物{jiayi(shewei);//蛇身长度加一do{shiwux=rand()%78+1,shiwuy=rand()%24+1;}while(panduan1(shewei,shiwux,shiwuy)||shiwux%2==0);/再次随机获取食物位置,并且不和蛇身重叠,每个蛇的部件都是两个字节gotoxy(shiwux,shiwuy);printf("※");打印}if(x>79||x<1||y<1||y>25) break;判断是否撞墙死亡,设置边界if(panduan2(shewei,head->x,head->y)) break;判断是否撞自己死亡}游戏结束getch();暂停一下,防止闪退return 0;}void jiaohuan(int *a,int *b)///交换啊a,b{int temp;temp=*a;*a=*b;*b=temp;}void println(S *a)///打印蛇的位置{while(a){ gotoxy(a->x,a->y);printf("%s",a->name);a=a->next;}}void sheweizhi(S *a,int x,int y)///x,y不能被修改,所以不要用地址,但蛇的x,y要用{///循环交换,将后一个的位置换到前一个while(a->next){jiaohuan(&a->x,&a->next->x);jiaohuan(&a->y,&a->next->y);a=a->next;}a->x=x;a->y=y;}void jiayi(S*shewei){S *newshe,*temp=shewei->next;newshe=(S *)malloc(sizeof(S));开设新的结点shewei->next=newshe;//连接strcpy(newshe->name,"□");设置新蛇样子newshe->x=shewei->x;newshe->y=shewei->y;设置新蛇位置newshe->next=temp;连接/重设蛇尾位置if(temp->x==shewei->x)shewei->y+=(shewei->y-temp->y);elseshewei->x+=(shewei->x-temp->x);}int panduan1(S *a,int x,int y)//判断链表中有误x,y{while(a){if(a->x==x&&a->y==y)return 1;a=a->next;}return 0;}int panduan2(S *a,int x,int y){a=a->next;/蛇尾不判断while(a->next){if(a->x==x&&a->y==y)return 1;a=a->next;}return 0;}
如果觉得《基于链表的贪吃蛇(C语言)》对你有帮助,请点赞、收藏,并留下你的观点哦!