分享自己写的一个贪吃蛇的游戏(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-1,?2,?"?Level:?%d?",?g_level);
181?????????mvwprintw(win,?GAMEWIN_YLEN-1,?30,?"?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->y?=?hy?-?1;
212?????????psnake->head->x?=?hx;
213?????????break;
214?????
215?????case?DIR_DOWN:
216?????????psnake->head->y?=?hy?+?1;
217?????????psnake->head->x?=?hx;
218?????????break;
219?????
220?????case?DIR_LEFT:
221?????????psnake->head->y?=?hy;
222?????????psnake->head->x?=?hx?-?1;
223?????????break;
224?????
225?????case?DIR_RIGHT:
226?????????psnake->head->y?=?hy;
227?????????psnake->head->x?=?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->y?<=?0?||?psnake->head->y?>=?GAMEWIN_YLEN
238???????||?psnake->head->x?<=?0?||?psnake->head->x?>=?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->y?==?pnode->y?&&?psnake->head->x?==?pnode->x)
247?????????????return?-1;
248?
249?????if?(psnake->head->y?==?pfood->y?&&?psnake->head->x?==?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->y?=?psnake->head->y?-?1;
262?????????pnode->x?=?psnake->head->x;
263?????????break;
264?????
265?????case?DIR_DOWN:
266?????????pnode->y?=?psnake->head->y?+?1;
267?????????pnode->x?=?psnake->head->x;
268?????????break;
269?????
270?????case?DIR_LEFT:
271?????????pnode->y?=?psnake->head->y;
272?????????pnode->x?=?psnake->head->x?-?1;
273?????????break;
274?????
275?????case?DIR_RIGHT:
276?????????pnode->y?=?psnake->head->y;
277?????????pnode->x?=?psnake->head->x?+?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,?1,?3);
300?????box(win,?0,?0);
301?????mvwprintw(win,?0,?2,?"?GAME?");
302?????mvwprintw(win,?GAMEWIN_YLEN-1,?2,?"?Level:?%d?",?g_level);
303?????mvwprintw(win,?GAMEWIN_YLEN-1,?30,?"?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,?4,?50?)->front,?4,?53
320?????????????)->front,?4,?52
321?????????)->front,?4,?51
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?=?y;
331?????(*ppsnode)->x?=?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->y?=?random()?%?(GAMEWIN_YLEN?-?1)?+?1;
379?????????pfood->x?=?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->y?==?pnode->y?&&?pfood->x?==?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?+?2,?3);
402?????box(win,?0,?0);
403?????mvwprintw(win,?0,?2,?"?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+1,?1);
419?????????mvwprintw(win,?i+1,?1,?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
總結
以上是生活随笔為你收集整理的分享自己写的一个贪吃蛇的游戏(Linux)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Source Server + Symb
- 下一篇: [译]How to make searc