源代码下载地址为:www.clang.cc
阅读学习了源代码,并做了简单的注释和修改,里面只用了链表数据结构,非常适合C语言入门者学习阅读。
程序可在VS2013下编译运行。
代码语言:javascript复制 1 #include<stdio.h>
2 #include<time.h>
3 #include<windows.h>
4 #include<stdlib.h>
5
6 #define U 1
7 #define D 2
8 #define L 3
9 #define R 4 //蛇的状态,U:上 ;D:下;L:左 R:右
10
11 typedef struct SNAKE //蛇身的一个节点
12 {
13 int x;
14 int y;
15 struct SNAKE *next;
16 }snake;
17
18 //全局变量//
19 int score = 0, add = 10;//总得分与每次吃食物得分。
20 int status, sleeptime = 200;//每次运行的时间间隔
21 snake *head, *food;//蛇头指针,食物指针
22 snake *q;//遍历蛇的时候用到的指针
23 int endGamestatus = 0; //游戏结束的情况,1:撞到墙;2:咬到自己;3:主动退出游戏。
24
25 //声明全部函数//
26 void Pos();
27 void creatMap();
28 void initSnake();
29 int biteSelf();
30 void createFood();
31 void cantCrossWall();
32 void snakeMove();
33 void pause();
34 void runGame();
35 void initGame();
36 void endGame();
37 void gameStart();
38
39 void Pos(int x, int y)//设置光标位置
40 {
41 COORD pos;
42 HANDLE hOutput;
43 pos.X = x;
44 pos.Y = y;
45 hOutput = GetStdHandle(STD_OUTPUT_HANDLE);//返回标准的输入、输出或错误的设备的句柄,也就是获得输入、输出/错误的屏幕缓冲区的句柄
46 SetConsoleCursorPosition(hOutput, pos);
47 }
48
49 void creatMap()//创建地图
50 {
51 int i;
52 for (i = 0; i<58; i = 2)//打印上下边框
53 {
54 Pos(i, 0);
55 printf("■");//一个方块占两个位置
56 Pos(i, 26);
57 printf("■");
58 }
59 for (i = 1; i<26; i )//打印左右边框
60 {
61 Pos(0, i);
62 printf("■");
63 Pos(56, i);
64 printf("■");
65 }
66 }
67
68 void initSnake()//初始化蛇身
69 {
70 snake *tail;
71 int i;
72 tail = (snake*)malloc(sizeof(snake));//从蛇尾开始,头插法,以x,y设定开始的位置//
73 tail->x = 24;
74 tail->y = 5;
75 tail->next = NULL;
76 for (i = 1; i <= 4; i )//初始长度为4
77 {
78 head = (snake*)malloc(sizeof(snake));
79 head->next = tail;
80 head->x = 24 2 * i;
81 head->y = 5;
82 tail = head;
83 }
84 while (tail != NULL)//从头到为,输出蛇身
85 {
86 Pos(tail->x, tail->y);
87 printf("■");
88 tail = tail->next;
89 }
90 }
91 //??
92 int biteSelf()//判断是否咬到了自己
93 {
94 snake *self;
95 self = head->next;
96 while (self != NULL)
97 {
98 if (self->x == head->x && self->y == head->y)
99 {
100 return 1;
101 }
102 self = self->next;
103 }
104 return 0;
105 }
106
107 void createFood()//随机出现食物
108 {
109 snake *food_1;
110 srand((unsigned)time(NULL));//为了防止每次产生的随机数相同,种子设置为time
111 food_1 = (snake*)malloc(sizeof(snake));
112 while ((food_1->x % 2) != 0) //保证其为偶数,使得食物能与蛇头对其
113 {
114 food_1->x = rand() % 52 2;
115 }
116 food_1->y = rand() % 24 1;
117 q = head;
118 while (q->next == NULL)
119 {
120 if (q->x == food_1->x && q->y == food_1->y) //判断蛇身是否与食物重合
121 {
122 free(food_1);
123 createFood();
124 }
125 q = q->next;
126 }
127 Pos(food_1->x, food_1->y);
128 food = food_1;
129 printf("■");
130 }
131
132 void cantCrossWall()//不能穿墙
133 {
134 if (head->x == 0 || head->x == 56 || head->y == 0 || head->y == 26)
135 {
136 endGamestatus = 1;
137 endGame();
138 }
139 }
140
141 void snakeMove()//蛇前进,上U,下D,左L,右R
142 {
143 snake * nexthead;
144 cantCrossWall();
145
146 nexthead = (snake*)malloc(sizeof(snake));
147 if (status == U)
148 {
149 nexthead->x = head->x;
150 nexthead->y = head->y - 1;
151 if (nexthead->x == food->x && nexthead->y == food->y)//如果下一个有食物//
152 {
153 nexthead->next = head;
154 head = nexthead;
155 q = head;
156 while (q != NULL)
157 {
158 Pos(q->x, q->y);
159 printf("■");
160 q = q->next;
161 }
162 score = score add;
163 createFood();
164 }
165 else //如果没有食物//
166 {
167 nexthead->next = head;
168 head = nexthead;
169 q = head;
170 while (q->next->next != NULL)
171 {
172 Pos(q->x, q->y);
173 printf("■");
174 q = q->next;
175 }
176 Pos(q->next->x, q->next->y);
177 printf(" ");
178 free(q->next);
179 q->next = NULL;
180 }
181 }
182 if (status == D)
183 {
184 nexthead->x = head->x;
185 nexthead->y = head->y 1;
186 if (nexthead->x == food->x && nexthead->y == food->y) //有食物
187 {
188 nexthead->next = head;
189 head = nexthead;
190 q = head;
191 while (q != NULL)
192 {
193 Pos(q->x, q->y);
194 printf("■");
195 q = q->next;
196 }
197 score = score add;
198 createFood();
199 }
200 else //没有食物
201 {
202 nexthead->next = head;
203 head = nexthead;
204 q = head;
205 while (q->next->next != NULL)
206 {
207 Pos(q->x, q->y);
208 printf("■");
209 q = q->next;
210 }
211 Pos(q->next->x, q->next->y);
212 printf(" ");
213 free(q->next);
214 q->next = NULL;
215 }
216 }
217 if (status == L)
218 {
219 nexthead->x = head->x - 2;
220 nexthead->y = head->y;
221 if (nexthead->x == food->x && nexthead->y == food->y)//有食物
222 {
223 nexthead->next = head;
224 head = nexthead;
225 q = head;
226 while (q != NULL)
227 {
228 Pos(q->x, q->y);
229 printf("■");
230 q = q->next;
231 }
232 score = score add;
233 createFood();
234 }
235 else //没有食物
236 {
237 nexthead->next = head;
238 head = nexthead;
239 q = head;
240 while (q->next->next != NULL)
241 {
242 Pos(q->x, q->y);
243 printf("■");
244 q = q->next;
245 }
246 Pos(q->next->x, q->next->y);
247 printf(" ");
248 free(q->next);
249 q->next = NULL;
250 }
251 }
252 if (status == R)
253 {
254 nexthead->x = head->x 2;
255 nexthead->y = head->y;
256 if (nexthead->x == food->x && nexthead->y == food->y)//有食物
257 {
258 nexthead->next = head;
259 head = nexthead;
260 q = head;
261 while (q != NULL)
262 {
263 Pos(q->x, q->y);
264 printf("■");
265 q = q->next;
266 }
267 score = score add;
268 createFood();
269 }
270 else //没有食物
271 {
272 nexthead->next = head;
273 head = nexthead;
274 q = head;
275 while (q->next->next != NULL)
276 {
277 Pos(q->x, q->y);
278 printf("■");
279 q = q->next;
280 }
281 Pos(q->next->x, q->next->y);
282 printf(" ");
283 free(q->next);
284 q->next = NULL;
285 }
286 }
287 if (biteSelf() == 1) //判断是否会咬到自己
288 {
289 endGamestatus = 2;
290 endGame();
291 }
292 }
293
294 void pause()//暂停
295 {
296 while (1)
297 {
298 Sleep(300);
299 if (GetAsyncKeyState(VK_SPACE))
300 {
301 break;
302 }
303
304 }
305 }
306
307 void runGame()//控制游戏
308 {
309
310 Pos(64, 15);
311 printf("不能穿墙,不能咬到自己n");
312 Pos(64, 16);
313 printf("用↑.↓.←.→分别控制蛇的移动.");
314 Pos(64, 17);
315 printf("F1 为加速,F2 为减速n");
316 Pos(64, 18);
317 printf("ESC :退出游戏.space:暂停游戏.");
318 Pos(64, 20);
319 printf("C语言研究中心 www.clang.cc");
320 status = R;
321 while (1)
322 {
323 Pos(64, 10);
324 printf("得分:%d ", score);
325 Pos(64, 11);
326 printf("每个食物得分:%d分", add);
327 if (GetAsyncKeyState(VK_UP) && status != D)
328 {
329 status = U;
330 }
331 else if (GetAsyncKeyState(VK_DOWN) && status != U)
332 {
333 status = D;
334 }
335 else if (GetAsyncKeyState(VK_LEFT) && status != R)
336 {
337 status = L;
338 }
339 else if (GetAsyncKeyState(VK_RIGHT) && status != L)
340 {
341 status = R;
342 }
343 else if (GetAsyncKeyState(VK_SPACE))
344 {
345 pause();
346 }
347 else if (GetAsyncKeyState(VK_ESCAPE))
348 {
349 endGamestatus = 3;
350 break;
351 }
352 else if (GetAsyncKeyState(VK_F1))
353 {
354 if (sleeptime >= 50)
355 {
356 sleeptime = sleeptime - 30;
357 add = add 2;
358 if (sleeptime == 320)
359 {
360 add = 2;//防止减到1之后再加回来有错
361 }
362 }
363 }
364 else if (GetAsyncKeyState(VK_F2))
365 {
366 if (sleeptime<350)
367 {
368 sleeptime = sleeptime 30;
369 add = add - 2;
370 if (sleeptime == 350)
371 {
372 add = 1; //保证最低分为1
373 }
374 }
375 }
376 Sleep(sleeptime);
377 snakeMove();
378 }
379 }
380
381 void initGame()//开始界面
382 {
383 Pos(40, 12);
384
385 system("title C语言研究中心 www.clang.cc");
386 printf("欢迎来到贪食蛇游戏!");
387 Pos(40, 25);
388 printf(" C语言研究中心 www.clang.cc.n");
389 system("pause");
390 system("cls");
391 Pos(25, 12);
392 printf("用↑.↓.←.→分别控制蛇的移动, F1 为加速,2 为减速n");
393 Pos(25, 13);
394 printf("加速将能得到更高的分数。n");
395 system("pause");
396 system("cls");
397 }
398
399 void endGame()//结束游戏
400 {
401
402 system("cls");
403 Pos(24, 12);
404 if (endGamestatus == 1)
405 {
406 printf("对不起,您撞到墙了。游戏结束.");
407 }
408 else if (endGamestatus == 2)
409 {
410 printf("对不起,您咬到自己了。游戏结束.");
411 }
412 else if (endGamestatus == 3)
413 {
414 printf("您的已经结束了游戏。");
415 }
416 Pos(24, 13);
417 printf("您的得分是%dn", score);
418 while (getchar() != 'y')
419 {
420 printf("close?[y]");
421 }
422 exit(0);
423 }
424
425 void gameStart()//游戏初始化
426 {
427 system("mode con cols=100 lines=30");
428 initGame();
429 creatMap();
430 initSnake();
431 createFood();
432 }
433
434 int main()
435 {
436 gameStart();
437 runGame();
438 endGame();
439 return 0;
440 }
原博客地址:http://www.cnblogs.com/jacklu/p/5214692.html