0
点赞
收藏
分享

微信扫一扫

基于链表的贪吃蛇(C语言)

code_balance 2022-04-14 阅读 29
c语言
#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;
}
  


举报

相关推荐

0 条评论