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

修复了前一篇的bug, 可以算是完整版.

没有设立game over的条件(容易, 但不想做这个), 实现了自己咬断自己的功能~

上代码~

  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 /* mseconds 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 void set_frame();
 33 void free_tail();
 34 
 35 void show() {
 36     update_snack();
 37     erase();
 38 
 39     set_frame();
 40     /* show food */
 41     move(fd->x, fd->y);
 42     printw("o");
 43     /* show snack */
 44     snack* p;
 45     for (p = tail; p != NULL; p = p->next) {
 46         move(p->x, p->y);
 47         printw("@");
 48     }
 49 
 50     refresh();
 51 }
 52 
 53 int set_timer() {
 54     long usec = MSEC * 1000;
 55 
 56     struct itimerval my_timerval;
 57     my_timerval.it_interval.tv_sec = 0;
 58     my_timerval.it_interval.tv_usec = usec;
 59     my_timerval.it_value.tv_sec = 0;
 60     my_timerval.it_value.tv_usec = usec;
 61     
 62     return setitimer(ITIMER_REAL, &my_timerval, 0);
 63 }
 64 
 65 void init_game() {
 66     cbreak();
 67     noecho();
 68     curs_set(0);
 69     srand(time(0));
 70 
 71     direction = 'w';
 72     tail = (snack*) malloc(sizeof(snack));
 73     head = (snack*) malloc(sizeof(snack));
 74     fd = (food*) malloc(sizeof(food));
 75     /* set_snack */
 76     tail->x = LENGTH / 2;
 77     tail->y = WIDTH / 2;
 78     tail->next = NULL; 
 79     head = tail;
 80 
 81     set_food();
 82     set_timer();
 83 }
 84 
 85 void set_food() {
 86     int x0, y0;
 87     /*
 88     x0 = rand() % LENGTH;
 89     y0 = rand() % WIDTH;
 90     */
 91     int in_snack = 0;
 92     do {
 93         x0 = rand() % LENGTH;
 94         y0 = rand() % WIDTH;
 95         
 96         snack* p;
 97         for (p = tail; p != NULL; p = p->next) {
 98             if ((x0 == p->x) && (y0 == p->y)) {
 99                 in_snack = 1;
100                 break;
101             }
102         }
103     } while (in_snack);
104 
105     fd->x = x0;
106     fd->y = y0;
107 }
108 
109 void get_order() {
110     char ch;
111 
112     while (1) {
113         ch = getchar();
114         if (('w' == direction) || ('s' == direction)) {
115             switch (ch) {
116                 case 'a': 
117                     direction = 'a';
118                     break;
119                 case 'd': 
120                     direction = 'd';
121                     break;
122                 default:
123                     break;
124             }
125         } else {
126             switch (ch) {
127                 case 'w':
128                     direction = 'w';
129                     break;
130                 case 's':
131                     direction = 's';
132                     break;
133                 default:
134                     break;
135             }
136         }
137     }
138 }
139 
140 void update_snack() {
141     head->next = (snack*) malloc(sizeof(snack));
142     int temp_x = head->x;
143     int temp_y = head->y;
144 
145     head = head->next;
146     head->x = temp_x;
147     head->y = temp_y;
148     head->next = NULL;
149     switch (direction) {
150         case 'w':
151             head->x -= 1;
152             break;
153         case 'a':
154             head->y -= 1;
155             break;
156         case 's':
157             head->x += 1;
158             break;
159         case 'd':
160             head->y += 1;
161             break;
162         default:
163             break;
164     }
165     if (head->x < 0) {
166         head->x += (LENGTH + 1);
167     } else if (head->x > LENGTH) {
168         head->x = head->x % LENGTH;
169     }
170     if (head->y < 0) {
171         head->y += (WIDTH + 1);
172     } else if (head->y >WIDTH) {
173         head->y = head->y % WIDTH; 
174     }
175     
176     if ((head->x != fd->x) || (head->y != fd->y)) {
177         free_tail();
178     } else { /* meet food */
179         set_food();
180     } 
181 
182     snack* p;
183     for (p = tail; p != head; p = p->next) {
184         if ((p->x == head->x) && (p->y == head->y)) {
185             while (tail != p->next)
186                 free_tail(); /* delete tail to p->next */
187         }
188     }    
189 }
190 
191 void set_frame() {
192     int i, j;
193     
194     for (i = 0; i <= LENGTH; i++) {
195         move(i, 0);
196         printw("|");
197         move(i, WIDTH);
198         printw("|");
199     }
200     for (j = 0; j <= WIDTH; j++) {
201         move(0, j);
202         printw("_");
203         move(LENGTH, j);
204         printw("_");
205     }
206 }
207 
208 void free_tail() {
209     snack* temp;
210     temp = tail;
211     tail = tail->next;
212     free(temp);
213     temp = NULL;
214 }
215 
216 int main() {
217     initscr(); 
218     init_game();
219     signal(SIGALRM, show);
220     get_order();
221     endwin(); 
222     
223     return 0;
224 }
posted @ 2012-04-29 10:55  leaforestd  阅读(206)  评论(0编辑  收藏  举报