zoukankan      html  css  js  c++  java
  • 分享自己写的一个贪吃蛇的游戏(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背后的那些软件

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

  • 相关阅读:
    如何闪开安装VS2013必须要有安装IE10的限制
    Java从键盘输入
    Java基本数据类型和关键字
    openssl windows编译 32位&64位
    eclipse代码提示配置
    手动启动Android模拟器
    Android编程中的实用快捷键
    pat1023. Have Fun with Numbers (20)
    pat1022. Digital Library (30)
    pat1020. Tree Traversals (25)
  • 原文地址:https://www.cnblogs.com/lixyvip/p/1780391.html
Copyright © 2011-2022 走看看