贪吃蛇是一款儿时爱不释手的游戏。近日修行,想玩玩游戏开发。便简单写了个控制台版的贪吃蛇。

程序的简单框架:

建立一张固定大小的MAP,保存输出信息。

当信息有变动时,用system("cls")进行清屏操作,再重新输出实现伪动态。

重点算法在蛇身的移动,转向与增长。三者均基于链表实现。

移动与转向:通过判定移动方向,确定下一步移动的位置后,新建表头结点。将新表头结点置为表头。删除末尾结点。

增长:通过判断尾部移动方向,确定位置后在尾部添加节点。

熟练运用链表的同学,相信也是小菜一碟了。

演示代码如下。

  1 /*
  2 *   windy 2016 7.9
  3 *   Snake FirstStep
  4 *   A program of the GreadySnake
  5 */
  6 #include <iostream>
  7 #include <conio.h>   //包含_kbhit()函数的头文件,_kbhit()运用可GOOGLE
  8 #include <string.h>
  9 #include <time.h>
 10 #include <windows.h>
 11 #include <stdio.h>
 12 #include <stdlib.h>
 13 #define ROW 25  // height of MAP
 14 #define COL 75   // weight of MAP
 15
 16 using namespace std;
 17
 18 //蛇身结点结构体
 19 typedef struct Node {
 20     int row;
 21     int col;
 22     Node* next;
 23
 24     Node() {};
 25     Node(int _r, int _c) {
 26         row = _r;
 27         col = _c;
 28     }
 29 }SnakeNode;
 30
 31 //果实结构体
 32 typedef struct {
 33     int row;
 34     int col;
 35     bool isEaten = true;  //果实生成后,isEaten置为false,被吃后,重新置为true
 36 }Fruit;
 37
 38 //draw the map outline
 39 void drawMap();
 40
 41 //create the fruit randomly
 42 void createFruit();
 43
 44 //create the snake body
 45 void createSnake();
 46
 47 //add snake body node
 48 void addNode(SnakeNode* head);
 49
 50 //let the snake move
 51 void snakeMove();
 52
 53 //print the snake
 54 void snakePrint();
 55
 56 //check if snake eat the fruit, if snake pump the boundary
 57 void check();
 58
 59 //snake turn
 60 void snakeTurn();
 61
 62 //erase the tail
 63 void tailErase(SnakeNode* newHead);
 64
 65 //snake body extend
 66 void snakeExtend();
 67
 68 //set global value
 69 Fruit fruit;
 70 //建立一张全是空格的地图
 71 char MAP[ROW][COL];
 72 //创建蛇头
 73 SnakeNode* head = new SnakeNode(10, 20);
 74 //记录分数
 75 int cnt = 0;
 76 //移动速度
 77 int TIME = 60;
 78
 79 int main()
 80 {
 81     system("color 0C");   //设置背景色
 82     system("title 贪吃蛇小游戏~");  //设置窗口名字
 83     system("mode con cols=80 lines=30");  //设置窗口大小
 84     memset(MAP, ' ', sizeof(MAP));
 85     createSnake();      //生成蛇
 86     drawMap();     //主要函数,详见下面代码
 87     return 0;
 88 }
 89
 90 void drawMap()
 91 {
 92     while (true) {
 93         //绘制地图外框
 94         for (int row = 0; row != ROW; row++) {
 95             for (int col = 0; col != COL; col++) {
 96                 if (row == 0 || row == ROW - 1)
 97                     MAP[row][col] = '-';
 98                 else if (col == 0 || col == COL - 1)
 99                     MAP[row][col] = '*';
100             }
101         }
102
103         if (!_kbhit())
104             snakeMove(); //无键盘输入信号,继续向前移动
105         else snakeTurn();    //有键盘输入信号,进行转向判定
106         check();          //检查移动后是否吃到果实,是否越界,是否自撞
107         if (fruit.isEaten) {
108             createFruit();
109             fruit.isEaten = false;
110         }
111         //打印地图
112         for (int row = 0; row != ROW; row++) {
113             for (int col = 0; col != COL; col++) {
114                 printf("%c", MAP[row][col]);
115             }
116             printf("\n"); //换行
117         }
118
119         Sleep(TIME);
120         system("cls");
121     }
122 }
123
124 void createFruit()
125 {
126     srand((unsigned)time(NULL));
127     int row = rand() % (ROW - 1) + 1;
128     int col = rand() % (COL - 1) + 1;
129
130     //检查果实是否在蛇身生成
131     SnakeNode* cur = head;
132     while (cur) {
133         if (cur->row == row && cur->col == col) {
134             row = rand() % (ROW - 1) + 1;   //若是,重新生成果实
135             col = rand() % (COL - 1) + 1;
136             cur = head;
137             continue;
138         }
139         cur = cur->next;
140     }
141
142     fruit.row = row;
143     fruit.col = col;
144     MAP[row][col] = '$';
145 }
146
147 void createSnake()
148 {
149     head->next = NULL;
150
151     //生成蛇身
152     const int N = 5;
153     for (int i = 0; i != N; i++) {
154         addNode(head);
155     }
156
157     //在MAP绘制蛇身
158     snakePrint();
159 }
160
161 void addNode(SnakeNode* head)
162 {
163     SnakeNode* curBody = head;
164
165     while (curBody->next) {
166         curBody = curBody->next;
167     }
168
169     SnakeNode* malc = new SnakeNode(curBody->row, curBody->col - 1);
170     malc->next = NULL;
171
172     curBody->next = malc;
173 }
174
175 void snakeMove()
176 {
177     SnakeNode* newHead = new SnakeNode();
178     //前进状态
179     if (head->row == head->next->row) {
180         if (head->col > head->next->col)  newHead->col = head->col + 1; //若向右行
181         else newHead->col = head->col - 1;   //若向左行
182         newHead->row = head->row;
183         newHead->next = head;
184     }
185     else if (head->col == head->next->col) {
186         if (head->row > head->next->row)  newHead->row = head->row + 1; //若向下行
187         else newHead->row = head->row - 1; //若向上行
188         newHead->col = head->col;
189         newHead->next = head;
190     }
191     //蛇移动后,将蛇尾结点删除
192     tailErase(newHead);
193     head = newHead;
194     snakePrint();
195 }
196
197 void snakePrint()
198 {
199     MAP[head->row][head->col] = '@';
200     SnakeNode* cur = head->next;
201     while (cur) {
202         MAP[cur->row][cur->col] = '#';
203         cur = cur->next;
204     }
205 }
206
207 void check()
208 {
209     if (fruit.row == head->row && fruit.col == head->col) {
210         fruit.isEaten = true;
211         cnt += 10;
212         TIME -= 5;
213         //snake extend while eating the fruit
214         snakeExtend();
215     }
216     if (head->row == ROW-1 || head->row == 0 || head->col == COL-1 || head->col == 0) {
217         printf("                   撞到墙啦!游戏结束 -_- \n\n\n\n 本次得分%d!\n\n\n\n",cnt);
218         if ( cnt <= 40 ) printf("                              为何如此彩笔!\n");
219         if (cnt > 40 && cnt < 80) printf("                       你离极限玩家不远了!\n");
220         if (cnt >= 80) printf("                          你已经超神了!\n");
221         system("pause");
222         exit(1);
223     }
224
225     SnakeNode* cur = head->next;
226     while (cur->next) {
227         if (head->row == cur->row && head->col == cur->col) {
228             printf(" 撞到自己啦!游戏结束 -_- \n\n\n\n 本次得分%d!\n\n\n\n", cnt);
229             if (cnt <= 40) printf("                              为何如此彩笔!\n");
230             if (cnt > 40 && cnt < 80) printf("                       你离极限玩家不远了!\n");
231             if (cnt >= 80) printf("                          你已经超神了!\n");
232             system("pause");
233             exit(1);
234         }
235         cur = cur->next;
236     }
237 }
238
239 void snakeTurn()
240 {
241     char key;
242     if (_kbhit()) { //kbhit函数在有键盘输入是,返回0.. 检测是否有键盘输入
243         while (_kbhit())  //存在多次输入时,以最后一次输入为主
244             key = _getch();
245         SnakeNode* newHead = new SnakeNode();
246         switch (key) {  //判断转向
247         case 'w': { //上转
248             if (head->row <= head->next->row) {
249                 newHead->row = head->row - 1;
250                 newHead->col = head->col;
251                 newHead->next = head;
252                 tailErase(newHead);
253                 head = newHead;
254             }
255         }break;
256         case 's': {//下转
257             if (head->row >= head->next->row) {
258                 newHead->row = head->row + 1;
259                 newHead->col = head->col;
260                 newHead->next = head;
261                 tailErase(newHead);
262                 head = newHead;
263             }
264         }break;
265         case 'a': {//左转
266             if (head->col <= head->next->col) {
267                 newHead->row = head->row;
268                 newHead->col = head->col - 1;
269                 newHead->next = head;
270                 tailErase(newHead);
271                 head = newHead;
272             }
273         }break;
274         case 'd': {//右转
275             if (head->col >= head->next->col) {
276                 newHead->row = head->row;
277                 newHead->col = head->col + 1;
278                 newHead->next = head;
279                 tailErase(newHead);
280                 head = newHead;
281             }
282         }break;
283         default: {
284             snakeMove();
285         }break;
286         }
287         snakePrint();
288     }
289 }
290
291 void tailErase(SnakeNode* newHead)
292 {
293     //删除尾部节点
294     SnakeNode* cur = newHead;
295     while (cur->next->next) {
296         cur = cur->next;
297     }
298     //将尾部结点置空
299     MAP[cur->next->row][cur->next->col] = ' ';
300     free(cur->next);
301     cur->next = NULL;
302 }
303
304 void snakeExtend()
305 {
306     SnakeNode* cur = head;
307
308     while (cur->next->next) {
309         cur = cur->next;
310     }
311
312     SnakeNode* newTail = new SnakeNode();
313     if (cur->row == cur->next->row) //尾部横向
314         if (cur->col > cur->next->col) { //尾巴在左
315             newTail->row = cur->next->row;
316             newTail->col = cur->next->col - 1;
317         }
318         else {
319             newTail->row = cur->next->row;
320             newTail->col = cur->next->col + 1; //尾巴在右
321         }
322     else  /*if( cur->col == cur->next->col )*/ //尾部竖向
323         if (cur->row > cur->next->row) {//尾巴在上
324             newTail->row = cur->next->row - 1;
325             newTail->col = cur->next->col;
326         }
327         else {
328             newTail->row = cur->next->row + 1;//尾巴在下
329             newTail->col = cur->next->col;
330         }
331
332         newTail->next = NULL;
333         cur->next->next = newTail;
334         snakePrint();
335 }

简单简单的控制台贪吃蛇就完成啦~

转载于:https://www.cnblogs.com/win-D-y/p/5656853.html

贪吃蛇小游戏 (一)相关推荐

  1. 100行代码,使用 Pygame 制作一个贪吃蛇小游戏!

    作者 | 周萝卜 来源 | 萝卜大杂烩 相信我们大家都玩过贪吃蛇游戏,今天我们就从头一起来写一个贪吃蛇小游戏,只需要100多行的代码就完成了. 用到的 Pygame 函数 贪吃蛇小游戏用到的函数 功能 ...

  2. Python实现贪吃蛇小游戏(双人模式)

    这篇文章主要为大家详细介绍了Python实现双人模式的贪吃蛇小游戏,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下 简单用py写了一个贪吃蛇游戏,有单人.双人模式,比较简 ...

  3. GUI编程---贪吃蛇小游戏开发

    学习链接:狂神说Java–1小时开发贪吃蛇小游戏 ①初识理论 帧:时间片足够小=>就是动画,1秒30帧.连起来是动画,拆开就是静态的图片! 键盘监听 定时器Timer 游戏图片素材:GUI之贪吃 ...

  4. python 贪吃蛇小游戏代码_10分钟再用Python编写贪吃蛇小游戏

    Python编写贪吃蛇 前不久我们公众号发布了一篇C++编写贪吃蛇小游戏的推文,反响空前.看来大家对这类简单易上手小游戏还是很喜爱的. 恰逢2018年IEEE Spectrum编程语言排行榜新鲜出炉, ...

  5. python100行代码程序-100行python代码,轻松完成贪吃蛇小游戏

    大家小时候都玩过贪吃蛇吧?小编小时候可喜欢拿爸妈的手机玩了,厉害着呢!今天,小编就来用100行代码实现一个简易版的贪吃蛇.在网上,贪吃蛇教程蛮多的,但要安装蛮多库的,而且也不够清晰,今天的代码比较短, ...

  6. python小游戏编程实例-10分钟教你用Python写一个贪吃蛇小游戏,适合练手项目

    另外要注意:光理论是不够的.这里顺便总大家一套2020最新python入门到高级项目实战视频教程,可以去小编的Python交流.裙 :七衣衣九七七巴而五(数字的谐音)转换下可以找到了,还可以跟老司机交 ...

  7. python100行代码-怎样写贪吃蛇小游戏?用100行python代码轻松解决!

    大家小时候都玩过贪吃蛇吧?小编小时候可喜欢拿爸妈的手机玩了,厉害着呢!今天,小编就来用100行代码实现一个简易版的贪吃蛇.在网上,贪吃蛇教程蛮多的,但要安装蛮多库的,而且也不够清晰,今天的代码比较短, ...

  8. python编程小游戏-10分钟用Python编写一个贪吃蛇小游戏,简单

    贪吃蛇,大家应该都玩过.小编当初第一次接触贪吃蛇的时候 ,还是能砸核桃的诺基亚上,当时玩的不亦乐乎.今天,我们用Python编程一个贪吃蛇游戏,下面我们先看看效果: 好了,先介绍一个思路 所有的游戏最 ...

  9. 再来一次的C语言贪吃蛇小游戏(三)

    8.游戏的不同界面 为了便于实现主要功能,之前我们所有的状态控制都是放在游戏中,但实际上我们应该把这些状态控制抽离出来,通过菜单来控制,以便在不同游戏界面间切换. 菜单界面 游戏界面 排行榜 游戏结束 ...

  10. 基于stm32、0.96寸OLED实现的贪吃蛇小游戏(详细源码注释)

    简介:本实验基于stm32最小系统.0.96寸OLED(68*128)和摇杆实现一个经典的贪吃蛇小游戏.项目源码地址:点击下载. 硬件设计: 普通摇杆,0.96寸OLED 单色屏幕(SPI协议通讯), ...

最新文章

  1. 京东到家甩包袱给达达 路走错了合并也没
  2. JAVA基础9-封装(3)
  3. java虚拟机(二)
  4. python操作gif
  5. [jQuery]10 Things I Learned from the jQuery Source
  6. 5.0:Spring-bean的加载
  7. 每日一题(14)—— 交换a,b的值(不使用中间变量)
  8. 浅谈MySql的存储引擎(表类型)
  9. 遇见低码:在价值中审视
  10. 如何优雅地停止Java进程
  11. [测试技术分享]easyFuzzer使用案例分享
  12. U-最小公倍数 递归
  13. selenium+testng+reprotng+ant配置
  14. 机器学习与数据挖掘工程师的发展方向总结
  15. 华为路由器与交换机常用命令(20200618)
  16. 中柏平板bios对照表_BIOS详解及中英文对照表
  17. 前端 DOM、BOM(二)
  18. 定位神器:1秒定位DOM元素绑定的事件代码的位置
  19. “三年拿下全球第一!”7年小米销量冲到全球第二,雷军做对了什么?
  20. java获取时间并进行计算

热门文章

  1. BAT和IBM信息无障碍现状概要
  2. 视频聊天网站的技术与发展
  3. 电子作业票如何实现特殊作业全过程信息化管理
  4. 史上最简单的Spring Security教程(二十八):CA登录与默认用户名密码登录共存详细实现及配置
  5. 数据中台已成下一风口,它会颠覆数据工程师的工作吗?
  6. 关于PCB行业三巨头的一点个人评价
  7. 安装oracle 19c rac报错:2节点执行root.sh asm实例启动失败
  8. GNSS连续运行单参考站解决方案
  9. 复数和向量的函数运算
  10. 如何查看Win11的CUDA版本