C语言简单实现贪吃蛇小程序

简介


在这里插入图片描述

一、学习交流

这个代码当时使用DevC++编写,后用vs也能编译通过,如果想先赋值代码,请直接点目录的完整代码 ,然后复制到自己的电脑上。
这个程序时我上高中时写出来的,现在已经大一了。回过头来再看这个程序,发现好多地方都可以改进,代码太过啰嗦,效率不是很高。代码仅供学习交流

二、适合刚学C语言的朋友

因为当时没有学习太多的数据结构和算法,数据都是用线性结构存储(数组),只要你会数组结构体函数,这个代码对你来说就没问题,因为当时我就学到了数组,所以这个适合刚学c的初学者

三、游戏设计思路

计算机与人交互的三个步骤:输入、计算机处理输入数据、输出。
所以游戏也是基于这个思想来实现人和游戏的互动的。
实现游戏互动,有种叫做MVC的思维模式,主要分为四部分:
User(用户):游戏玩家;
Controller(控制器):处理游戏交互;
Model(模型):游戏功能的实现;
View(视图):设计图形界面,给玩家呈现游戏场景;
首先,由 User(用户) 输入数据,然后由 Controller(控制器) 接受并处理,然后转发给 Model(模型) 进行处理与运算,最后由 View(视图) 把成果呈现在屏幕上。
我这个小程序就是:
输入 -> 处理输入数据 -> 处理数据 -> 更新屏幕显示
这个小程序并没有严格按照 MVC的思维模式 ,因为当时思维没有这么清晰。不过这个模式是非常重要的,它很好的描述出了游戏交互的主要步骤,我们在代码实现时,尽量按照这个模式来,这样会使你的代码可读性高,整体结构好。

代码核心

主要有两个:

一、数据的存储和表示(Data):

这里有一些定义的常量,目前不需要知道它们的具体用途,主体代码明白后,这些常量的用途也自然明白了,先把它们放这:

//游戏信息
#define GAMENAME "快乐贪吃蛇"
#define DEVLOPER "这里填作者信息"
#define QQ "这里填作者QQ号"
#define TEL "电话号码:10086"
#define WRITEDATE "最后一次编写日期:2019年7月19号"
//活动空间大小
#define I 20
#define J 40 //J>=length
//菜单框大小
#define MI 15
#define MJ 50
//方向常量
#define Key_Up 72
#define Key_Down 80
#define Key_Right 77
#define Key_Left 75
#define UP 'W'
#define DOWN 'S'
#define LEFT 'A'
#define RIGHT 'D'
//颜色常量
#define FONTCOLOR 0x0E  //字体颜色
#define SPACECOLOR 0x80 //空区域颜色
#define WALLCOLOR 0xC0  //墙颜色
#define DATACOLOR 0x8B  //控制数据颜色
#define SNAKECOLOR 0x8B //蛇颜色
//游戏初始数据
#define LEN 4 //LEN>=3 and LEN<=J/2
#define DIRECTION LEFT//最开始时,蛇的前进方向
#define WAITTIME 10//蛇的速度,越小越快

下面是数据的存储方式:

struct Position
{
  uint_fast8_t i, j;
};
//全局变量区
struct Position S[I * J] = {0}, FOOD;     //蛇座标,食物坐标
uint_fast8_t M[I + 2][J + 2];             //操作数据
uint_fast8_t length, waittime, foodcolor; //长度,输入等待时间,食物颜色
char direction;                           //方向
bool alive;                               //存活状态
char playerName[21];                      //玩家名字

这里用一个Position结构体表示点的坐标,因为我们一个地图是一个直角坐标系。
我编写gotoxy函数用来定位坐标轴上面的点,并根据flag参数更改坐标数据:

void gotoxy(uint_fast8_t i, uint_fast8_t j, char c, uint_fast8_t flag); 
//移动光标并更改控制数据

这里的uint_fast8_t表示的是无符号8位整型,你可以理解为int,只不过它的数据范围是0~255,在这个程序中坐标不会超过255(不然地图太大了)。
我用数组M存地图上的数据,其中:
4表示食物,屏幕上面用 ‘*’ 打印;
3表示头部,屏幕上面用 ‘@’ 打印;
所有表示如下代码所示:

#define GF(i, j) gotoxy(UPFRAME + i, LEFTFRAME + j, '*', 4) //食物
#define GH(i, j) gotoxy(UPFRAME + i, LEFTFRAME + j, '@', 3) //头
#define GN(i, j) gotoxy(UPFRAME + i, LEFTFRAME + j, 'o', 2) //颈
#define GB(i, j) gotoxy(UPFRAME + i, LEFTFRAME + j, 'o', 1) //身
#define GT(i, j) gotoxy(UPFRAME + i, LEFTFRAME + j, '+', 1) //尾
#define GW(i, j) gotoxy(UPFRAME + i, LEFTFRAME + j, ' ', 1) //墙
#define GS(i, j) gotoxy(UPFRAME + i, LEFTFRAME + j, ' ', 0) //空

游戏使用这个函数初始化数据:

void get_really(void);                      //游戏数据初始化

二、游戏场景(Scene):

小程序比较简单:只有两个场景:菜单场景游戏场景
菜单场景主要由下路函数实现:

void welcome(void);                         //游戏开始界面
void title(uint_fast8_t i, uint_fast8_t j); //打印标题
void menu(void);                            //打印菜单
void rule_of_game(void);                    //游戏介绍
void devloper(void);                        //开发者信息
void aboutgame(void);                       //关于游戏
void choice(void);                          //选择菜单选项

游戏场景主要由下列函数组成:

void game(void);              //游戏开始
void draw_map(void);          //绘制地图
void put_control_data(void);  //打印控制数据
void put_game_data(void);     //打印游戏数据
void press(void);             //玩家输入函数,用来接收玩家的输入指令
void count_nexthead(void);    //计算移动一次后,蛇头的位置
bool countstate(void);        //判定移动一次后,游戏处于什么状态(暂定、变长、死亡等等)
void renew_food(void);        //重新生成食物
void renew_S(void);           //更新蛇的坐标
bool death(void);             //死亡时调用
void move_control_data(void); //刷新屏幕上面的控制数据
void move(void);              //刷新屏幕上面蛇的位置
char select(void);            //游戏结束时调用,选择
void game_over(void);         //游戏结束

完整代码

下面整个小程序的C语言代码,当时使用DevC++编写,后用vs也能编译通过。

#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>
#include <conio.h>
#include <windows.h>
#include <time.h>
#include <string.h>
#include <ctype.h>
#include <inttypes.h>
//游戏信息
#define GAMENAME "快乐贪吃蛇"
#define DEVLOPER ""
#define QQ ""
#define TEL "电话号码:10086"
#define WRITEDATE "最后一次编写日期:2019年7月19号"
//活动空间大小
#define I 20
#define J 40 //J>=length
//菜单框大小
#define MI 15
#define MJ 50
//方向常量
#define Key_Up 72
#define Key_Down 80
#define Key_Right 77
#define Key_Left 75
#define UP 'W'
#define DOWN 'S'
#define LEFT 'A'
#define RIGHT 'D'
//颜色常量
#define FONTCOLOR 0x0E  //字体颜色
#define SPACECOLOR 0x80 //空区域颜色
#define WALLCOLOR 0xC0  //墙颜色
#define DATACOLOR 0x8B  //控制数据颜色
#define SNAKECOLOR 0x8B //蛇颜色
//游戏初始数据
#define LEN 4 //LEN>=3 and LEN<=J/2
#define DIRECTION LEFT//最开始时,蛇的前进方向
#define WAITTIME 10//蛇的速度,越小越快
//快捷使用蛇坐标
#define NEXTHEAD S[length]
#define HEAD S[length - 1]
#define NECK S[length - 2]
#define BODY S[length - 3]
#define TAIL S[0]
//界限坐标常量
#define UPFRAME 10                                      //地图上边界线 (横坐标)
#define DOWNFRAME (UPFRAME + I + 2) + 1                 //地图下边界线 (横坐标)
#define LEFTFRAME 10                                    //地图左边界线(纵坐标)
#define RIGHTFRAME (LEFTFRAME + J + 2) + 3              //地图右边界线(纵坐标)
#define TITLE(x) LEFTFRAME + (x - strlen(GAMENAME)) / 2 //标题(横坐标)
//移动光标
#define GO(i, j) gotoxy(i, j, ' ', -1)                         //无特殊定位,原始数据移动光标
#define GU(i, j) gotoxy(i, LEFTFRAME + j, ' ', -1)             //上框初始坐标
#define GD(i, j) gotoxy(DOWNFRAME + i, LEFTFRAME + j, ' ', -1) //下框初始坐标
#define GL(i, j) gotoxy(UPFRAME + i, j, ' ', -1)               //左框初始坐标
#define GR(i, j) gotoxy(UPFRAME + i, RIGHTFRAME + j, ' ', -1)  //右框初始坐标
#define GM(i, j) gotoxy(UPFRAME + i, LEFTFRAME + j, ' ', -1)   //中框初始坐标
//移动光标并打印
#define GF(i, j) gotoxy(UPFRAME + i, LEFTFRAME + j, '*', 4) //食物
#define GH(i, j) gotoxy(UPFRAME + i, LEFTFRAME + j, '@', 3) //头
#define GN(i, j) gotoxy(UPFRAME + i, LEFTFRAME + j, 'o', 2) //颈
#define GB(i, j) gotoxy(UPFRAME + i, LEFTFRAME + j, 'o', 1) //身
#define GT(i, j) gotoxy(UPFRAME + i, LEFTFRAME + j, '+', 1) //尾
#define GW(i, j) gotoxy(UPFRAME + i, LEFTFRAME + j, ' ', 1) //墙
#define GS(i, j) gotoxy(UPFRAME + i, LEFTFRAME + j, ' ', 0) //空
//快捷使用函数
#define PRIN(x) printf("%d", x)                                              //输出数值
#define COLOR(x) SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), x) //改色
//
struct Position
{
  uint_fast8_t i, j;
};
//全局变量区
struct Position S[I * J] = {0}, FOOD;     //蛇座标,食物坐标
uint_fast8_t M[I + 2][J + 2];             //操作数据
uint_fast8_t length, waittime, foodcolor; //长度,输入等待时间,食物颜色
char direction;                           //方向
bool alive;                               //存活状态
char playerName[21];                      //玩家名字

//函数声明区
void gotoxy(uint_fast8_t i, uint_fast8_t j, char c, uint_fast8_t flag); //移动光标并更改控制数据
void colorfulfont(char *font);                                          //打印花里胡哨的彩色字体
//
void get_really(void);                      //游戏数据初始化
void welcome(void);                         //游戏开始界面
void title(uint_fast8_t i, uint_fast8_t j); //打印标题
void menu(void);                            //打印菜单
void rule_of_game(void);                    //游戏介绍
void devloper(void);                        //开发者信息
void aboutgame(void);                       //关于游戏
void choice(void);                          //选择菜单选项
//
void game(void);              //游戏开始
void draw_map(void);          //绘制地图
void put_control_data(void);  //打印控制数据
void put_game_data(void);     //打印游戏数据
void press(void);             //玩家输入函数,用来接收玩家的输入指令
void count_nexthead(void);    //计算移动一次后,蛇头的位置
bool countstate(void);        //判定移动一次后,游戏处于什么状态(暂定、变长、死亡等等)
void renew_food(void);        //重新生成食物
void renew_S(void);           //更新蛇的坐标
bool death(void);             //死亡时调用
void move_control_data(void); //刷新屏幕上面的控制数据
void move(void);              //刷新屏幕上面蛇的位置
char select(void);            //游戏结束时调用,选择
void game_over(void);         //游戏结束
//程序入口
int main(void)
{
  FILE *fp_score = fopen("score.txt", "ab+"); //打开分数文件
  FILE *fp_temp = fopen("temp", "w+");        //新建一个临时文件
  char gameTime[50];                          //用来存放时间字符串
  if (fp_score == NULL)
  {
    printf("打开分数记录文件失败!!!");
    getch();
    exit(1);
  }
start:
  welcome();
game:
  get_really();
  game();
  game_over();
  //结算游戏数据
  time_t rawtime;
  struct tm *timeinfo;
  time(&rawtime);
  timeinfo = localtime(&rawtime);
  //通过文件进行类型转换
  fprintf(fp_temp, "%d年%d月%d号 %d:%d分%d秒", //将时间存到临时文件
          1900 + timeinfo->tm_year, 1 + timeinfo->tm_mon, timeinfo->tm_mday, timeinfo->tm_hour, timeinfo->tm_min, timeinfo->tm_sec);
  rewind(fp_temp);
  fgets(gameTime, 30, fp_temp); //从临时文件读取时间
  rewind(fp_temp);
  fprintf(fp_score, "| %-30s| %-50s| %-10d\n", playerName, gameTime, length - 4); //将结算数据保存
  //
  switch (select()) //游戏结束,判断用户的选择
  {
  case '1':
    goto start;
    break;
  case '2':
    goto game;
    break;
  default:
    break;
  }
  //显示历史分数
  system("cls");
  int size = ftell(fp_score);
  rewind(fp_score);
  char *data = (char *)malloc(size + 1);
  fread(data, size, 1, fp_score);
  data[size] = 0;
  puts(data);
  fclose(fp_score);
  fclose(fp_temp);
  remove("temp");
  getch();
  return 0;
}
void gotoxy(uint_fast8_t i, uint_fast8_t j, char c, uint_fast8_t flag)
{
  COORD position = {j, i};
  SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), position); //移动光标
  CONSOLE_CURSOR_INFO cursor_info = {1, 0};
  SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &cursor_info); //隐藏光标
  if (flag == 0 || flag == 1 || flag == 2 || flag == 3 || flag == 4)
    M[i - UPFRAME][j - LEFTFRAME] = flag, printf("%c", c); //改写
}
void colorfulfont(const char *font)
{
  uint_fast8_t i;
  for (i = rand() % 6 + 0x0A; *font; font++, i++)
  {
    if (i == 0x10)
      i = rand() % 6 + 0x0A;
    COLOR(i);
    putchar(*font);
  }
}
void get_really(void)
{
  uint_fast8_t i;
  length = LEN; //蛇的初始长度
  for (i = 0; i < length; i++)
  {
    S[i].i = I / 2;
    S[i].j = J / 2 + (length - 1 - i); //一条蛇的初始坐标
  }
  alive = true;          //活着
  direction = DIRECTION; //初始方向
}
void welcome(void)
{
  system("mode con cols=120 lines=45");
  srand((unsigned)time(NULL));
  COLOR(0x00);
  system("cls");
  title(UPFRAME * 0.8, TITLE(49));
  menu();
  choice();
}
void game(void)
{
  COLOR(0x0F);
  system("cls");
  GO(0, 0);
  puts("请输入你的名字(最多20个字符,汉字算两个):");
  gets(playerName);
  system("cls");
  title(UPFRAME * 0.8, TITLE(J + 2));
  draw_map();
  renew_food();
  put_control_data();
  put_game_data();
  Sleep(2000);
  while (alive)
  {
    press();              //输入
    count_nexthead();     //计算下一步蛇头的位置
    alive = countstate(); //刷新存活状态
    move();
    move_control_data();
    put_game_data();
  }
}
char select(void)
{
  char choice;
  GD(6, 10);
  COLOR(0x0A);
  printf("游戏结束,请键入选择【 】");
  GD(7, 1);
  printf("1.返回主菜单     2.重新开始     3.退出游戏");
  GD(6, 32);
  for (choice = getche(); choice != '1' && choice != '2' && choice != '3'; choice = getche())
    GD(6, 32);
  return choice;
}
void game_over(void)
{
  uint_fast8_t i;
  COLOR(SNAKECOLOR);
  for (i = 0; i < 5; i++)
  {
    Sleep(200);
    GM(HEAD.i, HEAD.j);
    putchar('x');
    Sleep(200);
    GM(HEAD.i, HEAD.j);
    putchar('@');
  }
  GM(HEAD.i, HEAD.j);
  putchar('x');
  uint_fast16_t a;
}
void title(uint_fast8_t i, uint_fast8_t j)
{
  GO(i, j);
  colorfulfont(GAMENAME);
}
void menu(void)
{
  uint_fast8_t i;
  COLOR(WALLCOLOR);
  for (i = 0; i < MI; i++)
    GW(i, 0), GW(i, MJ - 1);
  for (i = 1; i < MJ - 1; i++)
    GW(0, i), GW(MI - 1, i);
  COLOR(FONTCOLOR);
  GM(3, MJ / 6);
  colorfulfont("1.开始游戏");
  GM(9, MJ / 6);
  colorfulfont("2.游戏规则");
  GM(3, MJ / 2);
  colorfulfont("3.作者信息");
  GM(9, MJ / 2);
  colorfulfont("4.关于游戏");
}
void rule_of_game(void)
{
  uint_fast8_t i, j;
  COLOR(0x00);
  for (i = 0; i < 10; i++)
  {
    for (j = MJ; j < MJ + 60; j++)
    {
      GM(i, j);
      putchar(' ');
    }
  }
  COLOR(0x0A);
  GM(0, MJ + 20);
  printf("游戏规则");
  GM(2, MJ + 6);
  colorfulfont("操作一:控制方向-----\"W\"、\"S\"、\"A\"、\"D\"");
  GM(3, MJ + 14);
  colorfulfont("分别对应上下左右(大小写皆可)");
  GM(4, MJ + 14);
  colorfulfont("也可使用键盘的上下左右键");
  GM(6, MJ + 6);
  colorfulfont("操作二:暂停游戏。往反方向走可以暂停游戏");
  GM(8, MJ + 13);
  colorfulfont("(比如你正在向左走,按一下右键即可暂停游戏)");
  GM(10, MJ + 6);
  colorfulfont("规则三:撞墙和吃到自己都会死");
}
void devloper(void)
{
  uint_fast8_t i, j;
  COLOR(0x00);
  for (i = 0; i < 10; i++)
  {
    for (j = MJ; j < MJ + 60; j++)
    {
      GM(i, j);
      putchar(' ');
    }
  }
  COLOR(0x0A);
  GM(0, MJ + 20);
  printf("作者介绍");
  GM(2, MJ + 10);
  colorfulfont(DEVLOPER);
  GM(4, MJ + 10);
  colorfulfont(QQ);
  GM(6, MJ + 10);
  colorfulfont(TEL);
}
void aboutgame(void)
{
  uint_fast8_t i, j;
  COLOR(0x00);
  for (i = 0; i < 10; i++)
  {
    for (j = MJ; j < MJ + 60; j++)
    {
      GM(i, j);
      putchar(' ');
    }
  }
  COLOR(0x0A);
  GM(0, MJ + 15);
  printf("关于游戏");
  GM(2, MJ + 6);
  colorfulfont(WRITEDATE);
}
void choice(void)
{
  COLOR(0x0A);
  char chance;
  const char *notice = "请键入选择【 】";
  GM(MI + 3, MJ / 6);
  colorfulfont(notice);
  GM(MI + 3, MJ / 6 + strlen(notice) - 3);
  chance = getche();
  while (chance != '1')
  {
    if (chance == '2')
      rule_of_game();
    else if (chance == '3')
      devloper();
    else if (chance == '4')
      aboutgame();
    //
    GM(MI + 3, MJ / 6 + strlen(notice) - 3);
    chance = getche();
  }
}
void draw_map(void)
{
  uint_fast8_t i, j;
  //
  COLOR(WALLCOLOR);
  for (i = 1; i < I + 2; i++)
    GW(i, 0), GW(i, J + 1);
  for (j = 0; j < J + 2; j++)
    GW(0, j), GW(I + 1, j); //打印墙
  //
  COLOR(SPACECOLOR);
  for (i = 1; i <= I; i++)
    for (j = 1; j <= J; j++)
      GS(i, j); //打印活动空间
  //
  COLOR(SNAKECOLOR);
  GH(HEAD.i, HEAD.j); //打印蛇头
  GN(NECK.i, NECK.j); //打印蛇颈
  for (j = BODY.j; j < TAIL.j; j++)
    GB(BODY.i, j);    //打印蛇身
  GT(TAIL.i, TAIL.j); //打印蛇尾
}
void put_control_data(void)
{
  uint_fast8_t i, j;
  const char *notice = "控制数据";
  GO(UPFRAME * 0.8, RIGHTFRAME + (J + 2 - strlen(notice)) / 2);
  colorfulfont(notice);
  COLOR(DATACOLOR);
  for (i = 0; i < I + 2; i++)
  {
    GR(i, 0);
    for (j = 0; j < J + 2; j++)
      PRIN(M[i][j]);
  }
}
void put_game_data(void)
{
  COLOR(FONTCOLOR);
  GD(0, 0);
  printf("Food:(%3d,%3d)", FOOD.i, FOOD.j);
  GD(1, 0);
  printf("Head:(%3d,%3d)", HEAD.i, HEAD.j);
  GD(2, 0);
  printf("Neck:(%3d,%3d)", NECK.i, NECK.j);
  GD(3, 0);
  printf("Tail:(%3d,%3d)", TAIL.i, TAIL.j);
  GD(4, 0);
  printf("Length:%3d", length);
}
void press(void)
{
  char key;
  for (waittime = WAITTIME; waittime && !kbhit(); waittime--)
  {
    GD(1, (J + 2) / 2);
    COLOR(FONTCOLOR);
    printf("等待时间:%3d", waittime);
    Sleep(1);
  }
  if (waittime)
  {
    key = getch();
    if (key == -32) //方向键转换
    {
      key = getch();
      switch (key)
      {
      case Key_Up:
        key = UP;
        break;
      case Key_Down:
        key = DOWN;
        break;
      case Key_Right:
        key = RIGHT;
        break;
      case Key_Left:
        key = LEFT;
        break;
      }
    }
    strupr(&key); //把输入的字母同意转换成大写
    if (key == UP || key == DOWN || key == LEFT || key == RIGHT)
      direction = key;
  }
  GD(2, (J + 2) / 2);
  COLOR(FONTCOLOR);
  printf("方向:%c", direction);
}
void count_nexthead(void)
{
  NEXTHEAD = HEAD;
  switch (direction)
  {
  case UP:
    NEXTHEAD.i--;
    break;
  case DOWN:
    NEXTHEAD.i++;
    break;
  case LEFT:
    NEXTHEAD.j--;
    break;
  case RIGHT:
    NEXTHEAD.j++;
    break;
  }
}
bool countstate(void)
{
  switch (M[NEXTHEAD.i][NEXTHEAD.j])
  {
  case 1: //撞墙
  {
    //清除尾巴的控制数据
    COLOR(DATACOLOR);
    GR(TAIL.i, TAIL.j);
    PRIN(0);
    //清除蛇尾
    COLOR(SPACECOLOR);
    GS(TAIL.i, TAIL.j);
    //
    renew_S();
    return false;
  }
  case 2: //回头
  {
    GD(0, (J + 2) / 2);
    COLOR(FONTCOLOR);
    printf("暂停中");
    break;
  }
  case 4: //吃到食物
  {
    GD(0, (J + 2) / 2);
    COLOR(FONTCOLOR);
    printf("奔跑中");
    length++;
    renew_food();
    break;
  }
  default: //正常前进
  {
    GD(0, (J + 2) / 2);
    COLOR(FONTCOLOR);
    printf("奔跑中");
    //清除控制数据
    COLOR(DATACOLOR);
    GR(TAIL.i, TAIL.j);
    PRIN(0);
    //清除蛇尾
    COLOR(SPACECOLOR);
    GS(TAIL.i, TAIL.j);
    //
    renew_S();
    break;
  }
  }
  return true;
}
void renew_food(void)
{
  FOOD.i = rand() % I + 1;
  FOOD.j = rand() % I + 1;
  while (M[FOOD.i][FOOD.j])
  {
    FOOD.i = rand() % I + 1;
    FOOD.j = rand() % I + 1;
  }
  foodcolor = rand() % 6 + 0x8A;
  COLOR(foodcolor);
  GF(FOOD.i, FOOD.j);
}

void renew_S(void)
{
  uint_fast8_t i;
  for (i = 1; i <= length; i++)
    S[i - 1] = S[i];
}
bool death(void)
{
  bool die = 0;
  if (M[HEAD.i][HEAD.j] == 1)
    die = 1;
  return die;
}
void move_control_data(void)
{
  COLOR(DATACOLOR);
  GR(HEAD.i, HEAD.j);
  PRIN(M[HEAD.i][HEAD.j]);
  GR(NECK.i, NECK.j);
  PRIN(M[NECK.i][NECK.j]);
  GR(BODY.i, BODY.j);
  PRIN(M[BODY.i][BODY.j]);
  GR(TAIL.i, TAIL.j);
  PRIN(M[TAIL.i][TAIL.j]);
}
void move(void)
{
  COLOR(SNAKECOLOR);
  GH(HEAD.i, HEAD.j);
  GN(NECK.i, NECK.j);
  GB(BODY.i, BODY.j);
  GT(TAIL.i, TAIL.j);
}

看以后能不能再重新优化或者重新写一个,欢迎各位一起交流,一起进步!

  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值