#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();}/核心所在,在循环中监听有无字符输入
//
/检查,让程序更加强壮,减少BUG
if(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);
?? ?else?
?? ??? ?shewei->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;
}
??
|