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

GreedySnake.h

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

GreedySnake.c

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

main.c

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

C语言 —— 贪吃蛇的更多相关文章

  1. c语言贪吃蛇详解3.让蛇动起来

    c语言贪吃蛇详解3.让蛇动起来 前几天的实验室培训课后作业我布置了贪吃蛇,今天有时间就来写一下题解.我将分几步来教大家写一个贪吃蛇小游戏.由于大家c语言未学完,这个教程只涉及数组和函数等知识点. 上次 ...

  2. c语言贪吃蛇详解-2.画出蛇

    c语言贪吃蛇详解-2.画出蛇 前几天的实验室培训课后作业我布置了贪吃蛇,今天有时间就来写一下题解.我将分几步来教大家写一个贪吃蛇小游戏.由于大家c语言未学完,这个教程只涉及数组和函数等知识点. 蛇的身 ...

  3. c语言贪吃蛇详解1.画出地图

    c语言贪吃蛇详解-1.画出地图 前几天的实验室培训课后作业我布置了贪吃蛇,今天有时间就来写一下题解.我将分几步来教大家写一个贪吃蛇小游戏.由于大家c语言未学完,这个教程只涉及数组和函数等知识点. 首先 ...

  4. c语言贪吃蛇详解5.GameOver功能与显示成绩

    c语言贪吃蛇详解5.GameOver功能与显示成绩 以前我们已经做出来了一个能吃东西变长的蛇.不过它好像不会死... 现在就来实现一下game over的功能吧. 写个函数判断蛇是否撞到自己或者撞到墙 ...

  5. c语言贪吃蛇详解4.食物的投放与蛇的变长

    c语言贪吃蛇详解4.食物的投放与蛇的变长 前几天的实验室培训课后作业我布置了贪吃蛇,今天有时间就来写一下题解.我将分几步来教大家写一个贪吃蛇小游戏.由于大家c语言未学完,这个教程只涉及数组和函数等知识 ...

  6. 程序游戏推荐(C语言贪吃蛇,python天天酷跑(需要安装pygame),js是狠人就坚持30s)

    下面是下载位置,我把他们上传到我的文件下了. C语言贪吃蛇:https://files.cnblogs.com/files/ITXiaoAng/%E8%B4%AA%E5%90%83%E8%9B%87. ...

  7. C/C++编程笔记:C语言贪吃蛇源代码控制台(二),分数和食物!

    接上文<C/C++编程笔记:C语言贪吃蛇源代码控制台(一),会动的那种哦!>如果你在学习C语言开发贪吃蛇的话,零基础建议从上一篇开始哦!接下来正式开始吧! 三.蛇的运动 上次我已经教大家画 ...

  8. C/C++编程笔记:C语言贪吃蛇源代码控制台(一),会动的那种哦!

    前几天有个同学加我QQ私聊我说他们老师布置了一个贪吃蛇,他不知道怎么写所以来找我求解,我给他简单讲解了思路和一些难点之后他也能够自己独立将项目完成了!考虑到更多同学可能有贪吃蛇上的问题,今天有时间就来 ...

  9. c语言贪吃蛇

    思路:函数gotoxy(x,y)使光标移植屏幕的x,y坐标(屏幕左上角为0,0),用来绘制蛇和界面,color()函数用来设置绘制的颜色.设有snakelong节,第i节蛇的x坐标为x[i],y坐标为 ...

  10. [C语言]贪吃蛇_结构数组实现

    一.设计思路 蛇身本质上就是个结构数组,数组里存储了坐标x.y的值,再通过一个循环把它打印出来,蛇的移动则是不断地刷新重新打印.所以撞墙.咬到自己只是数组x.y值的简单比较. 二.用上的知识点 结构数 ...

随机推荐

  1. .NET 单点登录开源项目

    1. https://www.apereo.org/cas/client-integration 2.源码下载 https://wiki.jasig.org/display/CASC/.Net+Cas ...

  2. luogu P4360 [CEOI2004]锯木厂选址

    斜率优化dp板子题[迫真] 这里从下往上标记\(1-n\)号点 记\(a_i\)表示前缀\(i\)里面树木的总重量,\(l_i\)表示\(i\)到最下面的距离,\(s_i\)表示\(1\)到\(i-1 ...

  3. [CERC2016]机棚障碍 Hangar Hurdles(kruskal重构树+树上倍增)

    题面 \(solution:\) 某蒟蒻的心路历程: 这一题第一眼感觉很奇怪 带障碍物的图,最大的集装箱? 首先想到的就是限制我集装箱大小条件的是什么: 如果我要在某一个点上放一个集装箱且使它最大, ...

  4. Python巧用正则表达式,完成接口参数替换

    最近给Python11期的小朋友们上课,遇到了一个参数替换的问题,首先描述下场景: 需要参数化的数据如下所示: 这个时候如果利用单纯的if判断和字符串的find和replace方法,做起来是非常不明智 ...

  5. python基础知识~配置文件模块

    一 配置文件模块   import ConfigParser ->导入模块  conf = ConfigParser.ConfigParser() ->初始化类二 系统函数  conf.r ...

  6. 实验一 Java开发环境的熟悉--20165221

    实验报告封面 课程:Java程序设计 班级:1652班 姓名:谭笑 学号:20165221 成绩: 指导教师:娄嘉鹏 试验日期:2018.4.2 实验组次:21 预习程度:已预习 实验时间:15:35 ...

  7. slf4j的简单用法以及与log4j的区别

    之前在项目中用的日志记录器都是log4j的日志记录器,可是到了新公司发现都是slf4j,于是想着研究一下slf4j的用法. 注意:每次引入Logger的时候注意引入的jar包,因为有Logger的包太 ...

  8. POI读取Excel(xls、xlsx均可以)——(四)

    maven构建的项目-->pom.xml文件 eclipse提供Dependencies直接添加依赖jar包的工具:直接搜索poi以及poi-ooxml即可,maven会自动依赖需要的jar包: ...

  9. Maven安装配置操作

    1)下载maven安装包并解压: 2)环境变量配置: 3)编辑环境变量Path,追加%MAVEN_HOME%\bin; 4)maven安装配置后进行dos命令检查:在cmd中输入 mvn -v 5)配 ...

  10. 升级版updateOozie.sh

    以前的版本检测当天的Tar包,并只能选择1个Tar包进行更新代码,当天生成多个版本时需修改脚本中配置,并不方便. 升级版兼容目录下存在一个或者多个Tar包的情况: 1.单个Tar包时,直接解压缩到当前 ...