在构造这个贪吃蛇的时候会需要用到一个链表
蛇的身体和食物重合的时候长度加一,插入法来实现这个步骤
Vs 完美支持
源代码在此
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 gamecircle(); 35 void welcometogame(); 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++) 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)); 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 gamecircle()//控制游戏 308 { 309 310 Pos(75, 10); 311 printf("不能穿墙,不能咬到自己\n"); 312 Pos(75, 12); 313 printf("用↑.↓.←.→分别控制蛇的移动."); 314 Pos(75, 14); 315 printf("F1 为加速,F2 为减速\n"); 316 Pos(75, 16); 317 printf("ESC :退出游戏.\n"); 318 Pos(75, 18); 319 printf("space:暂停游戏."); 320 Pos(70, 24); 321 printf("博主主页http://www.cnblogs.com/nougat/"); 322 status = R; 323 while (1) 324 { 325 Pos(60, 3); 326 printf("得分:%d ", score); 327 Pos(60, 5); 328 printf("每个食物得分:%d分", add); 329 if (GetAsyncKeyState(VK_UP) && status != D) 330 { 331 status = U; 332 } 333 else if (GetAsyncKeyState(VK_DOWN) && status != U) 334 { 335 status = D; 336 } 337 else if (GetAsyncKeyState(VK_LEFT) && status != R) 338 { 339 status = L; 340 } 341 else if (GetAsyncKeyState(VK_RIGHT) && status != L) 342 { 343 status = R; 344 } 345 else if (GetAsyncKeyState(VK_SPACE)) 346 { 347 pause(); 348 } 349 else if (GetAsyncKeyState(VK_ESCAPE)) 350 { 351 endgamestatus = 3; 352 break; 353 } 354 else if (GetAsyncKeyState(VK_F1)) 355 { 356 if (sleeptime >= 50) 357 { 358 sleeptime = sleeptime - 30; 359 add = add + 2; 360 if (sleeptime == 320) 361 { 362 add = 2;//防止减到1之后再加回来有错 363 } 364 } 365 } 366 else if (GetAsyncKeyState(VK_F2)) 367 { 368 if (sleeptime<350) 369 { 370 sleeptime = sleeptime + 30; 371 add = add - 2; 372 if (sleeptime == 350) 373 { 374 add = 1; //保证最低分为1 375 } 376 } 377 } 378 Sleep(sleeptime); 379 snakemove(); 380 } 381 } 382 383 void welcometogame()//开始界面 384 { 385 Pos(48, 12); 386 387 system("title 睡前小游戏,嘿嘿"); 388 printf("带你回小时候的贪吃蛇"); 389 Pos(48, 25); 390 system("pause"); 391 system("cls"); 392 Pos(34, 12); 393 printf("用↑.↓.←.→分别控制蛇的移动, F1 为加速,2 为减速\n"); 394 Pos(48, 14); 395 printf("加速将能得到更高的分数。\n"); 396 Pos(52, 25); 397 system("pause"); 398 system("cls"); 399 } 400 401 void endgame()//结束游戏 402 { 403 404 system("cls"); 405 Pos(48, 12); 406 if (endgamestatus == 1) 407 { 408 printf("不能撞墙的哈."); 409 } 410 else if (endgamestatus == 2) 411 { 412 printf("不能吃自己的"); 413 } 414 else if (endgamestatus == 3) 415 { 416 printf("游戏结束啦"); 417 } 418 Pos(48, 15); 419 printf(" 得分%d分\n", score); 420 exit(0); 421 } 422 423 void gamestart()//游戏初始化 424 { 425 system("mode con cols=100 lines=30"); 426 welcometogame(); 427 creatMap(); 428 initsnake(); 429 createfood(); 430 } 431 432 int main() 433 { 434 gamestart(); 435 gamecircle(); 436 endgame(); 437 return 0; 438 }