博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
C语言 —— 贪吃蛇
阅读量:5278 次
发布时间:2019-06-14

本文共 8692 字,大约阅读时间需要 28 分钟。

参考视频:https://www.bilibili.com/video/av29580072/?p=1

 

GreedySnake.h

1 #ifndef GREEDYSNAKE_H_INCLUDED 2 #define GREEDYSNAKE_H_INCLUDED 3  4  5 #define SNAKE_LENGTH 20   //蛇的长度最大为20 6 #define true  1 7 #define false 0 8 enum {UP = -1, DOWN = 1, LEFT = -2, RIGHT = 2}; 9 10 typedef int bool;11 12 void FirstPage();                   //设置起始游戏界面13 void TestSpace();                   //按空格开始游戏14 void ShowBackground();              //展示游戏背景15 void SetSnakeRandPos();             //为蛇产生一个随机的位置16 void DrawSnake();                   //画蛇17 void SnakeMove();                   //蛇动18 void DestroySnake();                //销毁蛇19 void ChangeDir();                   //蛇随着方向键动起来20 bool IsSnakeDie();                  //判断蛇是否死亡21 void ProduceFood();                 //随机位置产生食物22 void SnakeGrowUp();                 //蛇变长23 void PrintScore();                  //打印分数24 25 26 #endif // GREEDYSNAKE_H_INCLUDED

 

GreedySnake.c

1 #include 
2 #include
3 #include
4 #include
5 #include
6 #include
7 #include "GreedySnake.h" 8 9 //把所有元素置为0 10 //snake[0][0]表示蛇头的行,snake[0][1]表示蛇头的列,snake[0][2]表示蛇头移动的方向 11 int g_arrSnake[SNAKE_LENGTH][3] = { 0 }; 12 13 int g_iSnakeLength = 2; //初始长度为3,但数组下标从0开始,故此处为2 14 15 char g_arrBackGround[20][50] = 16 { 17 "████████████████████████\n", //一个█占两个字节,占两个字符的位置 18 "█ █\n", 19 "█ █\n", 20 "█ █\n", 21 "█ █\n", 22 "█ █\n", 23 "█ █\n", 24 "█ █\n", 25 "█ █\n", 26 "█ █\n", 27 "█ █\n", 28 "█ █\n", 29 "█ █\n", 30 "█ █\n", 31 "█ █\n", 32 "█ █\n", 33 "█ █\n", 34 "█ █\n", 35 "█ █\n", 36 "████████████████████████\n" 37 }; 38 39 int g_iSnakeDir = LEFT; //蛇的方向,默认向左 40 bool g_bIsProFood = true; //蛇产生食物的标记 41 int g_iRow; //食物的行坐标 42 int g_iCol; //食物的列坐标 43 44 int g_iScore = 0; //分数 45 46 47 48 void FirstPage() //设置起始游戏界面 49 { 50 for (int i = 0; i < 20; ++i) 51 printf(" "); 52 for (int i = 0; i < 60; ++i) 53 printf("*"); 54 printf("\n"); 55 56 for (int j = 0; j < 5; ++j) 57 { 58 for (int i = 0; i < 20; ++i) 59 printf(" "); 60 printf("*"); 61 for (int i = 0; i < 58; ++i) 62 printf(" "); 63 printf("*\n"); 64 } 65 66 for (int i = 0; i < 20; ++i) 67 printf(" "); 68 printf("*"); 69 for (int i = 0; i < 15; ++i) 70 printf(" "); 71 printf("《 欢迎来到贪吃蛇的世界!》"); 72 for (int i = 0; i < 16; ++i) 73 printf(" "); 74 printf("*\n"); 75 76 for (int i = 0; i < 20; ++i) 77 printf(" "); 78 printf("*"); 79 for (int i = 0; i < 15; ++i) 80 printf(" "); 81 printf("《 请按空格键开始游戏 》"); 82 for (int i = 0; i < 16; ++i) 83 printf(" "); 84 printf("*\n"); 85 86 for (int j = 0; j < 10; ++j) 87 { 88 for (int i = 0; i < 20; ++i) 89 printf(" "); 90 printf("*"); 91 for (int i = 0; i < 58; ++i) 92 printf(" "); 93 printf("*\n"); 94 } 95 96 for (int i = 0; i < 20; ++i) 97 printf(" "); 98 for (int i = 0; i < 60; ++i) 99 printf("*");100 for (int i = 0; i < 8; ++i)101 printf("\n");102 }103 104 void TestSpace() //按空格开始游戏105 {106 char c;107 while ((c = getch()) != ' ') //getch()在头文件
内108 {109 110 }111 system("cls"); //清屏112 }113 114 void ShowBackground() //展示游戏背景115 {116 for (int i = 0; i < 20; ++i)117 printf(g_arrBackGround[i]);118 }119 120 void SetSnakeRandPos() //设置蛇的初始位置,默认蛇的身子为三节,向左移动121 {122 int x, y;123 srand((unsigned)time(NULL));124 x = rand()% 20 + 1; //因为蛇的身子起始为三节,所以x的范围为1-20(蛇不能起始就撞墙)125 y = rand()% 18 + 1;126 127 g_arrSnake[0][0] = y; //行 注意:x,y和初始背景中的行列刚好是反的128 g_arrSnake[0][1] = x * 2; //列 注意:一个█占两个字节,所以算其坐标时要乘以2129 g_arrSnake[0][2] = LEFT; //方向130 131 g_arrSnake[1][0] = y;132 g_arrSnake[1][1] = x * 2 + 2;133 g_arrSnake[1][2] = LEFT;134 135 g_arrSnake[2][0] = y;136 g_arrSnake[2][1] = x * 2 + 4;137 g_arrSnake[2][2] = LEFT;138 139 DrawSnake();140 }141 142 void DrawSnake() //展示蛇143 {144 //因为一个█占两个字节,所以不能直接用strcpy(&arrBackGround[arrSnake[i][0]][arrSnake[i][1]],"█");否则会把\0拷贝进来,导致出错145 //由于前面把arrSnake的所有元素都置为了0,所以当arrSnake[i][0]为0时,代表那个坐标处没有蛇的身子146 for (int i = 0; g_arrSnake[i][0] != 0; ++i)147 strncpy(&g_arrBackGround[g_arrSnake[i][0]][g_arrSnake[i][1]], "█", 2); //注意取地址符&不能漏掉!148 }149 150 151 void DestroySnake() //销毁蛇152 {153 for (int i = 0; g_arrSnake[i][0] != 0; ++i)154 strncpy(&g_arrBackGround[g_arrSnake[i][0]][g_arrSnake[i][1]], " ", 2); //注意取地址符&不能漏掉!155 156 }157 158 void SnakeMove() //蛇动159 {160 DestroySnake();161 for(int i = SNAKE_LENGTH - 1; i >= 1; --i)162 {163 if(g_arrSnake[i][0] != 0)164 {165 //把前一个节点的值,赋给当前节点166 g_arrSnake[i][0] = g_arrSnake[i-1][0];167 g_arrSnake[i][1] = g_arrSnake[i-1][1];168 g_arrSnake[i][2] = g_arrSnake[i-1][2];169 }170 }171 172 g_arrSnake[0][2] = g_iSnakeDir; //设置蛇头方向173 174 //处理第一个节点(蛇头)175 if(g_arrSnake[0][2] == LEFT || g_arrSnake[0][2] == RIGHT) //左右移动,列加减2176 {177 g_arrSnake[0][1] += g_arrSnake[0][2];178 }179 else180 {181 g_arrSnake[0][0] += g_arrSnake[0][2]; //上下移动,行加减1182 }183 184 DrawSnake();185 186 }187 188 void ChangeDir() //改变方向189 {190 //不能用getchar(), 会回显,并且要按回车之后才会开始读取191 //不能用getch(), 同步检测192 193 //异步检测194 if(GetAsyncKeyState('W'))195 {196 if (g_arrSnake[0][2] != DOWN) //蛇不能回头197 g_iSnakeDir = UP;198 }199 200 if(GetAsyncKeyState('S'))201 {202 if (g_arrSnake[0][2] != UP)203 g_iSnakeDir = DOWN;204 }205 206 if(GetAsyncKeyState('A'))207 {208 if (g_arrSnake[0][2] != RIGHT)209 g_iSnakeDir = LEFT;210 }211 212 if(GetAsyncKeyState('D'))213 {214 if (g_arrSnake[0][2] != LEFT)215 g_iSnakeDir = RIGHT;216 }217 }218 219 bool IsSnakeDie() //蛇死亡判断(包括撞墙和吃自己,两种情况)220 {221 if(g_arrSnake[0][2] == LEFT || g_arrSnake[0][2] == RIGHT) //如果蛇左右移动,则判断蛇头的左右是否是"█",如果是,则判定为蛇死亡222 {223 if(!strncmp(&g_arrBackGround[g_arrSnake[0][0]][g_arrSnake[0][1]+g_arrSnake[0][2]], "█", 2)) //注意取地址符&不能漏掉!224 return true;225 }226 else //如果蛇上下移动,则判断蛇头的上下是否是"█"227 {228 if(!strncmp(&g_arrBackGround[g_arrSnake[0][0]+g_arrSnake[0][2]][g_arrSnake[0][1]], "█", 2))229 return true;230 }231 return false;232 }233 234 void ProduceFood() //随机位置产生食物235 {236 //判断是否产生新的食物237 if(g_bIsProFood == false)238 return;239 240 bool bFlag = true;241 srand((unsigned)time(NULL));242 243 while(1) //产生合法的食物,即食物不与蛇的身子重合244 {245 g_iRow = rand()% 18 + 1; //行246 g_iCol = rand()% 22 + 1;247 248 for (int i = 0; g_arrSnake[i][0] != 0; i++) //遍历蛇249 if (g_iRow == g_arrSnake[i][0] && g_iCol == g_arrSnake[i][1]) //如果在食物产生在蛇身上250 {251 bFlag = false;252 break;253 }254 255 if(bFlag == true)256 break;257 }258 259 strncpy(&g_arrBackGround[g_iRow][g_iCol*2], "★", 2);260 g_bIsProFood = false;261 }262 263 void SnakeGrowUp() //蛇变长264 {265 if(g_iRow == g_arrSnake[0][0] && g_iCol*2 == g_arrSnake[0][1]) //注意:列要乘以2266 {267 if (UP == g_arrSnake[g_iSnakeLength][2])268 {269 g_arrSnake[g_iSnakeLength+1][0] = g_arrSnake[g_iSnakeLength][0]+1;270 g_arrSnake[g_iSnakeLength+1][1] = g_arrSnake[g_iSnakeLength][0];271 g_arrSnake[g_iSnakeLength+1][2] = g_arrSnake[g_iSnakeLength][2];272 }273 else if (DOWN == g_arrSnake[g_iSnakeLength][2])274 {275 g_arrSnake[g_iSnakeLength+1][0] = g_arrSnake[g_iSnakeLength][0]-1;276 g_arrSnake[g_iSnakeLength+1][1] = g_arrSnake[g_iSnakeLength][0];277 g_arrSnake[g_iSnakeLength+1][2] = g_arrSnake[g_iSnakeLength][2];278 }279 else if (LEFT == g_arrSnake[g_iSnakeLength][2])280 {281 g_arrSnake[g_iSnakeLength+1][0] = g_arrSnake[g_iSnakeLength][0];282 g_arrSnake[g_iSnakeLength+1][1] = g_arrSnake[g_iSnakeLength][0]+2;283 g_arrSnake[g_iSnakeLength+1][2] = g_arrSnake[g_iSnakeLength][2];284 }285 else if (RIGHT == g_arrSnake[g_iSnakeLength][2])286 {287 g_arrSnake[g_iSnakeLength+1][0] = g_arrSnake[g_iSnakeLength][0];288 g_arrSnake[g_iSnakeLength+1][1] = g_arrSnake[g_iSnakeLength][0]-2;289 g_arrSnake[g_iSnakeLength+1][2] = g_arrSnake[g_iSnakeLength][2];290 }291 g_iSnakeLength++;292 g_bIsProFood = true;293 g_iScore++;294 }295 296 }297 298 void PrintScore() //打印分数299 {300 COORD rd;301 //设置光标位置302 rd.X = 59;303 rd.Y = 10;304 SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), rd);305 printf("分数");306 307 rd.X = 60;308 rd.Y = 11;309 //设置光标位置310 SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), rd);311 //打印312 printf ("%d", g_iScore);313 }

 

main.c

1 #include 
2 #include
3 #include
4 #include
5 #include
6 #include "GreedySnake.h" 7 8 9 int main()10 {11 FirstPage();12 TestSpace();13 system("cls");14 SetSnakeRandPos();15 ShowBackground();16 17 while (1)18 {19 system("cls");20 ProduceFood();21 SnakeGrowUp();22 ChangeDir();23 24 if(IsSnakeDie())25 {26 printf("snake die!\n");27 break;28 }29 30 SnakeMove();31 ShowBackground();32 PrintScore();33 34 Sleep(500);35 }36 system("pause");37 return 0;38 }

 

转载于:https://www.cnblogs.com/FengZeng666/p/9694965.html

你可能感兴趣的文章
《TCP/IP 详解 卷一》读书笔记 -----第四章 ARP
查看>>
C# Stream 和 byte[] 之间的转换
查看>>
OMG: daily scrum nine
查看>>
redis与spring结合错误情况
查看>>
第六章 字节码执行方式--解释执行和JIT
查看>>
字符串方法title()、istitle()
查看>>
yield语句
查看>>
查看linux系统中占用cpu最高的语句
查看>>
[洛谷P1738]洛谷的文件夹
查看>>
ubuntu server设置时区和更新时间
查看>>
【京东咚咚架构演进】-- 好文收藏
查看>>
【HTML】网页中如何让DIV在网页滚动到特定位置时出现
查看>>
文件序列化
查看>>
jQuery之end()和pushStack()
查看>>
Bootstrap--响应式导航条布局
查看>>
Learning Python 009 dict(字典)和 set
查看>>
JavaScript中随着鼠标拖拽而移动的块
查看>>
HDU 1021 一道水题
查看>>
The operation couldn’t be completed. (LaunchServicesError error 0.)
查看>>
php每天一题:strlen()与mb_strlen()的作用分别是什么
查看>>