c实现终端中的贪食蛇(1)

说过想做一个终端中的贪食蛇, 想法出来的时候看了一点, 写了100行左右, 上周基本没动. 这两天又拿来写, 能跑, 但有以下问题:

1) 刷新food时经常会出现food在(0, 0)处的情况, 此时food不能被吃掉.

2) 改变define的WIDTH或LENGTH可能会出现snack不能动.

3) 蛇可以反方向行走.

暂时解决不了, 解决了再发上来. ->解决bug后的完整版本在这里: http://www.cnblogs.com/leaforestd/archive/2012/04/29/2476011.html

注: 结构参考了: http://blog.sina.com.cn/s/blog_4c3b26e10100sd7b.html 

 

code:

  1 #include <stdlib.h>
  2 #include <curses.h>
  3 #include <signal.h>
  4 #include <sys/time.h>
  5 
  6 #define WIDTH 70
  7 #define LENGTH 30
  8 #define MSEC 200 /* msec to refresh screen */
  9 
 10 typedef struct food {
 11     int x;
 12     int y;
 13 } food;
 14                                                                                                                                                 
 15 typedef struct snack {
 16     int x;
 17     int y;
 18     struct snack* next;
 19 } snack;
 20 
 21 food* fd;
 22 snack* tail;
 23 snack* head;
 24 char direction;
 25 
 26 void show();
 27 int set_timer();
 28 void init_game();
 29 void set_food();
 30 void get_order();
 31 void update_snack();
 32 
 33 void show() {
 34     update_snack();
 35     erase();
 36 
 37     /* show food */
 38     move(fd->x, fd->y);
 39     printw("o");
 40     /* show snack */
 41     snack* p;
 42     for (p = tail; p != NULL; p = p->next) {
 43         move(p->x, p->y);
 44         printw("@");
 45     }
 46 
 47     refresh();
 48 }
 49 
 50 int set_timer() {
 51     long usec = MSEC * 1000;
 52 
 53     struct itimerval my_timerval;
 54     my_timerval.it_interval.tv_sec = 0;
 55     my_timerval.it_interval.tv_usec = usec;
 56     my_timerval.it_value.tv_sec = 0;
 57     my_timerval.it_value.tv_usec = usec;
 58     
 59     return setitimer(ITIMER_REAL, &my_timerval, 0);
 60 }
 61 
 62 void init_game() {
 63     cbreak();
 64     noecho();
 65     curs_set(0);
 66     srand((unsigned)time(0));
 67 
 68     /* or segment violation */
 69     tail = (snack*) malloc(sizeof(snack));
 70     head = (snack*) malloc(sizeof(snack));
 71     fd = (food*) malloc(sizeof(food));
 72     /* set_snack */
 73     tail->x = (int) (WIDTH / 2);
 74     tail->y = (int) (LENGTH / 2);
 75     tail->next = NULL;
 76     head = tail;
 77 
 78     set_food();
 79     set_timer();
 80 }
 81 
 82 void set_food() {
 83     int x0, y0;
 84     int in_snack = 0;
 85     do {
 86         x0 = rand() % WIDTH;
 87         y0 = rand() % LENGTH;
 88         
 89         snack* p;
 90         for (p = tail; p != NULL; p = p->next) {
 91             if ((x0 == p->x) && (y0 == p->y)) {
 92                 in_snack = 1;
 93                  /* food in snack, jump out for */ 
 94                 break;
 95             }
 96         }
 97     } while (in_snack);
 98 
 99     fd->x = x0;
100     fd->y = y0;
101 }
102 
103 void get_order() {
104     char ch;
105 
106     while (1) {
107         ch = getchar();
108         switch (ch) {
109             case 'Q':
110                 exit(0);
111             case 'w': 
112                 direction = 'w';
113                 break;
114             case 'a': 
115                 direction = 'a';
116                 break;
117             case 's': 
118                 direction = 's';
119                 break;
120             case 'd': 
121                 direction = 'd';
122                 break;
123             default:
124                 break;
125         }
126     }
127 }
128 
129 void update_snack() {
130     /* head */
131     head->next = (snack*) malloc(sizeof(snack));
132     int hx = head->x;
133     int hy = head->y;
134 
135     head = head->next;
136     head->x = hx;
137     head->y = hy;
138     head->next = NULL;
139     switch (direction) {
140         case 'w':
141             head->x -= 1;
142             break;
143         case 'a':
144             head->y -= 1;
145             break;
146         case 's':
147             head->x += 1;
148             break;
149         case 'd':
150             head->y += 1;
151             break;
152         default:
153             break;
154     }
155     
156     if ((head->x != fd->x) || (head->y != fd->y)) {
157         /* don't eat, delete tail */
158         void* temp = tail;
159         tail = (tail->next? tail->next: head);    
160         free(temp);
161         temp = NULL;
162     } else {
163         /* eaten, refresh food */
164         set_food();
165     } 
166 }
167 
168 int main() {
169     initscr(); 
170     init_game();
171     signal(SIGALRM, show);
172     get_order();
173     endwin(); 
174     
175     return 0;
176 }
posted @ 2012-04-23 20:00  leaforestd  阅读(184)  评论(0编辑  收藏  举报