[新手上路]批处理新手入门导读[视频教程]批处理基础视频教程[视频教程]VBS基础视频教程[批处理精品]批处理版照片整理器
[批处理精品]纯批处理备份&还原驱动[批处理精品]CMD命令50条不能说的秘密[在线下载]第三方命令行工具[在线帮助]VBScript / JScript 在线参考
返回列表 发帖

C 语言贪吃蛇

本帖最后由 Gin_Q 于 2020-8-27 20:33 编辑

# 思路来自(知乎 id = int)int
# 还有些功能没有写!
  1. /*
  2. @ BY COOL_BREEZE
  3. @ 2020-08-27
  4. */
  5. #include<stdio.h>
  6. #include<stdlib.h>
  7. #include<time.h>
  8. #include<conio.h>
  9. #include<windows.h>
  10. #define HIGHT 30
  11. #define WIDTH 100
  12. // dos窗口显示模式
  13. #define MODE(X, Y) "MODE CON COLS="#X" LINES="#Y
  14. #define HAD (GetStdHandle(STD_OUTPUT_HANDLE))
  15. // 蛇的结构体开辟内存空间
  16. #define CALLSNAKE ((SNAKEP)malloc(sizeof(SNAKEV)))
  17. void hidecursor(void); // 改变光标的显示方式
  18. void gotoxy_print(int x, int y, char icon); // 移动光标到指定位置打印图标
  19. void __init__(void); // 初始化边框
  20. void create_snake(void); // 生成蛇
  21. void move_snake(void); // 移动蛇
  22. void create_food(void); // 生成食物
  23. void get_keyborad_input(void); // 获取键盘值
  24. int hit_the_wall(void); // 蛇撞墙
  25. void game_method(void);
  26. typedef struct SNAKE
  27. {
  28. int x;  
  29. int y;
  30. struct SNAKE* next;
  31. } SNAKEV, *SNAKEP;
  32. SNAKEP SNAKE_HEAD; //蛇头
  33. SNAKEP SNAKE_FOOD; //食物
  34. //蛇前进的方向
  35. #define U 0X48 // 上
  36. #define D 0X50 // 下
  37. #define L 0X4B // 左
  38. #define R 0X4D // 右
  39. #define S 0X7F // 空格 暂停
  40. char DIRECTION = L; // 默认蛇往左边移动
  41. char HEAD_ICON = 0XF;
  42. char BODY_ICON = 0XB;
  43. char FOOD_ICON = 0X24;
  44. char NULL_ICON = 0X20;
  45. int main(void)
  46. {
  47. system(MODE(130, 30));
  48. system("title 贪吃蛇游戏");
  49. game_method();
  50. hidecursor();
  51. __init__();
  52. SNAKE_FOOD = CALLSNAKE;
  53. create_snake();
  54. create_food();
  55. int ser; // 延迟
  56. while(1)
  57. {
  58. ser = 0;
  59. move_snake();
  60. if (kbhit()) // 检查键盘是否被按下,非阻塞的 (相当于多线程)
  61. {
  62. get_keyborad_input();
  63. Sleep(20);
  64. ser = 1;
  65. }
  66. if (hit_the_wall())
  67. {
  68. gotoxy_print((WIDTH-8) / 2, HIGHT / 2, NULL_ICON);
  69. printf("游戏结束");
  70. system("pause >nul");
  71. break;
  72. }
  73. if (ser)
  74. Sleep(10);
  75. else Sleep(200);
  76. }
  77. return 0;
  78. }
  79. void hidecursor(void)
  80. {
  81. CONSOLE_CURSOR_INFO show = {1, 0};
  82. SetConsoleCursorInfo(HAD, &show);
  83. }
  84. void gotoxy_print(int x, int y, char icon)
  85. {
  86. COORD poin = {x, y}; // 结构体
  87. SetConsoleCursorPosition(HAD, poin); // 跳转到窗口指定位置
  88. printf("%c", icon);
  89. }
  90. void game_method(void)
  91. {
  92. gotoxy_print(WIDTH + 5, HIGHT/2-7, NULL_ICON);
  93. printf("DATE 2020-08-27");
  94. gotoxy_print(WIDTH + 5, HIGHT/2-6, NULL_ICON);
  95. printf("BY COOL_BREEZE");
  96. gotoxy_print(WIDTH + 5, HIGHT/2-4, NULL_ICON);
  97. printf("空格 暂停");
  98. gotoxy_print(WIDTH + 5, HIGHT/2-3, NULL_ICON);
  99. printf("向上 ↑");
  100. gotoxy_print(WIDTH + 5, HIGHT/2-2, NULL_ICON);
  101. printf("向下 ↓");
  102. gotoxy_print(WIDTH + 5, HIGHT/2-1, NULL_ICON);
  103. printf("向左 ←");
  104. gotoxy_print(WIDTH + 5, HIGHT/2, NULL_ICON);
  105. printf("向右 →");
  106. }
  107. void __init__(void)
  108. {
  109. int i = 0;
  110. gotoxy_print(0, 0, 0X1); // 角落  1
  111. gotoxy_print(WIDTH-1, 0, 0X2); // 角落  2
  112. for (i=1; i<WIDTH-1; i++) // 上下边框
  113. {
  114. gotoxy_print(i, 0, 0X6);
  115. gotoxy_print(i, HIGHT-1, 0X6);
  116. }
  117. for (i=1;i<HIGHT-1; i++) // 左右边框
  118. {
  119. gotoxy_print(0, i, 0X5);
  120. gotoxy_print(WIDTH-1, i, 0X5);
  121. }
  122. gotoxy_print(0, HIGHT-1, 0X3); // 角落  3
  123. gotoxy_print(WIDTH-1, HIGHT-1, 0X4); // 角落  4
  124. }
  125. void create_snake(void)
  126. {
  127. int i = 0,x = (WIDTH-6) / 2, y = HIGHT / 2; //在中心创建蛇
  128. SNAKEP phead, pend;
  129. for (; i<6; i++) // 蛇默认长度为6
  130. {
  131. pend = CALLSNAKE;
  132. if (!i)
  133. {
  134. SNAKE_HEAD = phead = pend;
  135. pend->x = x;
  136. pend->y = y;
  137. gotoxy_print(SNAKE_HEAD->x, SNAKE_HEAD->y, HEAD_ICON);
  138. }
  139. else
  140. {
  141. phead->next = pend;
  142. pend->x = x + i; // 蛇身体在头右方
  143. pend->y = y;
  144. gotoxy_print(pend->x, pend->y, BODY_ICON);
  145. phead = pend;
  146. }
  147. }
  148. pend->next = NULL;
  149. }
  150. void move_snake(void)
  151. {
  152. SNAKEP head = CALLSNAKE; // 蛇新的头部
  153. switch (DIRECTION)
  154. {
  155. case U:
  156. head->x = SNAKE_HEAD->x;
  157. head->y = SNAKE_HEAD->y - 1;
  158. break;
  159. case D:
  160. head->x = SNAKE_HEAD->x;
  161. head->y = SNAKE_HEAD->y + 1;
  162. break;
  163. case L:
  164. head->x = SNAKE_HEAD->x - 1;
  165. head->y = SNAKE_HEAD->y;
  166. break;
  167. case R:
  168. head->x = SNAKE_HEAD->x + 1;
  169. head->y = SNAKE_HEAD->y;
  170. break;
  171. case S:
  172. system("pause >nul");
  173. break;
  174. }
  175. head->next = SNAKE_HEAD; // 旧头部连接新头部 使旧头部成为身体
  176. SNAKE_HEAD = head; // 获取头部
  177. if (SNAKE_HEAD->x == SNAKE_FOOD->x && SNAKE_HEAD->y == SNAKE_FOOD->y) // 检查蛇是否吃到食物
  178. {
  179. while (head) // 吃到了食物蛇蛇尾不需要释放
  180. {
  181. if (head == SNAKE_HEAD)
  182. gotoxy_print(SNAKE_HEAD->x, SNAKE_HEAD->y, HEAD_ICON);
  183. else
  184. gotoxy_print(head->x, head->y, BODY_ICON);
  185. head = head->next;
  186. }
  187. create_food();
  188. }
  189. else
  190. {
  191. while (head->next->next) // 没吃到食物释放掉蛇尾
  192. {
  193. if (head == SNAKE_HEAD)
  194. gotoxy_print(SNAKE_HEAD->x, SNAKE_HEAD->y, HEAD_ICON);
  195. else
  196. gotoxy_print(head->x, head->y, BODY_ICON);
  197. head = head->next;
  198. }
  199. gotoxy_print(head->next->x, head->next->y, NULL_ICON);
  200. free(head->next);
  201. head->next = NULL;
  202. }
  203. }
  204. void create_food(void)
  205. {
  206. SNAKEP  temp;
  207. while (1)
  208. {
  209. srand(time(NULL)); // 获取新种子 生成新的随机数
  210. SNAKE_FOOD->x = rand() % (WIDTH - 2) + 1; // 确保坐标只会出现在表格内(不包括表格)
  211. SNAKE_FOOD->y = rand() % (HIGHT - 2) + 1; // 确保坐标只会出现在表格内(不包括表格)
  212. temp = SNAKE_HEAD;
  213. while(temp) // 食物落在蛇身上重新获取
  214. {
  215. if (temp->x == SNAKE_FOOD->x && temp->y == SNAKE_FOOD->y)
  216. continue;
  217. else
  218. {
  219. gotoxy_print(SNAKE_FOOD->x, SNAKE_FOOD->y, FOOD_ICON);
  220. break;
  221. }
  222. }
  223. break;
  224. }
  225. }
  226. void get_keyborad_input(void)
  227. {
  228. int key = 0;
  229.     while (1)
  230.     {
  231.         key = getch();
  232.         if (key == 224) // 键盘方向键需要获取两次
  233.         {
  234.             key = getch();
  235.             if (key == U ||\
  236.                 key == D ||\
  237.                 key == L ||\
  238.                 key == R)
  239.             {
  240.              DIRECTION = key;
  241.              break;
  242. }
  243.             else continue;
  244.         }
  245.     }
  246. }
  247. int hit_the_wall(void)
  248. {
  249. if (SNAKE_HEAD->x == 0 || SNAKE_HEAD->x == WIDTH-1 ||\
  250. SNAKE_HEAD->y == 0 || SNAKE_HEAD->y == HIGHT-1 )
  251. return 1;
  252. return 0;
  253. }
复制代码

回复 2# Batcher


    代码哪里有问题,卡卡的!难搞咯!

TOP

返回列表