C语言贪食蛇

我们先来看一下C语言的贪食蛇代码,相对于面向对象的的语言,C语言是一门面向过程的语言,C语言写出来的代码都是顺着平常的思路来一步一步实现的,我们先来看C语言的代码

#include<stdio.h>
#include<stdlib.h>
#include<windows.h>
#include<time.h>
//函数声明区
void Pos(int x, int y);//光标位置设定
void muban();//打印模板
void initSnake();//蛇身的初始化
void creatFood();//创建食物
char reDirection();//识别方向
int snakeMove();//蛇移动
int crossWall();//不能穿墙
int eatSelf();//不能吃自己

typedef struct Snake//相当于蛇一个节点
{
    int x;//横坐标
    int y;//纵坐标
    struct Snake *next;
}snake;
snake *head;//头指针
snake *p;//用来遍历
snake *food1;//用来标记的
char status='L';//初始方向的状态,解决开始会动的问题
int score=0;//分数
int add=10;//一个食物的分
int leap=0;//用来标志是否结束,0没有,1代表蛇死了代表结束了
int endleap=0;//结束标志 1就是结束
int sleepTime=500;
void initSnake()//蛇身初始化,给定一个长度,用结构体表示是蛇的骨架,真正要显示出来是打印▇
{
    int i;
    snake *tail;//尾指针
    tail=(snake*)malloc(sizeof(snake));//第一个节点/头结点
    tail->x=30;//2的倍数,因为方块的长是两个单位
    tail->y=10;//1个单位
    tail->next=NULL;
    for(i=1;i<=4;i++)//尾插法
    {
        head=(snake*)malloc(sizeof(snake));//申请一个节点
        head->next=tail;//连接成链
        head->x=30-2*i;//下一个节点的位置
        head->y=10;
        tail=head;
    } 
    //遍历打印出来
    while(tail!=NULL)
    {
        Pos(tail->x,tail->y);
        printf("▇");
        tail=tail->next;
    }


}

char reDirection()//识别用户按下的键值  保留方向值
{
    if(GetAsyncKeyState(VK_F7))//热键 
    {
        if(sleepTime>300)//最多减到300
        {
            sleepTime-=50;//每次减50
            add++;//每次食物加1分
        }
    }
    if(GetAsyncKeyState(VK_F8))
    {
        if(sleepTime<800)//最多加到800
        {
            sleepTime+=50;//每次加50
            add--;//每次食物减1分
        }
    }
    if(GetAsyncKeyState(VK_UP)&&status!='D')
        status='U';
    if(GetAsyncKeyState(VK_DOWN)&&status!='U')
        status='D';
    if(GetAsyncKeyState(VK_LEFT)&&status!='R')
        status='L';
    if(GetAsyncKeyState(VK_RIGHT)&&status!='L')
        status='R';
        return status;
}
void Pos(int x, int y)//设置光标位置,从哪里开始输出
{
    COORD pos;//表示一个字符在控制台屏幕上的坐标,左上角(0,0)
    HANDLE hOutput;
    pos.X = x;
    pos.Y = y;
    hOutput = GetStdHandle(STD_OUTPUT_HANDLE);//返回标准的输入、输出或错误的设备的句柄,也就是获得输入、输出/错误的屏幕缓冲区的句柄
    SetConsoleCursorPosition(hOutput, pos);
}


void creatFood()//创建食物
{
    snake *food;//创造一个食物
    food=(snake*)malloc(sizeof(snake));
    srand((unsigned int)time(NULL));//随着时间变化,产生不一样种子,就会得到没规律的食物
    while(food->x%2!=0)
    {
        food->x=rand()%56+2;
    }
    food->y=rand()%23+1;

    //上面虽然解决了食物不会出现在城墙里,没有考虑食物出现在蛇本身里面
    p=head;//用p来遍历
    while(p!=NULL)//解决食物出现在蛇本身
    {
            if(food->x==p->x&&food->y==p->y)
            {
                free(food);
                creatFood();
            }
            p=p->next;
    }
    Pos(food->x,food->y);
    food1=food;//food1用来标记的作用
    printf("▇");
    Pos(70,20);//解决有光标闪烁的办法
    printf("您的分数是:%d",score);
}
void muban()
{   
    int i;
    for(i=0;i<=60;i+=2)//方块水平方向占两个单位
    {
       Pos(i,0);
       printf("▇");//上行
       Pos(i,26);
       printf("▇");//下行
    }
    for(i=0;i<=25;i+=1)//方块垂直方向占1个单位
    {
       Pos(0,i);//左列
       printf("▇");
       Pos(60,i);//右列
       printf("▇");
    }
}

int snakeMove()
{
    snake *nexthead;
    nexthead=(snake*)malloc(sizeof(snake));
    if(status=='R')//向右走
    {
        nexthead->x=head->x+2;
        nexthead->y=head->y;
        if(nexthead->x==food1->x&&nexthead->y==food1->y)//吃掉了食物
        {
            nexthead->next=head;
            head=nexthead;
            p=head;//p用来从头遍历,打印方块
            while(p!=NULL)
            {
                Pos(p->x,p->y);
                printf("▇");
                p=p->next;
            }//吃掉了食物得创造
            score=score+add;
            creatFood();

        }
        else//没有食物
        {
            nexthead->next=head;
            head=nexthead;
            p=head;//p用来从头遍历,打印方块
            while(p->next->next!=NULL)
            {
                Pos(p->x,p->y);
                printf("▇");
                p=p->next;
            }
            Pos(p->next->x,p->next->y);
            printf("  ");//会带来一个光标闪烁
            Pos(70,20);//解决办法
            printf("您的分数是:%d",score);
            free(p->next);
            p->next=NULL;
        }
    }
        if(status=='L')//向左走
    {
        nexthead->x=head->x-2;
        nexthead->y=head->y;
        if(nexthead->x==food1->x&&nexthead->y==food1->y)//吃掉了食物
        {
            nexthead->next=head;
            head=nexthead;
            p=head;//p用来从头遍历,打印方块
            while(p!=NULL)
            {
                Pos(p->x,p->y);
                printf("▇");
                p=p->next;
            }//吃掉了食物得创造
            score=score+add;
            creatFood();

        }
        else//没有食物
        {
            nexthead->next=head;
            head=nexthead;
            p=head;//p用来从头遍历,打印方块
            while(p->next->next!=NULL)
            {
                Pos(p->x,p->y);
                printf("▇");
                p=p->next;
            }
            Pos(p->next->x,p->next->y);
            printf("  ");
            Pos(70,20);//解决办法
            printf("您的分数是:%d",score);
            free(p->next);
            p->next=NULL;
        }
        }
        if(status=='U')//向上走
    {
        nexthead->x=head->x;
        nexthead->y=head->y-1;
        if(nexthead->x==food1->x&&nexthead->y==food1->y)//吃掉了食物
        {
            nexthead->next=head;
            head=nexthead;
            p=head;//p用来从头遍历,打印方块
            while(p!=NULL)
            {
                Pos(p->x,p->y);
                printf("▇");
                p=p->next;
            }//吃掉了食物得创造
            score=score+add;
            creatFood();

        }
        else//没有食物
        {
            nexthead->next=head;
            head=nexthead;
            p=head;//p用来从头遍历,打印方块
            while(p->next->next!=NULL)
            {
                Pos(p->x,p->y);
                printf("▇");
                p=p->next;
            }
            Pos(p->next->x,p->next->y);
            printf("  ");
            Pos(70,20);//解决办法
            printf("您的分数是:%d",score);
            free(p->next);
            p->next=NULL;
        }
        }
        if(status=='D')//向下走
    {
        nexthead->x=head->x;
        nexthead->y=head->y+1;
        if(nexthead->x==food1->x&&nexthead->y==food1->y)//吃掉了食物
        {
            nexthead->next=head;
            head=nexthead;
            p=head;//p用来从头遍历,打印方块
            while(p!=NULL)
            {
                Pos(p->x,p->y);
                printf("▇");
                p=p->next;
            }//吃掉了食物得创造
            score=score+add;
            creatFood();

        }
        else//没有食物
        {
            nexthead->next=head;
            head=nexthead;
            p=head;//p用来从头遍历,打印方块
            while(p->next->next!=NULL)
            {
                Pos(p->x,p->y);
                printf("▇");
                p=p->next;
            }
            Pos(p->next->x,p->next->y);
            printf("  ");
            Pos(70,20);//解决办法
            printf("您的分数是:%d",score);
            free(p->next);
            p->next=NULL;
        }
        }

    Sleep(sleepTime);//蛇移动的速度,里面是毫秒,越大速度越慢
    status=reDirection();//判别下方向先
    if(crossWall()==1||eatSelf()==1)
        //exit(0);//直接把程序关闭了
       endleap=1;
    return endleap;

}

int crossWall()//判断蛇有没穿透墙
{
    if(head->x==0||head->y==0||head->x==60||head->y==25)
        leap=1;
    return leap;
}
int eatSelf()//判断是否咬到了自己
{
    snake *q;//遍历的
    q=head->next;
    while(q!=NULL)
    {
        if(q->x==head->x&&head->y==q->y)
            leap=1;
        q=q->next;
    }
    return leap;
}
//打印食物的时候会出现光标,解决办法就是引开它

int main()
{
    muban();//打印模板
    initSnake();//初始化蛇
    creatFood();//创建食物
    while(1)//死循环,让蛇一直动起来,直到蛇死了
    {
        if(snakeMove()==1)//判断是否结束
        {
            Pos(70,23);
            printf("蛇死了");
            system("pause");//用来暂停
            Pos(70,24);//解决press any key  to continue   在该地点打印  大家试下
            break;
        }

    }
    printf("是否继续游戏,y or n:");//y 继续
    if(getch()=='y')//重新游戏
    {
        //蛇一开始就死了,因为全局变量没有恢复原值,仍然保留上一局的值
        status='L';//初始方向的状态,解决开始会动的问题
        score=0;//分数
        add=10;//一个食物的分
        leap=0;//用来标志是否结束,0没有,1代表蛇死了代表结束了
        endleap=0;//结束标志 1就是结束
        sleepTime=500;
        system("cls");//清理屏幕
        main();//自己调用自己 看不一样的编译器,vc6.0允许调用自己
    }
    if(getch()=='n')
    {
        Pos(70,25);//定一个位置,再打印press 
        exit(0);//退出程序
    }

    return 0;
}

//蛇的速度变化,每个食物的分数增加
//是否继续游戏
//按键的作用

在C语言中,我们利用定义一个一个函数模块来实现蛇的基础实现,然后定义蛇的一个结构体,利用链表的知识来串联蛇身体,来让蛇身连接起来并走动起来。
/go语言实现的贪食蛇请见博客/

猜你喜欢

转载自blog.csdn.net/sgsgy5/article/details/81605475