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
转载于:https://www.cnblogs.com/Skyxj/p/3263654.html
相关资源:联机贪吃蛇