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 }