贪吃蛇游戏部分代码运行问题

我按照课本要求做了一个贪吃蛇小游戏,以下是完整代码

/*******头文件*******/ 
#include<stdio.h>
#include<time.h>
#include<windows.h>
#include<stdlib.h>
#include<conio.h>
/*******宏定义*******/
#define U 1
#define D 2
#define L 3
#define R 4        //蛇的状态,U:上;D:下;L:左;R:右 

/*******函 数 声 明*******/
void gotoxy(int x,int y);      //设置光标位置
int color(int c);              //更改文字颜色
void printsnake();             //字符画,蛇
void welcometogame();          //开始界面
void createMap();             //绘制地图
void scoreandtips();          //游戏界面右侧的得分和小提示
void initsnake();             //初始化蛇身,画蛇身
void createfood();            //创建并随机出现食物
int biteself();               //判断是否咬到自己
void cantcrosswall();          //判断是否撞墙
void speedup();               //加速
void speeddown();             //减速
void snakemove();              //控制蛇前进方向
void keyboardControl();         //控制键盘按键
void Lostdraw();              //游戏结束界面
void endgame();              //游戏结束
void choose();               //游戏失败之后的选择
void File_out();              //在文件中读取最高分
void File_in();              //将最高分存进文件
void explation();            //游戏说明

/*******定义全局变量*******/
typedef struct snake         //蛇身的一个节点
{
int x;          //节点的x坐标
int y;          //节点的y坐标
struct snake *next;    //蛇身的下一节点
}snake;

int score = 0, add = 10;         //总得分与每次吃食物得分
int HighScore = 0;          //最高分
int status,sleeptime=200;    //蛇前进状态,每次运行的时间间隔
snake *head, *food;         //蛇头指针,食物指针
snake *q;                  //遍历蛇时用到的指针
int endgamestatus=0;       //游戏结束的情况:撞到墙;咬到自己;主动退出游戏
HANDLE hout;              //控制台句柄

/*******文字颜色函数*******/
int color(int c)
{
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),c);//改变文字颜色 
return 0;
}



/*******设置光标位置*******/
void gotoxy(int x,int y)
{
COORD c;
c.X=x;
c.Y=y;
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE),c);      //定位光标位置
}

/*******字符蛇*******/
void printsnake()
{
    system("color a");
    printf("                                                                                         \n");
    printf("                       __________       ___                                              \n");
    printf("                      /          \\     / \\ \\    |____      __\\__                     \n");
    printf("                     /  ________  \\   / ___ \\  _/ __     | |   /                       \n");
    printf("                     |  |      |__|     _/_   |_|  /    [|] |/                           \n");
    printf("                     |  |              | | |      /     _|_ \\__/                        \n");
    printf("                     \\  \\_______        / \\      |___/        ____                    \n");
    printf("                      \\         \\    ____ ____      ____   __ |  |  ___   ______       \n");
    printf("                       \\_______  \\   |  |/    \\    /    \\_/ / |  | /  /  /      \\   \n");
    printf("                               \\  \\  |    ___  \\  / ____   /  |  |/  /  /  ____  \\   \n");
    printf("                     __        |  |  |   /   \\  \\ | |  |  /   |     /  |  /____\\  |   \n");
    printf("                    \\  \\_______|  |  |  |    |  | | |__|  |   |     \\  |  ________/   \n");
    printf("                     \\            /  |  |    |  |  \\       \\  |  |\\  \\  \\  \\____  \n");
    printf("                      \\__________/   |__|    |__|   \\___/\\__\\ |__| \\__\\  \\______/ \n");    
}

/******欢迎界面******/
void welcometogame()
{
int n;
int i,j=1;gotoxy(43,18);color(11);
printf("贪 吃 蛇 大 作 战");
color(14);           //黄色边框 
for (i = 20;i <= 26;i++)         //输出上下边框 
{
    for (j =27; j <= 74; j++)    //输出左右边框 
    {
        gotoxy(j,i);
        if (i ==20 || i==26)
        {
            printf("-");
        }
        else if (j == 27 || j == 74)
        {
          printf("|");
        }
    }
}
color(12);              //红色
gotoxy(35,22);         //设置文字显示位置
printf("1.开始游戏");
gotoxy(55,22);
printf("2.游戏说明");
gotoxy(35,24);
printf("3.退出游戏");
gotoxy(29,27);
color(3);             //深蓝绿色
printf("请选择[1 2 3]:[ ]\b\b");           //\b为退格,使得光标处于[]中间
color(14);           //黄色
scanf("%d",&n);              //输入选项
switch (n)               //三个选项
{
case 1:                  
    system("cls");       //清屏
    createMap();          //创建地图 
    initsnake();          // 初始化蛇身 
    createfood();         //创建食物 
    break;
case 2:                 
    explation(); 
    break;
case 3:                
    exit(0);           //退出程序
    break;
default:               //输入非1~3之间的选项
color(12);
gotoxy(40,28);
printf("请输入1~3之间的数!");
getch();              //输入任意键
system("cls");         //清屏
printsnake();
welcometogame();
    }
}

/***创建地图****/
void createMap()
{
int i,j;
for(i=0;i<58;i+=2)      //打印上下边框
     {
gotoxy(i,0);
color(5);               //深紫色的边框
printf("◇");
gotoxy(i,26);
printf("◇");
     }
for(i=1;i<26;i++)       //打印左右边框 
{

gotoxy(0,i);
printf("◇");
gotoxy(56,i);
printf("◇");
}
for(i=2;i<56;i+=2)     //打印中间网格 
{
for(j=1;j<26;j++)
{
gotoxy(i,j);
color(3);
printf("■\n\n");
         }
      }
  }
 
/***游戏界面右侧的得分和小提示***/
void scoreandtips()
{
File_out();               //调用File_out()函数,读取文件save.txt中的内容
gotoxy(64,4);            //确定打印输出的位置
color(11);               //设置颜色
printf("☆最高记录☆:%d",HighScore);     //打印游戏最高分
gotoxy(64,8);
color(14); 
printf("得分:%d",score);
color(13);
gotoxy(73,11);
printf("小 提 示");
gotoxy(60,13);
color(6);
printf("╬-------------------------------------╬");       //打印边框 
gotoxy(60,25);
printf("╬-------------------------------------╬");
color(3);
gotoxy(64,14);
printf("每个食物得分:%d分",add);
gotoxy(64,16);
gotoxy(64,16);
printf("不能撞墙,不能咬到自己");
gotoxy(64,18);
printf("用↑ ↓ ← →分别控制蛇的移动");
gotoxy(64,20);
printf("F1:加速,F2:减速");
gotoxy(64,22);
printf("Space:暂停游戏");
gotoxy(64,24);
printf("Esc:退出游戏");
}

/*在文件中读取最高分*/
void File_out()
{
FILE *fp;
fp = fopen("save.txt","a+");      //打开文件save.txt
fscanf(fp,"%d",&HighScore);       //把文件中的最高分读出来
fclose(fp);                       //关闭文件
}

/****初始化蛇身,画蛇身****/
void initsnake()
{
snake *tail;
int i;
tail=(snake*)malloc(sizeof(snake));        //从蛇尾开始,头插法,以x,y设定开始的位置
tail->x=24;                               //蛇的初始位置(24,5)
tail->y=5;
tail->next=NULL;
for(i=1;i<=4;i++)                        //设置蛇身,长度为5
      {
head=(snake*)malloc(sizeof(snake));        //初始化蛇头
head->next=tail;                         //蛇头的下一位为蛇尾
head->x=24+2*i;                          //设置蛇头位置
head->y=5;
tail=head;                               //蛇头变成蛇尾,然后重复循环
      }
while(tail!=NULL)                          //从头到尾,输出蛇身
      {
gotoxy(tail->x,tail->y);
color(14);
printf("●");                             //输出蛇身,蛇身使用●组成
tail=tail->next;                        //蛇头输出完毕,输出蛇头的下一位,一直输出到蛇尾
      }
}

/***随机出现食物***/
void createfood()
{
snake *food_1;
srand((unsigned)time(NULL));                 //初始化随机数
food_1=(snake*)malloc(sizeof(snake));      //初始化food_1
//保证其为偶数,使得食物能与蛇头对齐,然后食物会出现在网格线上
while((food_1->x%2)!=0)
  {
       food_1->x=rand()%52+2;
  }
food_1->y=rand()%24+1;
q=head;
while(q->next==NULL)
  {
if(q->x==food_1->x && q->y==food_1->y)    //判断蛇身是否与食物重合
     {
          free(food_1);                  //如果蛇身和食物重合,那么释放食物指针
        createfood();                    //重新创建食物
     }
      q=q->next;
  }
gotoxy(food_1->x,food_1->y);            //设置食物的位置
food=food_1;
color(12);
printf("★");                          //输出食物
}

/***判断是否咬到了自己***/
int biteself()
{
snake *self;                              //定义self为蛇身上的一个节点
self=head->next;                         //self是蛇头之外的蛇身上的节点
while(self!=NULL)
  {
if(self->x==head->x && self->y==head->y)     //如果self和蛇头上的节点重合
    {
return 1;                                //返回1,蛇咬到自己,游戏失败
    }
    self=self->next;                     //循环射身上的每一个节点 
  }
  return 0;
}

/*****设置蛇撞墙的情况*****/
void cantcrosswall()
{
  if(head->x==0 || head->x==56 || head->y==0 || head->y==26)        //如果蛇头碰到了墙壁
  {
     endgamestatus=1;                                               //返回游戏结束的第一种情况,即蛇撞到墙
     endgame();
  }
}

/*****加速,蛇吃到食物或按<F1>键,会自动提速*****/
void speedup()
{
if(sleeptime>=50)               //如果时间间隔大于等于50
  {
sleeptime=sleeptime-10;         //时间间隔减10
add=add+2;                      //每吃一次食物的得分加2
  }
}

/***减速,按<F2>键,会自动减速***/
void speeddown()
{
if(sleeptime<350)              //如果时间间隔小于350
  {
    sleeptime=sleeptime+30;    //时间间隔加上30
    add-add-2;                 //每吃一次食物的得分减2
if(sleeptime==350)
    {
       add=1;                 //保证最低分为1
    }
  }
}

/****控制方向****/
void snakemove()                         //蛇前进,上U,下D,左L,右R
{
snake * nexthead;
cantcrosswall();
nexthead=(snake*)malloc(sizeof(snake));  //为下一步开辟空间
if(status==U)
  {
    nexthead->x=head->x;                 //向上前进时,x坐标不变,y坐标-1
    nexthead->y=head->y-1;
    nexthead->next=head;
    head=nexthead;
    q=head;                             //指针q指向蛇头
  
//如果下一个位置上有食物,下一个位置的坐标和食物的坐标相同
if(nexthead->x==food->x && nexthead->y==food->y)
  {
     while(q!=NULL)
      {
        gotoxy(q->x,q->y);
        color(14);
        printf("●");                    //原来食物的位置,将食物★换成蛇●
        q=q->next;                       //指针q指向的蛇身的下一位,也执行循环里的操作
      }
    score=score+add;                   //吃了一个食物,在总分上加上食物的分
    speedup();
    createfood();                       //创建食物
  }
  else
  {
    while(q->next->next!=NULL)      //如果没遇到食物
    {
      gotoxy(q->x,q->y);
      color(14);
      printf("●");                 //蛇正常往前走,输出当前位置的蛇身
      q=q->next;                    //继续输出整个蛇身
    }
//经过上面的循环,q指向蛇尾,蛇尾的下一位,就是蛇走过去的位置
      gotoxy(q->next->x,q->next->y);
      color(3);
      printf("■");
      free(q->next);               //输出■之后,释放指向下一位的指针
      q->next=NULL;               //指针下一位指向空
  }
}
if(status==D)
{
nexthead->x=head->x;
nexthead->y=head->y+1;
nexthead->next=head;
head=nexthead;
q=head;
if(nexthead->x==food->x && nexthead->y==food->y)        //有食物
  {
    while(q!=NULL)
    {
      gotoxy(q->x,q->y);                               //向下前进时,x坐标不变,y坐标+1
      color(14);
      printf("●");
      q=q->next;
    }
    score=score+add;                                   //得分
    speedup();                                         //加速
    createfood();                                      //继续生成食物
}
//食物变成蛇身上的一部分,即被蛇吃掉

else                                                        //没有食物
  {
    while(q->next->next!=NULL)
    {
      gotoxy(q->x,q->y);
      color(14);
      printf("●");
      q=q->next;
    }
    gotoxy(q->next->x,q->next->y);                         //蛇走过的路线变回棋盘原有的图案
    color(3);
    printf("■");
    free(q->next);                                        //释放指针
    q->next=NULL;
  }
}
if(status==L)
{
  nexthead->x=head->x-2;                                //向左前进时,x坐标向左移动-2,y坐标不变
  nexthead->y=head->y;
  nexthead->next=head;
  head=nexthead;
  q=head;
  if(nexthead->x==food->x && nexthead->y==food->y)     //有食物
  {
    while(q!=NULL)
    {
      gotoxy(q->x,q->y);
      color(14);
      printf("●");
      q=q->next;
    }
    score=score+add;
    speedup();
    createfood();
  }
}
else                                                     //没有食物
{
  while(q->next->next!=NULL)
  {
    gotoxy(q->x,q->y);
    color(14);
    printf("●");
    q=q->next;
  }
    gotoxy(q->next->x,q->next->y);
    color(3);
    printf("■");
    free(q->next);
    q->next=NULL;
}
if(status==R)
{
  nexthead->x=head->x+2;                                //向右前进时,x坐标向右移动+2,y坐标不变
  nexthead->y=head->y;
  nexthead->next=head;
  head=nexthead;
  q=head;
  if(nexthead->x==food->x && nexthead->y==food->y)     //有食物
  {
    while(q!=NULL)
    {
      gotoxy(q->x,q->y);
      color(14);
      printf("●");
      q=q->next;
    }
    score=score+add;
    speedup();
    createfood();
  }
  else                                     //没有食物
  {
    while(q->next->next!=NULL)
    {
      gotoxy(q->x,q->y);
      color(14);
      printf("●");
      q=q->next;
    }
    gotoxy(q->next->x,q->next->y);
    color(3);
    printf("■");
    free(q->next);
    q->next=NULL;
  }
}
    if(biteself()==1)                                     //判断是否咬到自己
    {
    endgamestatus=2;
    endgame();
    }
}

/****控制键盘按键****/
void keyboardControl()
{
status=R;
while(1)
  {
scoreandtips();            //游戏界面右侧的得分和小提示
//GetAsynckeyState函数用来判断函数调用时指定虚拟键的状态
if(GetAsyncKeyState(VK_UP) && status!=D)
{
status=U;                //如果蛇不是向下前进时,按向上键 ↑,执行向上前进操作
}
else if(GetAsyncKeyState(VK_DOWN)&& status!=U)
{
status=D;                //如果蛇不是向上前进时,按向下键 ↓,执行向下前进操作
}
else if(GetAsyncKeyState(VK_LEFT)&& status!=R)
{
status=L;                 //如果蛇不是向右前进时,按向左键 ←,执行向左前进
}
else if(GetAsyncKeyState(VK_RIGHT)&& status!=L)
{
status=R;                //如果蛇不是向左前进时,按向右键 →,执行向右前进
}
if(GetAsyncKeyState(VK_SPACE))                   //按暂停键,执行Sleep()函数暂停进程
{
while(1)
   {
//Sleep()函数,头文件#include <unistd.h>,令进程暂停,直到达到里面设定的参数的时间。
Sleep(300);
if(GetAsyncKeyState(VK_SPACE))                  //按空格键暂停
     {
break;
     }
   }
}
else if(GetAsyncKeyState(VK_ESCAPE))
{
endgamestatus=3;                               //按<Esc>键,直接跳转到结束界面
break;
}
else if(GetAsyncKeyState(VK_F1))               //按<F1>键,加速
{
speedup();
}
else if(GetAsyncKeyState(VK_F2))               //按<F2>键,减速
{
speeddown();                                   //调用减速函数
}
Sleep(sleeptime);
snakemove();                                  //不按键时,蛇保持前进
  }
}

/***失败界面***/
void Lostdraw()
{
system("cls");
int i;
gotoxy(45,2);
color(6);
printf("\\\\\\|///");        //小人的头发
gotoxy(43,3);
printf("\\\\");
gotoxy(47,3);
color(15);
printf(".-.-");             //眉毛
gotoxy(54,3);
color(6);
printf("//");

gotoxy(44,4);
color(14);
printf("(");               //左耳

gotoxy(47,4);
color(15);
printf(".@.@");           //眼睛

gotoxy(54,4);
color(14);
printf(")");             //右耳

gotoxy(17,5);
color(11);
printf("+------------------------");  //上边框

gotoxy(35,5);
color(14);
printf("o00o");         //左手

gotoxy(39,5);
color(11);
printf("----------");                //上边框

gotoxy(48,5);
color(14);
printf("(_)");//嘴

gotoxy(51,5);
color(11);
printf("----------");               //上边框

gotoxy(61,5);
color(14);
printf("o00o");       //右手

gotoxy(65,5);
color(11);
printf("-----------------+");     //上边框

for(i = 6;i<=19;i++)             //竖边框
{
gotoxy(17,i);
printf("|");
gotoxy(82,i);
printf("|");
}

gotoxy(17,20);
printf("+--------------------------------");  //下边框

gotoxy(52,20);
color(14);
printf("☆☆☆”");

gotoxy(60,20);
color(11);
printf("----------------------+");           //下边框
}

/****结束游戏****/
void endgame()
{
system("cls");
if(endgamestatus==1)
{
Lostdraw();
gotoxy(35,9);
color(12);
printf("对不起,您撞到墙了。游戏结束!");
}
else if(endgamestatus==2)                //如果蛇咬到了自己
{
Lostdraw();
gotoxy(35,9);
color(12);
printf("对不起,您咬到自己了。游戏结束!");
}
else if(endgamestatus==3)               //如果按Esc键退出
{
Lostdraw();
gotoxy(40,9);
color(12);
printf("您已经结束了游戏。");
}
gotoxy(43,12);
color(13);
printf("您的得分是%d",score);
if(score >= HighScore)                   //如果分数高于最高分
{
color(10);
gotoxy(33,16);
printf("创纪录啦!最高分被你刷新啦,真棒!!!");
File_in();                             //把最高分写进文件
}
else                                     //如果分数低于最高分
{
color(10);
gotoxy(33,16);
printf("继续努力吧~ 你离最高分还差:%d",HighScore-score);
}
choose();                             //边框下面的分支选项
}

/***将最高分存储于文件中***/
void File_in()
{
FILE *fp;
fp = fopen("save.txt","w+");           //以读写的方式建立一个名为save.txt的文件
fprintf(fp,"%d",score);               //把分数写进文件中
fclose(fp);                          //关闭文件
}

/****边框下面的分支选项****/
void choose()
{
int n;
gotoxy(25,23);
color(12);
printf("我要重新玩一局-------1");
gotoxy(52,23);
printf("不玩了,退出吧-------2");
gotoxy(46,25);
color(11);
printf("选择:");
scanf("%d",&n);
switch (n)
{
case 1:
        system("cls");            //清屏
        score=0;                  //分数归零
        sleeptime=200;            //设定初始速度
        add = 10;                  //使add设定为初值,吃一个食物得10分,然后累加
        printsnake();             //返回欢迎界面
        welcometogame();
        break;
case 2:
        exit(0);                  //退出游戏
        break;
default:                          //输入1和2以外的数字
        gotoxy(35,27);
        color(12);
        printf("※※您的输入有误,请重新输入※※");
        system("pause >nul");      //按任意键
        endgame();
        choose();                 //边框下面的分支选项
        break;
    }
}

/******游戏说明******/
void explation()
{
int i,j=1;
  system("cls");
  color(13);
  gotoxy(44,3);
  printf("游戏说明");
  color(2);
for (i = 6; i <= 22; i++)               //输出上下边框===
  {
    for (j = 20; j <= 75; j++)         //输出左右边框||
    {
      gotoxy(j,i);
      if(i==6 ||i==22) printf("=");
      else if (j == 20 || j== 75) printf("||");
    }
  }
color(3);
gotoxy(30,8);
printf("tip1:不能撞墙,不能咬到自己");
color(10);
gotoxy(30,11);
printf("tip2:用个.↓.<.→分别控制蛇的移动");
color(14);
gotoxy(30,14);
printf("tip3:F1为加速,F2 为减速");
color(11);
gotoxy(30,17);
printf("tip4:按空格键暂停游戏,再按空格键继续");
color(4);
gotoxy(30,20);
printf("tip5:Esc:退出游戏");
getch();                             //按任意键返回主界面
system("cls");
printsnake();
welcometogame();
}

/**主函数**/
int main()
{
system("mode con cols=100 lines=30");
printsnake();
welcometogame();
File_out();
keyboardControl();
endgame();
return 0;
}


程序可以运行没有报错,但是它在运行游戏内容时只会进行一步,然后就停止了,不会运行剩下的进程,如图

img

本人太笨了找不到问题在哪,求各位解惑!!

snakemove函数有问题

void snakemove()                         //蛇前进,上U,下D,左L,右R
{
    snake * nexthead;
    cantcrosswall();
    nexthead = (snake*)malloc(sizeof(snake));  //为下一步开辟空间
    if (status == U)
    {
        nexthead->x = head->x;                 //向上前进时,x坐标不变,y坐标-1
        nexthead->y = head->y - 1;
        nexthead->next = head;
        head = nexthead;
        q = head;                             //指针q指向蛇头

    //如果下一个位置上有食物,下一个位置的坐标和食物的坐标相同
        if (nexthead->x == food->x && nexthead->y == food->y)
        {
            while (q != NULL)
            {
                gotoxy(q->x, q->y);
                color(14);
                printf("●");                    //原来食物的位置,将食物★换成蛇●
                q = q->next;                       //指针q指向的蛇身的下一位,也执行循环里的操作
            }
            score = score + add;                   //吃了一个食物,在总分上加上食物的分
            speedup();
            createfood();                       //创建食物
        }
        else
        {
            while (q->next->next != NULL)      //如果没遇到食物
            {
                gotoxy(q->x, q->y);
                color(14);
                printf("●");                 //蛇正常往前走,输出当前位置的蛇身
                q = q->next;                    //继续输出整个蛇身
            }
            //经过上面的循环,q指向蛇尾,蛇尾的下一位,就是蛇走过去的位置
            gotoxy(q->next->x, q->next->y);
            color(3);
            printf("■");
            free(q->next);               //输出■之后,释放指向下一位的指针
            q->next = NULL;               //指针下一位指向空
        }
    }
    if (status == D)
    {
        nexthead->x = head->x;
        nexthead->y = head->y + 1;
        nexthead->next = head;
        head = nexthead;
        q = head;
        if (nexthead->x == food->x && nexthead->y == food->y)        //有食物
        {
            while (q != NULL)
            {
                gotoxy(q->x, q->y);                               //向下前进时,x坐标不变,y坐标+1
                color(14);
                printf("●");
                q = q->next;
            }
            score = score + add;                                   //得分
            speedup();                                         //加速
            createfood();                                      //继续生成食物
        }
        //食物变成蛇身上的一部分,即被蛇吃掉

        else                                                        //没有食物
        {
            while (q->next->next != NULL)
            {
                gotoxy(q->x, q->y);
                color(14);
                printf("●");
                q = q->next;
            }
            gotoxy(q->next->x, q->next->y);                         //蛇走过的路线变回棋盘原有的图案
            color(3);
            printf("■");
            free(q->next);                                        //释放指针
            q->next = NULL;
        }
    }
    if (status == L)
    {
        nexthead->x = head->x - 2;                                //向左前进时,x坐标向左移动-2,y坐标不变
        nexthead->y = head->y;
        nexthead->next = head;
        head = nexthead;
        q = head;
        if (nexthead->x == food->x && nexthead->y == food->y)     //有食物
        {
            while (q != NULL)
            {
                gotoxy(q->x, q->y);
                color(14);
                printf("●");
                q = q->next;
            }
            score = score + add;
            speedup();
            createfood();
        }
    }
    else                                                     //你这个else应该放错位置了
    {
        while (q->next->next != NULL)
        {
            gotoxy(q->x, q->y);
            color(14);
            printf("●");
            q = q->next;
        }
        gotoxy(q->next->x, q->next->y);
        color(3);
        printf("■");
        free(q->next);
        q->next = NULL;
    }
    if (status == R)
    {
        nexthead->x = head->x + 2;                                //向右前进时,x坐标向右移动+2,y坐标不变
        nexthead->y = head->y;
        nexthead->next = head;
        head = nexthead;
        q = head;
        if (nexthead->x == food->x && nexthead->y == food->y)     //有食物
        {
            while (q != NULL)
            {
                gotoxy(q->x, q->y);
                color(14);
                printf("●");
                q = q->next;
            }
            score = score + add;
            speedup();
            createfood();
        }
        else                                     //没有食物
        {
            while (q->next->next != NULL)
            {
                gotoxy(q->x, q->y);
                color(14);
                printf("●");
                q = q->next;
            }
            gotoxy(q->next->x, q->next->y);
            color(3);
            printf("■");
            free(q->next);
            q->next = NULL;
        }
    }
    if (biteself() == 1)                                     //判断是否咬到自己
    {
        endgamestatus = 2;
        endgame();
    }
}


这里是改完的状态,试玩了一下,能够玩到我被自己撞死(悲,操作太菜力)


void snakemove()                         //蛇前进,上U,下D,左L,右R
{
    snake * nexthead;
    cantcrosswall();
    nexthead = (snake*)malloc(sizeof(snake));  //为下一步开辟空间
    if (status == U)
    {
        nexthead->x = head->x;                 //向上前进时,x坐标不变,y坐标-1
        nexthead->y = head->y - 1;
        nexthead->next = head;
        head = nexthead;
        q = head;                             //指针q指向蛇头

    //如果下一个位置上有食物,下一个位置的坐标和食物的坐标相同
        if (nexthead->x == food->x && nexthead->y == food->y)
        {
            while (q != NULL)
            {
                gotoxy(q->x, q->y);
                color(14);
                printf("●");                    //原来食物的位置,将食物★换成蛇●
                q = q->next;                       //指针q指向的蛇身的下一位,也执行循环里的操作
            }
            score = score + add;                   //吃了一个食物,在总分上加上食物的分
            speedup();
            createfood();                       //创建食物
        }
        else
        {
            while (q->next->next != NULL)      //如果没遇到食物
            {
                gotoxy(q->x, q->y);
                color(14);
                printf("●");                 //蛇正常往前走,输出当前位置的蛇身
                q = q->next;                    //继续输出整个蛇身
            }
            //经过上面的循环,q指向蛇尾,蛇尾的下一位,就是蛇走过去的位置
            gotoxy(q->next->x, q->next->y);
            color(3);
            printf("■");
            free(q->next);               //输出■之后,释放指向下一位的指针
            q->next = NULL;               //指针下一位指向空
        }
    }
    if (status == D)
    {
        nexthead->x = head->x;
        nexthead->y = head->y + 1;
        nexthead->next = head;
        head = nexthead;
        q = head;
        if (nexthead->x == food->x && nexthead->y == food->y)        //有食物
        {
            while (q != NULL)
            {
                gotoxy(q->x, q->y);                               //向下前进时,x坐标不变,y坐标+1
                color(14);
                printf("●");
                q = q->next;
            }
            score = score + add;                                   //得分
            speedup();                                         //加速
            createfood();                                      //继续生成食物
        }
        //食物变成蛇身上的一部分,即被蛇吃掉

        else                                                        //没有食物
        {
            while (q->next->next != NULL)
            {
                gotoxy(q->x, q->y);
                color(14);
                printf("●");
                q = q->next;
            }
            gotoxy(q->next->x, q->next->y);                         //蛇走过的路线变回棋盘原有的图案
            color(3);
            printf("■");
            free(q->next);                                        //释放指针
            q->next = NULL;
        }
    }
    if (status == L)
    {
        nexthead->x = head->x - 2;                                //向左前进时,x坐标向左移动-2,y坐标不变
        nexthead->y = head->y;
        nexthead->next = head;
        head = nexthead;
        q = head;
        if (nexthead->x == food->x && nexthead->y == food->y)     //有食物
        {
            while (q != NULL)
            {
                gotoxy(q->x, q->y);
                color(14);
                printf("●");
                q = q->next;
            }
            score = score + add;
            speedup();
            createfood();
        }
        else                                                     //没有食物
        {
            while (q->next->next != NULL)
            {
                gotoxy(q->x, q->y);
                color(14);
                printf("●");
                q = q->next;
            }
            gotoxy(q->next->x, q->next->y);
            color(3);
            printf("■");
            free(q->next);
            q->next = NULL;
        }
    }
    if (status == R)
    {
        nexthead->x = head->x + 2;                                //向右前进时,x坐标向右移动+2,y坐标不变
        nexthead->y = head->y;
        nexthead->next = head;
        head = nexthead;
        q = head;
        if (nexthead->x == food->x && nexthead->y == food->y)     //有食物
        {
            while (q != NULL)
            {
                gotoxy(q->x, q->y);
                color(14);
                printf("●");
                q = q->next;
            }
            score = score + add;
            speedup();
            createfood();
        }
        else                                     //没有食物
        {
            while (q->next->next != NULL)
            {
                gotoxy(q->x, q->y);
                color(14);
                printf("●");
                q = q->next;
            }
            gotoxy(q->next->x, q->next->y);
            color(3);
            printf("■");
            free(q->next);
            q->next = NULL;
        }
    }
    if (biteself() == 1)                                     //判断是否咬到自己
    {
        endgamestatus = 2;
        endgame();
    }
}

c++完整贪吃蛇

#include<stdlib.h>
#include<stdio.h>
#include<windows.h>
#include<iostream>
#include<conio.h>
#define random(x) (rand()%x)
using namespace std;

int **map;
char c = 0;
int sign = 0;

char check_snake(char c);

struct snake{    
    int i;
    int j;
    struct snake *next;
    };

struct snake *generateSnake(){
    struct snake *s;
    s = (struct snake*)malloc(sizeof(struct snake));
    struct snake *p = s;
    int x[6] = {2, 3, 4, 5, 5, 5};
    int y[6] = {2, 2, 2, 2, 3, 4};
    for(int i = 0; i < 6; i++){
        struct snake *node; //节点
        node = (struct snake*)malloc(sizeof(struct snake));
        p->next = node;        
        p = p->next;
        p->i = x[i];
        p->j = y[i];
    }
    p->next = NULL;
    return s;
}  // 设置蛇的长度和初始位置

void gotoxy(int x, int y)
{
    COORD Position;
    Position.X = x;
    Position.Y = y;
    //调用API改变字体位置
    SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), Position);
}

// 绘制地图
void draw_map(int **map, int height, int weight){

    for(int i = 0; i < height ; ++i){
        for(int j = 0; j < weight ; ++j){
            if(i == 0  || i == height - 1  ){  // 表示在第一层和最后一层  
                map[i][j] = 1;  // 四边形的四边作为墙,强我们用1表示,表示位置已占
            }
            else if ( j == 0 ||  j == weight - 1 ){ // 表示在最左层和最右层
                map[i][j] = 1;
            }
            else{
                map[i][j] = 0 ; // 除墙以外其他位置为0 表示该位置为空
            }
        }
        cout << "\n";
    }
    return;
}
// 图形形状
void draw(int **map,int *star, int height, int weight){
    system("cls");//清空屏幕
    gotoxy(0, 0);
    for(int i = 0; i < height; ++i){
        for(int j = 0; j < weight; ++j){
            if(map[i][j] == 1){
             cout << "■";
            }
            else if (map[i][j] == 2)
            {
                cout << "●";
            }
            else if ( i == star[0] && j == star[1])
            {
                cout << "★";
            }
            else{
             cout << "□";
            }
        }
        cout << '\n';
    }
    return;
}

// 蛇
void drawSnake(int **map, struct snake *s){
    struct snake *p = s->next;
    map[p->i][p->j] = 2;    // 蛇头
    p = p->next;
    while(p){
        map[p->i][p->j] = 1;
        p = p->next;
    }
    return;
}


void draw_star(int **map,int *star, int height, int weight){
    int sum = 0; // 空格子的个数
    int index = 0; // 剩下的格子

    // 算出空格子的个数
    for(int i = 0; i < height ; ++i){
        for(int j = 0; j < weight; ++j){
            if(map[i][j] == 0)
            {
                sum += 1;
            }
        }
    }
    index = random(sum) + 1; // 在1到sum 中随机的位置生成星星
    //生成星星
    for(int i = 0; i < height; ++i){
        for(int j = 0; j < weight; ++j){
            if(map[i][j] == 0){
                index -= 1;
            }
            if(index == 0){
                star[0] = i;
                star[1] = j;
                return ;
            }
        }
    }
    return;
}

void update_snake(char c,struct snake *s,int *star){
    snake *newsnake;
    newsnake = (snake*)malloc(sizeof(snake));
    if(c == 'w'){
        // 相当于在s 头插一个新节点
        newsnake->i = s->next->i - 1;
        newsnake->j = s->next->j; 

        if(map[newsnake->i][newsnake->j] == 1){
            // 头插的节点的位置 原本 map[i][j] == 1 表示该位置是墙或者是蛇身了
             sign = 3;  
        }
        else if(newsnake->i == star[0] && newsnake->j == star[1]){
            newsnake->next = s->next; 
            s->next = newsnake; 
            struct  snake *q = s; 
                while(q->next->next != NULL){
                    gotoxy(q->i, q->j);
                    printf("■");  // 恢复蛇身
                    q = q->next;
                }
            sign = 2;
        }
        else{
            newsnake->next = s->next; 
            s->next = newsnake; 
            struct  snake *q = s;   
            while(q->next->next != NULL){
                gotoxy(q->i, q->j);
                printf("■"); 
                q = q->next;
            }
            gotoxy(q->i, q->j);
            printf("■");
            map[q->next->i][q->next->j] = 0; 
            free(q->next);        
            q->next = NULL;
        }
    }
    else if( c == 's'){
        newsnake->i = s->next->i + 1;
        newsnake->j = s->next->j;
        if(map[newsnake->i][newsnake->j] == 1){
            sign = 3;  
        }
        if(newsnake->i == star[0] && newsnake->j == star[1]){
            newsnake->next = s->next; 
            s->next = newsnake;
            struct  snake *q = s; 
            while(q->next->next != NULL){
                gotoxy(q->i, q->j);
                printf("■"); 
                q = q->next;
            }
            sign = 2;
        }
        else{
            newsnake->next = s->next; 
            s->next = newsnake; 
            struct  snake *q = s;   
            while(q->next->next != NULL){
                gotoxy(q->i, q->j);
                printf("■"); 
                q = q->next;
            }
            gotoxy(q->i, q->j);
            printf("■");
            map[q->next->i][q->next->j] = 0; 
            free(q->next);        
            q->next = NULL;
        }
    }
    else if( c == 'a'){
        newsnake->i = s->next->i;
        newsnake->j = s->next->j - 1;
        if(map[newsnake->i][newsnake->j] == 1){
            sign = 3;  
        }        
        if(newsnake->i == star[0] && newsnake->j == star[1]){
            newsnake->next = s->next; 
            s->next = newsnake; 
            struct  snake *q = s;
            while(q->next->next != NULL){
                gotoxy(q->i, q->j);
                printf("■"); 
                q = q->next;
            }
            sign = 2;
        }
        else{
            newsnake->next = s->next; 
            s->next = newsnake; 
            struct  snake *q = s;   
            while(q->next->next != NULL){
                gotoxy(q->i, q->j);
                printf("■"); 
                q = q->next;
            }
            gotoxy(q->i, q->j);
            printf("■");
            map[q->next->i][q->next->j] = 0;
            free(q->next);         
            q->next = NULL;
        } 
    }       
    else{
        newsnake->i = s->next->i;
        newsnake->j = s->next->j + 1;
        if(map[newsnake->i][newsnake->j] == 1){
            sign = 3; 
        }        
        if(newsnake->i == star[0] && newsnake->j == star[1]){
            newsnake->next = s->next; 
            s->next = newsnake;
            struct  snake *q = s;
            while(q->next->next != NULL){
                gotoxy(q->i, q->j);
                printf("■"); 
                q = q->next;
            }
            sign = 2;
        }
        else{
            newsnake->next = s->next; 
            s->next = newsnake; 
            struct  snake *q = s;   
            while(q->next->next != NULL){
                gotoxy(q->i, q->j);
                printf("■"); 
                q = q->next;
            }
            gotoxy(q->i, q->j);
            printf("■");
            map[q->next->i][q->next->j] = 0; 
            free(q->next);           
            q->next = NULL;
        }  
    }            
}

// 蛇 移动方向
// 上 119 wd
// 下 115 s
// 左 97  a
// 右 100 d
void action_snake(struct snake *s,int *star){
        switch(c)
        {
            //向上
            case 'w':
            update_snake(c, s,star);
            break;
            //向下
            case 's':
            update_snake(c, s,star);
            break;
            //向左
            case 'a':
            update_snake(c, s,star);
            break;
            //向右
            case 'd':
            update_snake(c, s,star);
            break;
        }
}

void check_snake(){
    DWORD time = 500; // 1表示一毫秒 1000表示一秒  要改变速度可以修改time的时间
    DWORD time_start = GetTickCount();  // 获取当前时间
    char t;
    while(true){
        if(_kbhit()){
            char ch = _getch(); // 当前键位
            if(ch == 97 || ch == 100 || ch == 115 || ch == 119){
                t = ch;  
                if( t == 97 && c == 'd')
                {
                    c = 'd';
                }
                else if( t == 100 && c =='a'){
                    c ='a';
                }
                else if(t == 115 && c == 'w'){
                    c = 'w';
                }
                else if(t == 119 && c == 's'){
                    c = 's';
                }
                else{
                    c = ch;
                }
            }
        }
        DWORD time_end = GetTickCount(); // 获取键位后的时间
        if(time_end - time_start > time){
            time_start = time_end; 
            break;
        }
    }
    return;
}

int main(){
    int height = 20; // 地图高度  map.height = 20
    int weight = 20; // 地图宽度  map.weight = 20

    struct snake *s = generateSnake();
    map = (int **) malloc(sizeof(int*)*height);
    for(int i = 0; i < height; ++i){
        map[i] = (int *) malloc(sizeof(int)*weight);
    }    
    draw_map(map,height,weight);
    drawSnake(map,s);
    int star[2] = {0,0};
    draw_star(map,star,height,weight);
    draw(map,star,height,weight);
    while(1){
        if( sign == 3){
            break;
        }
        check_snake();
        action_snake(s,star);

        draw_map(map,height,weight);
        drawSnake(map,s);
        if(sign == 2){
            draw_star(map,star,height,weight);
            sign = 0;
        }
        draw(map,star,height,weight);
        gotoxy(0, 0);
    }

    system("cls");
    gotoxy(height/2,weight/2);
    cout << "游戏结束 " ;
    system("pause");

    return 0;
}