• 博客园logo
  • 会员
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录
FightingForWorldFinal
博客园    首页    新随笔    联系   管理    订阅  订阅

贪吃蛇

  1 #include <stdio.h>
  2 #include <conio.h>
  3 #include <stdlib.h>
  4 #include <windows.h>
  5 #include <time.h>
  6 #define MAX__X 23
  7 #define MAX__Y 50
  8 #define MAX_FOOD 50
  9 #define ESC 27
 10 #define SPACE 32
 11 
 12 typedef struct Node
 13 {
 14     int x;
 15     int y;
 16     struct Node *next;
 17 } Node,*LinkList;
 18 
 19 typedef struct
 20 {
 21     LinkList front;
 22     LinkList rear;
 23     int length;
 24 } Queue;
 25 
 26 Queue snake;
 27 
 28 void gotoxy(int x,int y)//坐标定位
 29 {
 30     COORD loc;
 31     loc.X  =  y;
 32     loc.Y  =  x;
 33     SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), loc);
 34 }
 35 
 36 void help_info()//显示帮助信息
 37 {
 38     gotoxy(8,55);
 39     puts("按ESC键退出,空格键暂停:");
 40     gotoxy(10,55);
 41     puts("上,下,左,右:w,s,a,d");
 42     gotoxy(12,55);
 43     puts("蛇越长,速度也会越快:");
 44     gotoxy(14,55);
 45     puts("如无法控制蛇,请关闭");
 46     gotoxy(15,56);
 47     puts("大写键盘锁定状态:");
 48 }
 49 
 50 void game_info()//显示游戏信息
 51 {
 52     gotoxy(3,60);
 53     printf("当前蛇长度: %d",snake.length);
 54     gotoxy(5,60);
 55     printf("               ");
 56     gotoxy(5,60);
 57     printf("离胜利还差: %d",MAX_FOOD-snake.length);
 58 }
 59 
 60 void enqueue(int x,int y)//入队
 61 {
 62     LinkList p;
 63     p = (LinkList)malloc(sizeof(Node));
 64     p->x = x;
 65     p->y = y;
 66     snake.rear->next = p;
 67     snake.rear = p;
 68     p->next = NULL;
 69     snake.length++;
 70 }
 71 
 72 void dequeue()//出队
 73 {
 74     LinkList p = snake.front;
 75     //保存食物位置
 76     p->next->x = p->x;
 77     p->next->y = p->y;
 78     snake.front = snake.front->next;
 79     snake.length--;
 80     free(p);
 81 }
 82 
 83 void destroy_queue()//销毁队列
 84 {
 85     LinkList p;
 86     while(p = snake.front)
 87     {
 88         snake.front = snake.front->next;
 89         free(p);
 90     }
 91 }
 92 
 93 void snake_init()//初始化蛇,rear指向蛇头,front指向食物,front->next指向蛇尾
 94 {
 95     int i;
 96     snake.rear = snake.front = (LinkList)malloc(sizeof(Node));
 97     snake.rear->next = NULL;
 98     snake.length = 0;
 99     for(i = 0; i < 3; i++)
100     {
101         enqueue(1,i + 1);
102     }
103 }
104 
105 void show_food()//随机化食物位置
106 {
107     LinkList p;
108     srand(time(NULL));//初始化随机种子
109     while(1)
110     {
111         snake.front->x = rand() % (MAX__X-1) + 1;
112         snake.front->y = rand() % (MAX__Y-1) + 1;
113         p = snake.front->next;
114         //防止食物出现在蛇内部
115         while(p)
116         {
117             if(snake.front->x == p->x && snake.front->y == p->y)
118             {
119                 break;
120             }
121             else
122             {
123                 p = p->next;
124             }
125         }
126         if(!p)
127         {
128             break;
129         }
130     }
131     gotoxy(snake.front->x,snake.front->y);
132     putchar('@');//食物
133 }
134 
135 int judge()//判断失败与否
136 {
137     LinkList p;
138     if(snake.length >= MAX_FOOD)
139     {
140         system("cls");
141         gotoxy(4,20);
142         puts("恭喜你,赢了!!!");
143         exit(0);
144     }
145     //碰到自身
146     p = snake.front->next;
147     while(snake.rear !=  p)
148     {
149         if(snake.rear->x == p->x && snake.rear->y == p->y)
150         {
151             break;
152         }
153         else
154         {
155             p = p->next;
156         }
157     }
158     if(snake.rear == p)
159     {
160         //碰到边界
161         if(snake.rear->x >= 1 && snake.rear->y >= 1 && snake.rear->x < MAX__X && snake.rear->y < MAX__Y)
162         {
163             return 1;
164         }
165     }
166     system("cls");
167     gotoxy(4,20);
168     puts("GAME OVER!!!");
169     destroy_queue();
170     getch();
171     exit(0);
172 }
173 
174 void drow_wall()//画墙
175 {
176     int i;
177     for(i = 0; i <= MAX__Y; i++)
178     {
179         gotoxy(0,i);
180         putchar('W');
181         gotoxy(MAX__X,i);
182         putchar('M');
183         if(i <= MAX__X)
184         {
185             gotoxy(i,0);
186             putchar('I');
187             gotoxy(i,MAX__Y);
188             putchar('I');
189         }
190     }
191 }
192 
193 void drow_snake(int i)//0表示画蛇头,1表示画蛇身
194 {
195     LinkList p;
196     p = snake.rear;
197     gotoxy(p->x,p->y);
198     if(i)
199     {
200         putchar('*');    //蛇身
201     }
202     else
203     {
204         putchar('%');    //蛇头
205     }
206 }
207 
208 void clear_snake_tail()
209 {
210     LinkList p = snake.front->next;
211     gotoxy(p->x,p->y);
212     putchar(' ');//清除旧蛇尾
213     p = p->next;
214     gotoxy(p->x,p->y);
215     putchar('~');//添加新蛇尾
216 }
217 
218 void snake_auto_move(char temp)//实现蛇的自动移动
219 {
220     int x,y,speed;
221     do
222     {
223         clear_snake_tail();
224         drow_snake(1);//画蛇身
225         x = snake.rear->x;
226         y = snake.rear->y;
227         switch(temp)
228         {
229             case 'w':
230                 x--;
231                 break;
232             case 's':
233                 x++;
234                 break;
235             case 'a':
236                 y--;
237                 break;
238             case 'd':
239                 y++;
240         }
241         enqueue(x,y);//新蛇头入队
242         if(snake.front->x == x && snake.front->y == y) //蛇捕捉到食物后,食物重新随机化
243         {
244             game_info();
245             show_food();
246         }
247         else
248         {
249             dequeue();    //旧蛇尾出队
250         }
251         drow_snake(0);//画蛇头
252         speed = -2.3 * snake.length + 157;
253         Sleep(speed);//程序暂停speed个单位毫秒
254     }
255     while(!_kbhit() && judge()); //_kbhit为检测键盘输入
256 }
257 
258 void snake_move()//实现玩家控制蛇的移动
259 {
260     char c,pause;
261     static char temp = 0;//静态局部变量
262     pause = 0;
263     if(!temp)  //一开始的时候让蛇先自动移动
264     {
265         temp = 'd';
266         snake_auto_move(temp);
267     }
268     while(1)
269     {
270         c = getch();
271         if(c == ESC) //退出
272         {
273             system("cls");
274             puts("游戏退出成功!");
275             system("pause");
276             destroy_queue();
277             exit(0);
278         }
279         if(pause == SPACE)
280         {
281             if(c == SPACE) //再按下空格键继续游戏
282             {
283                 pause = 0;
284                 gotoxy(6,20);
285                 printf("           ");//消除~~Pause~~:
286                 snake_auto_move(temp);
287             }
288             continue;
289         }
290         if(c == SPACE) //按空格键暂停游戏
291         {
292             pause = SPACE;
293             gotoxy(6,20);
294             printf("~~Pause~~:");
295             continue;
296         }
297         if(c == 'w' || c == 'a' || c == 's' || c == 'd')
298         {
299             if((temp == 'w' && c == 's') || (temp == 's' && c == 'w') || (temp == 'd' && c == 'a') || (temp == 'a' && c == 'd')) //不允许连续的两次内按相反的键
300             {
301                 snake_auto_move(temp);
302                 continue;
303             }
304             break;
305         }
306         snake_auto_move(temp);
307     }
308     temp = c;
309     snake_auto_move(temp);
310 }
311 
312 int main()
313 {
314     help_info();
315     snake_init();
316     show_food();
317     drow_wall();
318     game_info();
319     while(judge())
320     {
321         snake_move();
322     }
323     return 0;
324 }
View Code

 

posted @ 2013-08-16 22:50  Sky-J  阅读(233)  评论(0)    收藏  举报
刷新页面返回顶部
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3