用链表做控制台下的贪吃蛇小游戏

本人大一学了C语言后的课程设计:

以下是大体流程图:

这是我的运行代码:

#include<stdio.h>

#include<windows.h>

#include<time.h>

#include<conio.h>

#define X15//地图长

#define Y10//地图宽

/*  引用函数

system("cls");刷屏

 

kbhit()若有键盘输入返回非0

 

Sleep();使程序停顿                                                     sleep函数和kbhit函数结合起来就可以实现键盘输入改变蛇方向,否则蛇继续运行的作用

 

HANDLEhOut; 控制光标位置

COORD pos={0,2}; /* 光标的起始位(第1列,第3行) 0是第1列 2是第3行0  

hOut =GetStdHandle(STD_OUTPUT_HANDLE);             通过改变COORD pos 的坐标就可以自如的控制光标位置,非常好用

SetConsoleCursorPosition(hOut,pos);

      

*/

int Welcome(void);//用户欢迎界面

void Map_border(int,int);//定义地图边境

int Death(struct Snake *);//判断蛇是否死亡

void Body(struct Snake *);//显示蛇形

void Move(struct Snake *,char,struct Food *);//移动每个节点

void food(struct Food*);//显示食物

void Del_node(struct Snake *head);//清除链表

void End(void);//显示结束界面

struct Snake{

         int x;

         int y;

         char direction;

         Snake *next;

};//定义蛇节点

struct Food{

         int x;

         int y;

};

int len=sizeof(struct Snake);

int score;//所吃食物个数

int main()

{

         HANDLE hOut;//光标的起始位(第1列,第1行) 0是第1列 2是第3行0  

    hOut = GetStdHandle(STD_OUTPUT_HANDLE);

         srand((unsigned)time(NULL));//产生随机数以便产生食物和蛇头

         char choice;

         char s='N';

         struct Snake *head;

         struct Food *F;

         int speed;//游戏速度

         speed=Welcome()*100;

         do

         {

                   s='N';

                   score=0;

                   F=(struct Food*)malloc(sizeof(struct Food));

                   head=(struct Snake*)malloc(len);

                   head->x=rand()%X;

                   head->y=rand()%Y;

                   head->direction='e';

                   head->next=NULL;//初始化蛇头

                   do

                   {

                            F->x=rand()%X;

                            F->y=rand()%Y;//初始化食物

                   }while((F->x==0)||(F->y==0)||(F->x==X-1)||(F->y==Y-1));

                   while(Death(head)!=0)//判断死亡没有

                   {

                            choice='\0';

                            Map_border(X,Y);//显示地图

                            Body(head);//显示蛇身

                            food(F);//显示食物

                            COORD pos={(head->x)*2,head->y};

                            SetConsoleCursorPosition(hOut,pos);

                            printf("⊙");//再次显示蛇头

                            Sleep(speed);//停顿程序

                            if(kbhit())//等待键盘输入

                            {

                                     choice=getch();

                                     printf("\b");

                            }

                            system("cls");//清屏

                            Move(head,choice,F);//移动和增加节点

                   }

                   End();

                   Del_node(head);//清除蛇链表

                   free(F);//清除食物内存

                   s=getchar();

         }while(s=='Y');//判断是否重新开始

         return 0;

}

void Map_border(int x,int y)//定义地图边境

{

         int i,j;

         for(i=0;i<y;i++)

         {

                   printf("■");

                   if(i==0||i==y-1)

                            for(j=1;j<x-1;j++)

                            {printf("■");}

                   else

                            for(j=1;j<x-1;j++)

                            {printf("  ");}

                   printf("■\n");

         }

         return;

}

int Death(struct Snake *head)//判断蛇是否死亡

{

         struct Snake *ptr;

         if(head->x==X-1||head->y==Y-1||head->x==0||head->y==0)//不超界

                   return 0;

         for(ptr=head->next;ptr!=NULL;ptr=ptr->next)

         {

                   if((head->x==ptr->x)&&(head->y==ptr->y))//蛇头不咬身子

                            return 0;

         }

         return 1;

}

void Move(struct Snake *head,char choice,struct Food *F)//移动每个节点

{

         int x,m;

         int y,n;

         struct Snake *p,*ptr;

         struct Snake *last=NULL;

         ptr=head;

         x=head->x;

         y=head->y;

         if((F->x==head->x)&&(F->y==head->y))//如果吃到食物增加节点

         {

                   score+=1;

                   last=(struct Snake*)malloc(len);

                   do

                   {

                            F->x=rand()%X;

                            F->y=rand()%Y;

                   }while((F->x==0)||(F->y==0)||(F->x==X-1)||(F->y==Y-1));

                   last->next=NULL;

         }

         if(choice=='w'||choice=='a'||choice=='s'||choice=='d')

                   head->direction=choice;//改变蛇头方向

         switch(head->direction)//移动头节点

         {

         case 'w':head->y=head->y-1;break;

         case 's':head->y=head->y+1;break;

         case 'a':head->x=head->x-1;break;

         case 'd':head->x=head->x+1;break;

         }

         for(p=head->next;p!=NULL;p=p->next)//头节点以后的每个节点继承上一个节点的坐标

         {

                   m=p->x;

                   n=p->y;

                   p->x=x;

                   p->y=y;

                   x=m;

                   y=n;

                   ptr=p;

         }

         if(last!=NULL)//吃到食物后增加的节点继承上个状态的尾节点坐标

         {

                   ptr->next=last;

                   last->x=x;

                   last->y=y;

         }

         return;

}

void food(struct Food *F)//根据食物坐标显示食物

{

         HANDLE hOut;

    hOut = GetStdHandle(STD_OUTPUT_HANDLE);

         COORD pos= {(F->x)*2,F->y};

         SetConsoleCursorPosition(hOut, pos);

         printf("ff");

         return;

}

void Body(struct Snake *head)//根据蛇每个节点坐标显示蛇身

{

         HANDLE hOut;    

         hOut = GetStdHandle(STD_OUTPUT_HANDLE);

         struct Snake *p;

         for(p=head->next;p!=NULL;p=p->next)

         {

                   COORD pos={(p->x)*2,p->y};

                   SetConsoleCursorPosition(hOut,pos);

                   printf("□");

         }

         return;

}

void Del_node(struct Snake *head)//清除链表

{

         struct Snake *p1,*p2;

         p2=head;

         for(p1=head->next;p1!=NULL;p1=p1->next)

         {

                   free(p2);

                  p2=p1;

         }

         return;

}

void End(void)//显示积分

{

         printf("**********************************************\n");

         printf("*                                           *\n");

         printf("*                                           *\n");

         printf("*                  Game Over                 *\n");

         printf("*             Your score is %d               *\n",score);

         printf("*                                           *\n");

         printf("*              enter Y play again            *\n");

         printf("*              else enter any key            *\n");

         printf("*                                           *\n");

         printf("*                                           *\n");

         printf("*                                           *\n");

         printf("*                                            *\n");

         printf("**********************************************\n");

}

int Welcome(void)//显示欢迎界面

{

         int sum;

         printf("**********************************************\n");

         printf("*                                           *\n");

         printf("*                                            *\n");

         printf("*            欢迎使用贪吃蛇游戏              *\n");

         printf("*                                           *\n");

         printf("*                                           *\n");

         printf("*             W键:上   S键:下              *\n");

         printf("*             A键:左  D键:右              *\n");

         printf("*                                           *\n");

         printf("*                                           *\n");

         printf("*          选择游戏速度后开始游戏            *\n");

         printf("*    1~3:困难    4~7:中等    7~10:缓慢   *\n");

         printf("**********************************************\n");

         scanf("%d",&sum);

         getchar();

         return sum;

}

这是游戏运行的图文:


请大家广泛留言哈!嘻嘻~~~~~~


  • 4
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 6
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值