用队列写贪吃蛇(C语言版)

来源:互联网 发布:记账app 知乎 编辑:程序博客网 时间:2024/05/19 09:47

By Tomas 2016.3.2
编程语言: C
程序介绍: 利用队列这个数据结构编写一个简单的贪吃蛇小游戏。

原理分析: 队列的特点就是先进先出(FIFO),我们就是利用他的这个特点来模拟一条贪吃蛇。我们首先考虑一下这个游戏需要哪些元素,然后怎么用终端模拟这些元素。

蛇:蛇在终端上的表示就是很多个字符连在一起就是蛇,比如: @@@@ 或者 2222222 都是一条蛇。然而,队列是有队头和队尾之分,那么用它表示的蛇也必须有蛇头和蛇尾。这个点很重要,就是需要用队尾表示蛇头,因为队列是先进先出的数据结构,蛇在移动的时候,他的尾巴要消失,然后需要在移动的方向上加上一段蛇,这样就能使蛇移动。在数据结构上来说就是队列的一个元素先出队列,然后再将一个元素人队。如图:

蛇的移动:

蛇一:
这里写图片描述

蛇二: 蛇一向下移动
尾巴消失
这里写图片描述

然后在下方添加一段蛇,这样蛇就向下移动了

这里写图片描述

蛇吃到食物:
看了蛇的移动,那么蛇吃到食物比移动更容易,直接将一段蛇添加到原来的蛇上面就好了,在数据结构上就是表现为一个元素进入队列的操作。如图:
蛇向下走一步就可以吃到食物了。
这里写图片描述

蛇吃到食物,变成三个节点。
这里写图片描述

以上是蛇正常游戏,那么接下来就是游戏结束的条件。
撞到边框: 边框就用坐标表示,然后在对应的坐标上输出字符。
撞到自己: 每走一步,就判断头的坐标是否与原来蛇的节点坐标重复,若重复则游戏结束。

以下是参考代码:

#include<stdio.h>#include<conio.h>#include<windows.h>#include<process.h>#include<stdlib.h>#include<time.h>                       //引用头文件enum Diriction{    UP,DOWN,LEFT,RIG};struct Snake{                              //定义蛇的节点    int x;    int y;    struct Snake *next;};                                      struct Serpent{    enum Diriction dir;                   //定义蛇的方向    int lenght;                           //定义蛇的长度};struct Food{    int a;    int b;};                                         //定义食物的坐标//全局变量,在全体函数都可以用的到的变量,在这只声明一次就可以了struct Snake *head,*tail;           //定义蛇头和蛇尾的指针,就相当于队列的头和尾,head是队头,tail是队尾struct Food *food;                         //定义食物struct Serpent *serpent;                   //定义蛇的方向和长度int getit=0;                               //判断是否得分,若是则可投放食物//声明以下可用到的函数void Gotoxy();                                  //定位光标void Initsnake();                          //初始化蛇void Home();                                     //绘制边框void Initfood();                           //投放食物void Keyhit();                                    //键盘控制        void Move();                                   //蛇身的移动void Addtail(int x, int y);                   //增加队尾长度void clearhead();                             //清除上次的队头void Print();                //打印画面int main(){    Initsnake();               //初始化蛇    while(1)               {        Keyhit();                //键盘输入        Move();                  //移动        system("cls");        Print();                 //打印        Sleep(100);              //每隔100毫秒刷新游戏界面                 };    return 0;}void Gotoxy(int x, int y)                 //定位光标,网上搜的{     COORD pos;     pos.X = x - 1;     pos.Y = y - 1;    SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE),pos); }void Initsnake(){    int i;    head=tail=(struct Snake*)malloc(sizeof(struct Snake));     //初始化队列       food=(struct Food*)malloc(sizeof(struct Food));                       serpent=(struct Serpent*)malloc(sizeof(struct Snake));       //为全局变量开辟内存    head->next=NULL;    serpent->dir=RIG;    serpent->lenght=4;    for(i=0;i<serpent->lenght;i++)        Addtail(10+i,10);    Initfood();                                            //初始化食物}void Home(){    int a;                                     for(a=0;a<31;a++)                             //30*16        printf("%c", 3);    printf("\n");    for(a=0;a<16;a++)        printf("%c                             %c\n",3,3);    for(a=0;a<31;a++)        printf("%c", 3);                                //直接打印边框}void Initfood()                                   //投放食物{    int m=1;    getit=0;    struct Snake *q=head;                        //将蛇头附给指针q    srand((unsigned)time(NULL));        //以时间为种子产生随机数    food->a=rand()%(30-2)+2;                         //这是随机数,并限制了食物的出现范围    food->b=rand()%(15-2)+2;    while(q!=tail)                              //遍历蛇,判断是否食物是否在蛇身上??    {        if(q->x==food->a &&q->y==food->b)     //蛇身上rice=0,食物无效            {                m=0;               break;}        q=q->next;    }    if(m==0)        Initfood();                                 //食物无效,隐含rice==0,又调用一次                            }void Keyhit(){    char n;    if(_kbhit())                                //无阻隔输入    {        n=_getch();                 //警告    1   warning C4996: 'getch': The POSIX name for this item is deprecated.        switch(n)        {        case 'w':            {            if(serpent->dir==DOWN)   //判断输入方向与蛇的方向是否相同,是则输入无效                         break;            else                serpent->dir=UP;break;             }        case 's':            {                if(serpent->dir==UP)                    break;                else                    serpent->dir=DOWN;break;            }        case 'a':            {                if(serpent->dir==RIG)                    break;                else                    serpent->dir=LEFT;break;            }        case 'd':            {                if(serpent->dir==LEFT)                    break;                else                    serpent->dir=RIG;break;            }        }    }}void Move(){    int a=0;    struct Snake *p;    struct Snake *q;    p=tail;                                      //将队尾附给p    switch(serpent->dir)    {    case UP:            Addtail(p->x,p->y-1);break;            //添加队尾    case DOWN:            Addtail(p->x,p->y+1);break;    case LEFT:            Addtail(p->x-1,p->y);break;    case RIG:                         Addtail(p->x+1,p->y);break;    }     if(tail->x==food->a &&tail->y==food->b)        //吃到食物    {        serpent->lenght++;                //记分        getit=1;    }    if(getit!=1)                             //如果没吃到食物清除队尾        clearhead();    p=tail;    q=head;                                 while(q!=tail)                              //判断是否撞到自己    {        if(q->x==p->x &&q->y==p->y)                        exit(0);        q=q->next;    }    if(tail->x>30 || tail->y>17||tail->x<=1 ||tail->y<=1)       //超边框退出        exit(0);}void Addtail(int x,int y)                 //压入队{    struct Snake *newnode=(struct Snake*)malloc(sizeof(struct Snake));    newnode->x=x;    newnode->y=y;    newnode->next=NULL;    tail->next=newnode;    tail=newnode;                 //将新的节点附给队尾}void clearhead()                                     //这是清除队尾{    struct Snake *p;    p=head;    p=p->next;    head=p;}void Print()                                   //打印画面{    Home();    Gotoxy(food->a,food->b);                   //打印食物    printf("%c", 4);    struct Snake *q;    q=head;    Gotoxy(tail->x,tail->y);    printf("%c",5);    while(q!=tail)                           //打印蛇    {        Gotoxy(q->x,q->y);        printf("%c",2);        q=q->next;    }    if(getit==1)                              //判断食物是否被吃        Initfood();    Gotoxy(30,20);    printf("score :%d", serpent->lenght-4); //分数}
0 0
原创粉丝点击