zoukankan      html  css  js  c++  java
  • 贪吃蛇

      1 #include <stdio.h>
      2 #include <stdlib.h>
      3 #include <memory.h>
      4 #include <time.h>
      5 #include <signal.h>
      6 
      7 #define WIDTH 10
      8 #define HEIGHT 10
      9 #define SUCCESS 0
     10 #define FAILURE 1
     11 #define EATEN_FOOD 2
     12 #define GAME_OVER 3
     13 
     14 const int width = WIDTH;
     15 const int height = HEIGHT;
     16 static int area[WIDTH][HEIGHT];
     17 
     18 #define CHECK_FALSE_RET(expr, ret) if(!(expr)) return ret;
     19 
     20 #define LOG(format, ...) //printf(format, ##__VA_ARGS__)
     21 
     22 typedef enum Direct {
     23     NO_DIRECT,
     24     UP,
     25     DOWN,
     26     LEFT,
     27     RIGHT
     28 }Direct;
     29 
     30 typedef struct Point {
     31     int x;
     32     int y;
     33     Point *next;
     34 }Point;
     35 
     36 typedef struct Snake {
     37     Point *head;
     38     Point *tail;
     39     int length;
     40     Direct direct;
     41 }Snake;
     42 
     43 Point* NewPoint()
     44 {
     45     Point *np = (Point*)malloc(sizeof(Point));
     46     if(np != NULL)
     47     {
     48         memset(np, 0, sizeof(Point));
     49     }
     50     return np;
     51 }
     52 
     53 Point* NewPointWithParam(int x, int y)
     54 {
     55     Point *np = NewPoint();
     56     if(np != NULL)
     57     {
     58         np->x = x;
     59         np->y = y;
     60     }
     61     return np;
     62 }
     63 
     64 Direct DecideForwardDirect(Snake *snake, Point *food)
     65 {
     66     if(snake == NULL || food == NULL)
     67     {
     68         LOG("[error]: DecideForwardDirect failed. snake=NULL|food=NULL
    ");
     69          return NO_DIRECT;
     70     }
     71     Direct dir = NO_DIRECT;
     72     Point *head = snake->head;
     73     if(head == NULL) 
     74     {
     75         LOG("[error]: DecideForwardDirect failed. head=NULL
    ");
     76         return NO_DIRECT;
     77     }
     78     
     79     switch(snake->direct)
     80     {
     81         case UP:
     82             if(head->x == 0) dir = RIGHT;
     83             else if(head->x == width-2) dir = LEFT;
     84             break;
     85         case DOWN:
     86             if(head->x == width - 1)
     87             {
     88                 if(head->y == height - 1) dir = LEFT;
     89                 else dir = DOWN;
     90             }
     91             break;
     92         case LEFT:
     93             if(head->x == 0) dir = UP;
     94             else dir = LEFT;
     95             break;
     96         case RIGHT:
     97             if(head->y == 0 && head->x == width - 1) dir = DOWN;
     98             else if(head->y != 0 && head->x == width - 2) dir = UP;
     99             else dir = RIGHT;
    100             break;
    101         default:
    102             break;
    103     }
    104     snake->direct = dir;
    105     return dir;
    106 }
    107 
    108 Point *CreateOneFood(Snake *snake)
    109 {    
    110     if(snake == NULL) return NULL;
    111  
    112     Point *np = NULL;
    113     Point *food = NULL;
    114     int unusedNum = width*height - snake->length;
    115     int randPos;
    116     int x, y;
    117     int foodX = -1, foodY = -1;
    118     memset(area, 0, width*height*sizeof(int));
    119     np = snake->head;
    120     while(np != NULL)
    121     {
    122         area[np->x][np->y] = 1;
    123         np = np->next;
    124     }
    125     randPos = rand() % unusedNum;
    126     for(x=0; x<width; x++)
    127     {
    128         if(randPos < 0) break;
    129         for(y=0; y<height; y++)
    130         {
    131             if(area[x][y] == 0) randPos--;
    132             if(randPos < 0)
    133             {
    134                 foodX = x;
    135                 foodY = y;
    136                 break;
    137             }
    138         }
    139     }
    140 
    141     if((foodX >= 0 && foodX < width) && (foodY >= 0 && foodY < height))
    142     {
    143         food = NewPointWithParam(foodX, foodY);
    144     }
    145     
    146     return food;
    147 }
    148 
    149 int FortainEatFood(Snake *snake, Point *food)
    150 {
    151     if(snake == NULL || food == NULL) return FAILURE;
    152     food->next = snake->head;
    153     snake->head = food;
    154     if(snake->tail == NULL) snake->tail = food;
    155     snake->length++;
    156     return SUCCESS;
    157 }
    158 
    159 Point *GetPreviousTail(Snake *snake)
    160 {
    161     if(snake == NULL) return NULL;
    162     Point *np = snake->head;
    163      while(np->next != snake->tail && np->next != NULL) np = np->next;
    164     if(np->next == NULL) return NULL;
    165     return np;
    166 }
    167 
    168 
    169 int FortainForward(Snake *snake, Direct dir, Point *food)
    170 {
    171     if(snake == NULL) return FAILURE;
    172     if(dir == NO_DIRECT) return FAILURE;
    173     if(food == NULL) return FAILURE;
    174     Point *preTail;
    175     preTail = GetPreviousTail(snake);
    176     if(preTail == NULL) return FAILURE;
    177     int currX = snake->head->x;
    178     int currY = snake->head->y;
    179     int nextX = currX;
    180     int nextY = currY;
    181     
    182     switch(dir)
    183     {
    184         case UP:
    185             nextY = currY - 1;
    186             break;
    187         case DOWN:
    188             nextY = currY + 1;
    189             break;
    190         case LEFT:
    191             nextX = currX - 1;
    192             break;
    193         case RIGHT:
    194             nextX = currX + 1;
    195         default:
    196             break;
    197     }
    198     if(nextX == food->x && nextY == food->y)
    199     {
    200         FortainEatFood(snake, food);
    201         return EATEN_FOOD;
    202     }
    203     else
    204     {
    205         snake->tail->x = nextX;
    206         snake->tail->y = nextY;
    207         snake->tail->next = snake->head;
    208         snake->head = snake->tail;
    209         snake->tail = preTail;
    210         snake->tail->next = NULL;
    211     }
    212     
    213     return SUCCESS;
    214 }
    215 
    216 int FortainGameInit(Snake *snake)
    217 {
    218     if(snake == NULL) return FAILURE;
    219     Point *np1 = NewPointWithParam(width-1, height-1);
    220     Point *np2 = NewPointWithParam(width-2, height-1);
    221     Point *np3 = NewPointWithParam(width-3, height-1);
    222     if(np1 == NULL || np2 == NULL || np3 == NULL) return FAILURE;
    223     
    224     FortainEatFood(snake, np1);
    225     FortainEatFood(snake, np2);
    226     FortainEatFood(snake, np3);
    227 
    228     snake->direct = LEFT;
    229     return SUCCESS;
    230 }
    231 
    232 int FortainGameCheck(Snake *snake)
    233 {
    234     if(snake == NULL) return FAILURE;
    235     memset(area, 0, width*height*sizeof(int));
    236     Point *np = snake->head;
    237     while(np != NULL)
    238     {
    239         CHECK_FALSE_RET(np->x >= 0, FAILURE);
    240         CHECK_FALSE_RET(np->x < width, FAILURE);
    241         CHECK_FALSE_RET(np->y >= 0, FAILURE);
    242         CHECK_FALSE_RET(np->y < height, FAILURE);
    243 
    244         CHECK_FALSE_RET(area[np->x][np->y] == 0, GAME_OVER);
    245         area[np->x][np->y] = 1;
    246         np = np->next;
    247     }
    248     CHECK_FALSE_RET(snake->length != width*height, GAME_OVER);
    249     return SUCCESS;
    250 }
    251 
    252 void FortainGameMain()
    253 {
    254     Snake snake;
    255     Point *food;
    256     int ret;
    257     int count = 0;
    258     Direct dir;
    259 
    260     memset(&snake, 0, sizeof(Snake));
    261     ret = FortainGameInit(&snake);
    262     if(ret == FAILURE) 
    263     {
    264         LOG("[error]: GameInit failed!
    ");
    265         return;
    266     }
    267     LOG("[info]: GameInit done! length=%d
    ", snake.length);
    268     
    269     Point *np = snake.head;
    270     while(np != NULL)
    271     {
    272         LOG("x=%d,y=%d,next=%x
    ", np->x, np->y, np->next);
    273         np = np->next;
    274     }
    275     
    276     food = CreateOneFood(&snake);
    277     if(food == NULL) LOG("[error]: CreateFood failed!
    ");
    278     else LOG("[info]: CreateFood success! P(%d, %d)
    ", food->x, food->y);
    279     while(true)
    280     {
    281         dir = DecideForwardDirect(&snake, food);
    282         LOG("[info]: DecideDirect, dir=%d
    ", dir);
    283         ret = FortainForward(&snake, dir, food);
    284         LOG("[info]: Forward, dir=%d, food=(%d,%d), head=(%d,%d), length=%d
    ", dir, food->x, food->y, snake.head->x, snake.head->y, snake.length);
    285         if(ret == FAILURE)
    286         {
    287             LOG("[error]: Forward failed.dir|%d,length|%d.
    ", dir, snake.length);
    288             break;
    289         }
    290         else if(ret == EATEN_FOOD)
    291         {
    292             LOG("[info]: Eat food. length|%d
    ", snake.length);
    293             if(snake.length < width*height)
    294             {
    295                 food = CreateOneFood(&snake);
    296                 if(food == NULL)
    297                 {
    298                     LOG("[error]: CreateFood failed!
    ");
    299                     break;
    300                 }
    301                 else LOG("[info]: CreateFood success! P(%d, %d)
    ", food->x, food->y);
    302             }
    303         }
    304         ret = FortainGameCheck(&snake);
    305         if(ret == FAILURE)
    306         {
    307             LOG("[error]: GameCheck failed!
    ");
    308             break;
    309         }
    310         else if(ret == GAME_OVER)
    311         {
    312             printf("[info]: Game over!!! length=%d, count=%d
    ", snake.length, count);
    313             break;
    314         }
    315         count++;
    316     }
    317 }
    318 
    319 void SignHandler(int sign)
    320 {
    321     switch(sign)
    322     {
    323         case SIGABRT:
    324             printf("signal: SIGABRT. 
     程序异常终止。
    ");
    325             break;
    326         case SIGFPE:
    327             printf("signal: SIGFPE. 
     算术运算出错,如除数为 0 或溢出(不一定是浮点运算)。
    ");
    328             break;
    329         case SIGILL:
    330             printf("signal: SIGILL. 
     非法函数映象,如非法指令,通常是由于代码中的某个变体或者尝试执行数据导致的。
    ");
    331             break;
    332         case SIGINT:
    333             printf("signal: SIGINT. 
     中断信号,如 ctrl-C,通常由用户生成。
    ");
    334             break;
    335         case SIGSEGV:
    336             printf("signal: SIGSEGV. 
     非法访问存储器,如访问不存在的内存单元。
    ");
    337             break;
    338         case SIGTERM:
    339             printf("signal: SIGTERM. 
     发送给本程序的终止请求信号。
    ");
    340             break;
    341     }
    342 }
    343 
    344 int main()
    345 {
    346     signal(SIGABRT, SignHandler);
    347     signal(SIGFPE, SignHandler);
    348     signal(SIGILL, SignHandler);
    349     signal(SIGINT, SignHandler);
    350     signal(SIGSEGV, SignHandler);
    351     signal(SIGTERM, SignHandler);
    352     for(int i=0; i<100; i++)
    353     {
    354         clock_t start = clock();
    355         srand(time(NULL));
    356         FortainGameMain();
    357         printf("Time: %d ms
    ", clock()-start);
    358     }
    359     return 0;
    360 }
  • 相关阅读:
    MongoDB 释放磁盘空间 db.runCommand({repairDatabase: 1 })
    RK 调试笔记
    RK Android7.1 拨号
    RK Android7.1 移植gt9271 TP偏移
    RK Android7.1 定制化 itvbox 盒子Launcher
    RK Android7.1 双屏显示旋转方向
    RK Android7.1 设置 内存条作假
    RK Android7.1 设置 蓝牙 已断开连接
    RK Android7.1 进入Camera2 亮度会增加
    RK 3128 调触摸屏 TP GT9XX
  • 原文地址:https://www.cnblogs.com/rmthy/p/6404980.html
Copyright © 2011-2022 走看看