分享自己写的一个贪吃蛇的游戏(Linux)


作者: dave_cn 发表于 2010-07-18 21:20 原文链接 阅读: 148 评论: 2

转载请注明出处。http://www.cnblogs.com/dave_cn/

本程序需要ncurses库,ubuntu下安装ncurses可以执行下面命令:

sudo apt-get install libncurses5-dev 

关于ncurses的用法,读者可以Google之。

程序运行的效果如下:

其中包含两个窗口,一个为game窗口,一个为日志窗口。 

 

 

 代码如下:

   1 /**

  2  * Snake
  3  * author: dave_cn
  4  * date  : 2010/7/14
  5  * info  :
  6  *        @ ...... food
  7  */
  8 #include <stdio.h>
  9 #include <stdlib.h>
 10 #include <string.h>
 11 #include <sys/time.h>
 12 #include <sys/types.h>
 13 #include <unistd.h>
 14 #include <ncurses.h>
 15 
 16 #define TBool            int
 17 #define True             1
 18 #define False            0    
 19 #define SHAPE_FOOD       '@'
 20 #define SHAPE_SNAKE      '*'
 21 #define GAMEWIN_YLEN     15
 22 #define GAMEWIN_XLEN     60
 23 #define LOGWIN_YLEN      7
 24 #define LOGWIN_XLEN      (GAMEWIN_XLEN)
 25 #define LOGBUF_NUM       (LOGWIN_YLEN-2)
 26 #define LOGBUF_LEN       (GAMEWIN_XLEN-2)
 27 #define MAXLEVEL         12
 28 
 29 #define GetSnakeTail(s)  ((s)->head->front)
 30 
 31 WINDOW *logwin;
 32 #define INITRUNLOG()     logwin = newlogw()
 33 #define RUNLOG(str)      runlog(logwin, str)
 34 #define DESTROYRUNLOG()  delwin(logwin)
 35 
 36 int g_level;
 37 
 38 enum TDirection {
 39     DIR_UP,
 40     DIR_DOWN,
 41     DIR_LEFT,
 42     DIR_RIGHT
 43 };
 44 
 45 struct TFood {
 46     int y;
 47     int x;
 48 };
 49 
 50 struct TSnakeNode {
 51     int y;
 52     int x;
 53     struct TSnakeNode *front;
 54 };
 55 
 56 struct TSnake {
 57     int    length;
 58     struct TSnakeNode *head;
 59     enum   TDirection  dir;
 60 };
 61 
 62 int refreshgamew(WINDOW *win, struct TSnake *psnake);
 63 void movesnake(struct TSnake *psnake);
 64 int checksnake(struct TFood *pfood, struct TSnake *psnake);
 65 void snakegrowup(struct TFood *pfood, struct TSnake *psnake);
 66 void gameover(WINDOW *win, char *str);
 67 struct TSnakeNode *newsnakenode(struct TSnakeNode **ppsnode, int y, int x);
 68 WINDOW* newgamew();
 69 struct TSnake* initsnake();
 70 void destroysnake(struct TSnake *psnake);
 71 void drawsnakew(WINDOW *win, struct TSnake *psnake);
 72 void drawfoodw(WINDOW *win, struct TFood *pfood, struct TSnake *psnake);
 73 TBool checkfood(struct TFood *pfood, struct TSnake *psnake);
 74 WINDOW* newlogw();
 75 void runlog(WINDOW *win, char *str);
 76 void cleanline(WINDOW *win, int y, int x);
 77 
 78 int main()
 79 {
 80     initscr();
 81     raw();
 82     noecho();
 83     keypad(stdscr, TRUE);
 84     curs_set(0);
 85     refresh();
 86 
 87     g_level = 1;
 88     INITRUNLOG();
 89     RUNLOG("  Press 'q' or 'Q' to quit.");
 90     RUNLOG("  Press 'w/s/a/d' or 'W/S/A/D' to move the snake.");
 91     RUNLOG("Info:");
 92     
 93     WINDOW *gwin = newgamew();
 94     struct TSnake *psnake = initsnake();
 95     drawsnakew(gwin, psnake);
 96     
 97     while (refreshgamew(gwin, psnake) >= 0) ;
 98     
 99     getch();
100     
101     destroysnake(psnake);
102     delwin(gwin);
103     DESTROYRUNLOG();
104     endwin();
105     
106     return 0;
107 }
108 
109 int refreshgamew(WINDOW *win, struct TSnake *psnake)
110 {
111     static TBool ffood = False;
112     struct TFood pfood;
113     
114     if (!ffood) {
115         drawfoodw(win, &pfood, psnake);
116         ffood = True;
117     }
118 
119     int key = -1;
120     
121     fd_set set;
122     FD_ZERO(&set);
123     FD_SET(0&set);
124     
125     struct timeval timeout;
126     timeout.tv_sec = 0;
127     timeout.tv_usec= (6 - (int)(g_level/3)) * 100*1000;
128     
129     if (select(1&set, NULL, NULL, &timeout) < 0)
130         return -1;
131     
132     if (FD_ISSET(0&set)) {
133         while ((key = getch()) == -1) ;
134     
135         switch (key) {
136         case 'w':
137         case 'W':
138             (psnake->dir == DIR_DOWN) ? : (psnake->dir = DIR_UP);
139             break;
140         
141         case 's':
142         case 'S':
143             (psnake->dir == DIR_UP) ? : (psnake->dir = DIR_DOWN);
144             break;
145         
146         case 'a':
147         case 'A':
148             (psnake->dir == DIR_RIGHT) ? : (psnake->dir = DIR_LEFT);
149             break;
150         
151         case 'd':
152         case 'D':
153             (psnake->dir == DIR_LEFT) ? : (psnake->dir = DIR_RIGHT);
154             break;
155         
156         case 'q':
157         case 'Q':
158             RUNLOG("Quit Game!");
159             gameover(win, "Quit Game!");
160             return -1;
161         
162         default:
163             break;
164         }
165     }
166 
167     movesnake(psnake);
168     drawsnakew(win, psnake);
169     switch (checksnake(&pfood, psnake)) {
170     case 0:
171         break;
172         
173     case 1:
174         ffood = False;
175         if (++g_level > MAXLEVEL) {
176             RUNLOG("Win!!!");
177             gameover(win, "Win!!!");
178             return -1;
179         }
180         mvwprintw(win, GAMEWIN_YLEN-12" Level: %d ", g_level);
181         mvwprintw(win, GAMEWIN_YLEN-130" Speed: %d ", (int)(g_level/3));
182         wrefresh(win);
183         RUNLOG("Level UP!");
184         snakegrowup(&pfood, psnake);
185         break;
186         
187     default:
188         RUNLOG("Game over!");
189         gameover(win, "Game over!");
190         return -1;
191     }
192     
193     return 1;
194 }
195 
196 /**
197  * stuct TSnake是一个倒置的首尾相连的链表,head->front指向snake的尾部
198  * 如: [a]<-[b]<-[c]<-[d]    a为head
199  *      |              ^     snake移动的时候,只用head指向d,
200  *      `--------------'     并且修改d的(y,x)为snake头移动到的位置.
201  */
202 void movesnake(struct TSnake *psnake)
203 {
204     int hy = psnake->head->y;
205     int hx = psnake->head->x;
206     
207     psnake->head = GetSnakeTail(psnake);
208     
209     switch (psnake->dir) {
210     case DIR_UP:
211         psnake->head->= hy - 1;
212         psnake->head->= hx;
213         break;
214     
215     case DIR_DOWN:
216         psnake->head->= hy + 1;
217         psnake->head->= hx;
218         break;
219     
220     case DIR_LEFT:
221         psnake->head->= hy;
222         psnake->head->= hx - 1;
223         break;
224     
225     case DIR_RIGHT:
226         psnake->head->= hy;
227         psnake->head->= hx + 1;
228         break;
229         
230     default:
231         break;
232     }
233 }
234 
235 int checksnake(struct TFood *pfood, struct TSnake *psnake)
236 {
237     if ( psnake->head-><= 0 || psnake->head->>= GAMEWIN_YLEN
238       || psnake->head-><= 0 || psnake->head->>= GAMEWIN_XLEN)
239     {
240         return -1;
241     }
242 
243     struct TSnakeNode *pnode = GetSnakeTail(psnake);
244     int i = 0;
245     for (; i < psnake->length - 1++i, pnode = pnode->front)
246         if (psnake->head->== pnode->&& psnake->head->== pnode->x)
247             return -1;
248 
249     if (psnake->head->== pfood->&& psnake->head->== pfood->x)
250         return 1;
251     
252     return 0;
253 }
254 
255 void snakegrowup(struct TFood *pfood, struct TSnake *psnake)
256 {
257     struct TSnakeNode *pnode = (struct TSnakeNode *)malloc(sizeof(struct TSnakeNode));
258     
259     switch (psnake->dir) {
260     case DIR_UP:
261         pnode->= psnake->head->- 1;
262         pnode->= psnake->head->x;
263         break;
264     
265     case DIR_DOWN:
266         pnode->= psnake->head->+ 1;
267         pnode->= psnake->head->x;
268         break;
269     
270     case DIR_LEFT:
271         pnode->= psnake->head->y;
272         pnode->= psnake->head->- 1;
273         break;
274     
275     case DIR_RIGHT:
276         pnode->= psnake->head->y;
277         pnode->= psnake->head->+ 1;
278         break;
279         
280     default:
281         break;
282     }
283     
284     pnode->front = GetSnakeTail(psnake);
285     psnake->head->front = pnode;
286     psnake->head = pnode;
287     ++psnake->length;
288 }
289 
290 void gameover(WINDOW *win, char *str)
291 {
292     mvwprintw(win, (int)(GAMEWIN_YLEN/2), (GAMEWIN_XLEN/2 - strlen(str)/2), str);
293     mvwprintw(win, (int)(GAMEWIN_YLEN/2 + 1), 20"Press any key to quit...");
294     wrefresh(win);
295 }
296 
297 WINDOW* newgamew()
298 {
299     WINDOW *win = newwin(GAMEWIN_YLEN, GAMEWIN_XLEN, 13);
300     box(win, 00);
301     mvwprintw(win, 02" GAME ");
302     mvwprintw(win, GAMEWIN_YLEN-12" Level: %d ", g_level);
303     mvwprintw(win, GAMEWIN_YLEN-130" Speed: %d ", (int)(g_level/3));
304     wrefresh(win);
305     
306     return win;
307 }
308 
309 struct TSnake* initsnake()
310 {
311     struct TSnake *psnake = (struct TSnake *)malloc(sizeof(struct TSnake));
312 
313     psnake->dir    = DIR_LEFT;
314     psnake->length = 4;
315     
316     newsnakenode (
317         &newsnakenode (
318             &newsnakenode (
319                 &newsnakenode( &psnake->head, 450 )->front, 453
320             )->front, 452
321         )->front, 451
322     )->front = psnake->head;
323 
324     return psnake;
325 }
326 
327 struct TSnakeNode *newsnakenode(struct TSnakeNode **ppsnode, int y, int x)
328 {
329     *ppsnode = (struct TSnakeNode *)malloc(sizeof(struct TSnakeNode));
330     (*ppsnode)->= y;
331     (*ppsnode)->= x;
332     (*ppsnode)->front = NULL;
333     
334     return *ppsnode;
335 }
336 
337 void destroysnake(struct TSnake *psnake)
338 {
339     struct TSnakeNode *psnode = GetSnakeTail(psnake);
340     struct TSnakeNode *ptmp   = NULL;
341     
342     int i = 0;
343     for (; i < psnake->length; ++i) {
344         ptmp   = psnode;
345         psnode = psnode->front;
346         free(ptmp);
347     }
348     
349     free(psnake);
350     psnake = NULL;
351 }
352 
353 void drawsnakew(WINDOW *win, struct TSnake *psnake)
354 {
355     static int taily = 0;
356     static int tailx = 0;
357     if (taily != 0 && tailx != 0) {
358         mvwaddch(win, taily, tailx, ' ');
359     }
360     
361     struct TSnakeNode *psnode = GetSnakeTail(psnake);
362     
363     int i = 0;
364     for (; i < psnake->length; ++i) {
365         mvwaddch(win, psnode->y, psnode->x, SHAPE_SNAKE);
366         psnode = psnode->front;
367     }
368     
369     taily = GetSnakeTail(psnake)->y;
370     tailx = GetSnakeTail(psnake)->x;
371 
372     wrefresh(win);
373 }
374 
375 void drawfoodw(WINDOW *win, struct TFood *pfood, struct TSnake *psnake)
376 {
377     do {
378         pfood->= random() % (GAMEWIN_YLEN - 1+ 1;
379         pfood->= random() % (GAMEWIN_XLEN - 1+ 1;
380     } while (False == checkfood(pfood, psnake));
381     checkfood(pfood, psnake);
382     
383     mvwaddch(win, pfood->y, pfood->x, SHAPE_FOOD);
384     wrefresh(win);
385 }
386 
387 TBool checkfood(struct TFood *pfood, struct TSnake *psnake)
388 {
389     struct TSnakeNode *pnode = GetSnakeTail(psnake);
390 
391     int i = 0;
392     for (; i < psnake->length; ++i, pnode = pnode->front)
393         if (pfood->== pnode->&& pfood->== pnode->x)
394             return False;
395 
396     return True;
397 }
398 
399 WINDOW* newlogw()
400 {
401     WINDOW *win = newwin(LOGWIN_YLEN, LOGWIN_XLEN, GAMEWIN_YLEN + 23);
402     box(win, 00);
403     mvwprintw(win, 02" LOG ");
404     wrefresh(win);
405     
406     return win;
407 }
408 
409 void runlog(WINDOW *win, char *str)
410 {
411     static char logbuf[LOGBUF_NUM][LOGBUF_LEN] = {0};
412     static int  index = 0;
413     
414     strcpy(logbuf[index], str);
415     
416     int i = 0;
417     for (; i < LOGBUF_NUM; ++i) {
418         cleanline(win, i+11);
419         mvwprintw(win, i+11, logbuf[(index+i) % LOGBUF_NUM]);
420         wrefresh(win);
421     }
422     
423     index = (index + LOGBUF_NUM - 1% LOGBUF_NUM;
424 }
425 
426 void cleanline(WINDOW *win, int y, int x)
427 {
428     char EMPTYLINE[LOGBUF_LEN] = {0};
429     memset(EMPTYLINE, ' ', LOGBUF_LEN-1);
430     
431     mvwprintw(win, y, x, EMPTYLINE);
432     wrefresh(win);
433 }

 

 我在ubuntu10.04下面测试过。

编译方法:

cc -o snake filename.c -lncurses 

 

 

 

评论: 2 查看评论 发表评论

百度期待您的加盟


最新新闻:
· 微软不为外界所知的十件趣事(2010-07-18 22:58)
· 中国第2季搜索引擎市场规模达26亿 百度破70%(2010-07-18 22:54)
· Facebook用户数下周达5亿 邀请用户共享故事(2010-07-18 22:49)
· 开源的可视化编辑器 KindEditor 3.5.1 发布(2010-07-18 22:35)
· WordPress 陷入开源‘边界’之争(2010-07-18 17:47)

编辑推荐:揭秘Facebook背后的那些软件

网站导航:博客园首页  个人主页  新闻  闪存  小组  博问  社区  知识库

转载于:https://www.cnblogs.com/lixyvip/archive/2010/07/18/1780391.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/495845.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Linux 的 diff 命令

读懂 diff&#xff1a;http://www.ruanyifeng.com/blog/2012/08/how_to_read_diff.html 菜鸟教程&#xff1a;https://www.runoob.com/linux/linux-comm-diff.html diff 命令详解&#xff1a;https://www.cnblogs.com/wf-linux/p/9488257.htmlhttp://man.linuxde.net/diffhttp…

机器人大潮中暗藏多少伪命题

来源&#xff1a;中国青年报摘要&#xff1a;伴随着巨大的产业浪潮&#xff0c;一种担忧在人群中弥漫&#xff0c;即机器人的“步伐”如此之快&#xff0c;未来究竟会否抢走人类的饭碗&#xff0c;和人类之间爆发一场就业战争&#xff0c;进而夺走人类的一切&#xff1f;2018 R…

哈佛医学院解析:触发医学深度学习系统受到「对抗攻击」的诱因有哪些?

原文来源&#xff1a;arXiv作者&#xff1a;Samuel G. Finlayson、Isaac S. Kohane、Andrew L. Beam「雷克世界」编译&#xff1a;EVA对抗样本的发现引起了人们对深度学习系统的实际部署的关注。在本文中&#xff0c;我们认为&#xff0c;就货币激励和技术脆弱性&#xff08;mo…

Git 详解 和 廖雪峰 Git 教程

转载&#xff1a;廖雪峰 git 教程&#xff1a;https://www.liaoxuefeng.com/wiki/896043488029600 GitHub 秘籍&#xff1a;https://github.com/tiimgreen/github-cheat-sheet/blob/master/README.zh-cn.md Git Community Book 中文版&#xff1a;http://gitbook.liuhui998.c…

ASP.NET MVC: 构建不带 Web 窗体的 Web 应用程序(转载)

我 从事专业开发迄今为止已有 15 年&#xff0c;在此之前&#xff0c;我利用业余时间从事开发至少也有 10 年了。与我这一代的大多数人一样&#xff0c;我是从 8 位计算机起步&#xff0c;然后转用 PC 平台的。随着计算机的复杂性日益增加&#xff0c;我编写的应用程序涵盖了从…

2018人工智能前沿报告:深度学习的应用和价值

来源&#xff1a; 199IT互联网数据中心摘要&#xff1a;报告重点强调了前沿AI技术的应用范围之广&#xff0c;以及经济潜力之盛&#xff0c;也提到了发展中的一些局限和挑战。报告包含400个应用案例&#xff0c;横跨19个行业的9种业务功能。报告重点强调了前沿AI技术的应用范围…

跟我学Telerik公司的RadControls控件(四)

朋友们、同行们通过前面《跟我学Telerik公司的RadControls控件》系列三篇的学习&#xff0c;你一定会内心有一种涌动&#xff0c;有种相见&#xff08;RadControls&#xff09;恨晚的感觉。那就和晓军一起加入学习RadControls控件的行列&#xff0c;为IT的朋友提供更加明了化的…

puppeteer( Nodejs 版 selenium )快速入门

From&#xff1a;https://www.cnblogs.com/CyLee/p/9310839.html puppeteer 官网&#xff1a;https://pptr.dev/ Puppeteer 中文文档 &#xff08;与官方同步更新&#xff09;&#xff1a;https://segmentfault.com/a/1190000015913821 Puppeteer 中文文档 &#xff1a;https…

硅谷人眼中的2018年十大前沿科技预测

来源&#xff1a; 和米资本近日&#xff0c;由斯坦福大学的顶级学术研究团队、美国国防部高级研究计划局、硅谷最具创新力和影响力的创业公司以及和米资本一起精心策划&#xff0c;共同探讨技术将如何重新塑造行业和社会等问题&#xff0c;分析预测了2018年全球十大前沿科技的未…

麦肯锡AI应用报告:深度学习是蓝海还是深坑?

来源&#xff1a;网络大数据AI的价值并不在模型自身&#xff0c;而在于公司怎样用好它们。麦肯锡出品&#xff0c;一份深度学习领域的分析报告&#xff0c;包含400个应用案例&#xff0c;横跨19个行业的9种业务功能。报告重点强调了前沿AI技术的应用范围之广&#xff0c;以及经…

pyppeteer:比 selenium 更高效的爬虫利器

API 接口文档&#xff1a;API Reference&#xff1a;https://miyakogi.github.io/pyppeteer/reference.html pyppeteer github 地址&#xff1a;https://github.com/miyakogi/pyppeteer pyppeteer 英文文档地址&#xff1a;https://miyakogi.github.io/pyppeteer/ pyppeteer…

全球机器学习领域顶尖的16家公司

来源&#xff1a;网络大数据 作者&#xff1a;Andy Patrizio摘要&#xff1a;机器学习是众多公司颇感兴趣的一个新兴领域。本文介绍了几大领先的机器学习公司&#xff0c;包括老牌技术厂商和后起之秀。机器学习是与人工智能一同急剧发展的领域。IDC预测&#xff0c;人工智能和…

突破淘宝对于 selenium 检测

From&#xff1a;https://blog.csdn.net/qq_42196922/article/details/89400988 多加一行代码&#xff0c;突破淘宝模拟登录滑块&#xff1a;http://www.imooc.com/article/285729 爬虫自动化&#xff1a;https://www.jianshu.com/p/b3b92f327374 selenium 跳过 webdriver 检…

18年你需要了解的15个人工智能统计数据

来源&#xff1a;网络大数据人工智能(AI)每天都在以惊人的速度增长&#xff0c;并且与此同时&#xff0c;围绕着各行业的统计数据也在发生变化。该技术在简化医疗保健行业工作流程方面取得了巨大成功&#xff0c;减少了教育部门行政任务的工时&#xff0c;同时也降低了制造业的…

Python GUI 开发工具

Python Tkinter教程&#xff08;GUI图形界面开发教程&#xff09;&#xff1a;http://c.biancheng.net/python/tkinter/ PyQt5教程&#xff1a;http://code.py40.com/face 作为 Pyhon 开发者&#xff0c;我们迟早都会碰到 图形用户界面&#xff08;GUI&#xff09;应用 开发任…

pandas 读写 excel

Python开发 之 Python3读写Excel文件&#xff08;较全&#xff09;&#xff1a;https://blog.csdn.net/u014597198/article/details/83104653 python读取excel&#xff08;Python处理xls&#xff09;&#xff1a;https://blog.csdn.net/chenggong2dm/article/details/44956805…

7张图了解2018物联网产业发展新趋势

来源&#xff1a;硅谷动力 作者&#xff1a;文乾摘要&#xff1a;物联网其本质上是互联网的延伸&#xff0c;利用以传感器为主的嵌入式计算机系统进行各终端之间的彼此数据交互。本篇文章用7张图片讲述了物联网应用的各个领域。随着互联网红利逐渐消失&#xff0c;“Interne…

安装 Python 包时解决 Microsoft visual c++ 14.0 is required 问题

参考&#xff1a;http://www.hongweipeng.com/index.php/archives/1532/ 在 windows 上安装 scrapy 时经常会遇到这个问题&#xff0c;安装其他组件也可能会遇到。但问题解决办法都是大致相同的。 如&#xff1a;pip install scrapy 时出现&#xff1a;error: Microsoft Visua…

硅基光电子芯片:换道超车的核心技术

来源&#xff1a;光电子先导院 作者&#xff1a;周治平2018年4月16日&#xff0c;美国商务部激活了对中兴通讯的拒绝令&#xff0c;禁止美国公司向中兴通讯销售任何零部件、商品、软件和技术&#xff0c;直到2025年3月13日。这一禁令立刻使中兴通讯业务陷入休克状态&#xff…

AI虚拟偶像:知识图谱赋予AI“生命感”

来源&#xff1a;脑极体AI是个非常有趣的词&#xff0c;不管是中文翻译的&#xff0c;还是英文的Artificial Intelligence&#xff0c;都有“生物性”的含义。一个是集结了地球顶尖智慧的“人工”&#xff0c;另一个Intelligence则专指生物拥有的智慧。不过在当今的AI风潮中&am…