推箱子(窄字符Version)——C语言小程序
推箱子——C语言小程序

1 #include <stdio.h> 2 #include <conio.h> 3 #include <stdlib.h> 4 #include <Windows.h> 5 #include "Game.h" 6 7 #define N 100 /* 二维数组最大100*100 */ 8 #define NTAB 24 /* 调整界面位置 */ 9 #define YES 1 /* 可以移动 */ 10 #define NO 0 /* 不能移动 */ 11 #define MAP_MAX 6 /* 最大关卡数 */ 12 13 int suc = 0;/* 通关判定 */ 14 15 void OpenMap(FILE **fp, int map); /* 打开地图文件 */ 16 void InitMap(char (*map)[N]); /* 地图初始化 */ 17 void JudgeFopen_s(errno_t err); /* 判断文件打开是否成功 */ 18 void ReadMap(char (*map)[N], FILE *fp, int *x, int *y, int *suc); /* 读取地图 */ 19 void DisplyMap(char (*map)[N]); /* 打印地图 */ 20 21 void PlayerMove(int move, int *x, int *y, char (*map)[N]); /* 玩家移动*/ 22 void JudgePlayerMove(int move, int *x, int *y, char (*map)[N]); /* 判断玩家移动方向 */ 23 int JudgeBarr(int move, int *x, int *y, char(*map)[N]); /* 判断玩家移动方向上是否有障碍物 */ 24 int JudgeBarrType(int move, int *x, int *y, char(*map)[N]); /* 判断障碍物类别 */ 25 void BoxMove(int move, int *x, int *y, char(*map)[N]); /* 箱子移动 */ 26 int IsBox(int move, int *x, int *y, char(*map)[N]); /* 判断是否推动的是箱子*/ 27 int JudgeBoxBoun(int move, int *x, int *y, char(*map)[N]); /* 判断箱子能否被推动 */ 28 void RefreshBox(int move, int *x, int *y, char(*map)[N]); /* 更新移动后的箱子的位置 */ 29 void RefreshPlayer(int move, int *x, int *y, char(*map)[N]);/* 更新移动后的玩家位置 */ 30 int JudgePlayerOri(int move, int *x, int *y, char(*map)[N]);/* 判断玩家原位置是不是空地 */ 31 int JudgeBoxDes(int move, int *x, int *y, char(*map)[N]); /* 判断箱子移动后的位置是不是目标点 */ 32 int JudgeBoxOri(int move, int *x, int *y, char(*map)[N]); /* 判断箱子原位置是不是目标点 */ 33 int JudgePlayerDes(int move, int *x, int *y, char(*map)[N]);/* 判断玩家移动后的位置是不是目标点 */ 34 int JudgeSuc(FILE **fp, int *suc, int *num, char (*map)[N], int *x, int *y); /* 判断是否通关 */ 35 void SucCount(int move, int *x, int *y, char(*map)[N], int *suc); /* 通关条件计数 */ 36 37 38 /* Game: 推箱子 */ 39 /* WASD移动 */ 40 int main() 41 { 42 FILE *fp; 43 int order; /* 指令 */ 44 int move; /* 移动方向 */ 45 char ss[N][N]; /* 地图 */ 46 int x, y; /* 玩家坐标 */ 47 int level = 1; /* 当前关卡数 */ 48 49 OpenMap(&fp, level); /* 打开存储地图的文件 */ 50 51 HideCursor(); /* 隐藏光标 */ 52 InitMap(ss); /* 初始化地图 */ 53 ReadMap(ss, fp, &x, &y, &suc);/* 读取地图 */ 54 DisplyMap(ss); /* 打印地图 */ 55 while (1) 56 { 57 order = _getch(); /* 接收指令 */ 58 move = MoveByWasd(order); /* 判断移动方向 */ 59 JudgePlayerMove(move, &x, &y, ss); /* 玩家移动 */ 60 JudgeSuc(&fp, &suc, &level, ss, &x, &y); /* 判断是否通关 */ 61 } 62 63 return 0; 64 } 65 66 /* Function: 打开地图文件*/ 67 void OpenMap(FILE **fp, int map) 68 { 69 errno_t err; 70 71 switch(map) 72 { 73 case 1: 74 { 75 err = fopen_s(fp, "m1.txt", "r"); /* 文件打开成功返回0值,否则返回非0值*/ 76 JudgeFopen_s(err); /* 判断文件打开是否成功 */ 77 break; 78 } 79 case 2: 80 { 81 err = fopen_s(fp, "m2.txt", "r"); 82 JudgeFopen_s(err); 83 break; 84 } 85 case 3: 86 { 87 err = fopen_s(fp, "m3.txt", "r"); 88 JudgeFopen_s(err); 89 break; 90 } 91 case 4: 92 { 93 err = fopen_s(fp, "m4.txt", "r"); 94 JudgeFopen_s(err); 95 break; 96 } 97 case 5: 98 { 99 err = fopen_s(fp, "m5.txt", "r"); 100 JudgeFopen_s(err); 101 break; 102 } 103 case 6: 104 { 105 err = fopen_s(fp, "m6.txt", "r"); 106 JudgeFopen_s(err); 107 break; 108 } 109 default: 110 { 111 system("cls"); 112 printf("\t\t\t没有更多了关卡了,即将退出游戏"); 113 Sleep(3000); 114 exit(0); 115 } 116 } 117 } 118 /* Function: 通关条件计数 */ 119 void SucCount(int move, int *x, int *y, char(*map)[N],int *suc) 120 { 121 if (JudgeBoxOri(move, x, y, map) == YES) /* 箱子原位置不是目标点 */ 122 { 123 if (JudgeBoxDes(move, x, y, map) == YES) /* 箱子移动后的位置不是目标点 */ 124 { 125 return; 126 } 127 else /* 箱子移动后的位置是目标点*/ 128 { 129 (*suc)--; 130 return; 131 } 132 } 133 else /* 箱子原位置是目标点 */ 134 { 135 if (JudgeBoxDes(move, x, y, map) == YES) /* 箱子移动后的位置不是目标点 */ 136 { 137 (*suc)++; 138 return; 139 } 140 else /* 箱子移动后的位置是目标点*/ 141 { 142 return; 143 } 144 } 145 } 146 147 /* Function: 判断是否通关 */ 148 int JudgeSuc(FILE **fp, int *suc, int *num, char (*map)[N], int *x, int *y) 149 { 150 if ((*suc) == 0) 151 { 152 (*suc) = 0; /* 关卡通关计数重置 */ 153 (*num)++; /* 关卡数+1 */ 154 155 system("cls"); 156 if ((*num) <= MAP_MAX) 157 { 158 printf("\t\t\t通关!即将进入第下一关"); 159 } 160 else 161 { 162 system("cls"); 163 printf("\t\t\t没有更多了关卡了,即将退出游戏"); 164 Sleep(3000); 165 exit(0); 166 } 167 168 Sleep(1000); 169 system("cls"); 170 171 OpenMap(fp,*num); /* 打开地图文件 */ 172 InitMap(map); /* 初始化地图 */ 173 ReadMap(map, *fp, x, y, suc);/* 读取地图 */ 174 DisplyMap(map); /* 打印地图 */ 175 176 return YES; /* 通关 */ 177 } 178 else 179 { 180 return NO; 181 } 182 } 183 /* Function: 玩家移动*/ 184 void PlayerMove(int move, int *x, int *y, char (*map)[N]) 185 { 186 switch(move) 187 { 188 case UP: 189 { 190 if (JudgePlayerOri(move, x, y, map) == YES) /* 如果玩家原位置是空地 */ 191 { 192 gotoxy(*x+NTAB, *y);printf(" ");(*y)--;gotoxy(*x+NTAB, *y);printf("I");break;/* 玩家移动 */ 193 } 194 else /* 玩家原位置是目标点 */ 195 { 196 gotoxy(*x+NTAB, *y);printf("*");(*y)--;gotoxy(*x+NTAB, *y);printf("I");break; /* 玩家移动 */ 197 } 198 } 199 case DOWN: 200 { 201 if (JudgePlayerOri(move, x, y, map) == YES) /* 如果玩家原位置是空地 */ 202 { 203 gotoxy(*x+NTAB, *y);printf(" ");(*y)++;gotoxy(*x+NTAB, *y);printf("I");break;/* 玩家移动 */ 204 } 205 else 206 { 207 gotoxy(*x+NTAB, *y);printf("*");(*y)++;gotoxy(*x+NTAB, *y);printf("I");break;/* 玩家移动 */ 208 } 209 } 210 case LEFT: 211 { 212 if (JudgePlayerOri(move, x, y, map) == YES) /* 如果玩家原位置是空地 */ 213 { 214 gotoxy(*x+NTAB, *y);printf(" ");(*x)--;gotoxy(*x+NTAB, *y);printf("I");break; /* 玩家移动 */ 215 } 216 else 217 { 218 gotoxy(*x+NTAB, *y);printf("*");(*x)--;gotoxy(*x+NTAB, *y);printf("I");break; /* 玩家移动 */ 219 } 220 } 221 case RIGHT: 222 { 223 if (JudgePlayerOri(move, x, y, map) == YES) /* 如果玩家原位置是空地 */ 224 { 225 gotoxy(*x+NTAB, *y);printf(" ");(*x)++;gotoxy(*x+NTAB, *y);printf("I");break; /* 玩家移动 */ 226 } 227 else 228 { 229 gotoxy(*x+NTAB, *y);printf("*");(*x)++;gotoxy(*x+NTAB, *y);printf("I");break; /* 玩家移动 */ 230 } 231 } 232 default: break; 233 } 234 } 235 /* Function: 判断玩家移动后的位置是不是目标点 */ 236 int JudgePlayerDes(int move, int *x, int *y, char(*map)[N]) 237 { 238 switch(move) 239 { 240 case UP: 241 { 242 if (map[(*y)-1][*x] == '*') /* 移动后的位置是目标点 */ 243 { 244 return YES; 245 } 246 else 247 { 248 return NO; 249 } 250 } 251 case DOWN: 252 { 253 if (map[(*y)+1][*x] == '*') 254 { 255 return YES; 256 } 257 else 258 { 259 return NO; 260 } 261 } 262 case LEFT: 263 { 264 if (map[*y][(*x)-1] == '*') 265 { 266 return YES; 267 } 268 else 269 { 270 return NO; 271 } 272 } 273 case RIGHT: 274 { 275 if (map[*y][(*x)+1] == '*') 276 { 277 return YES; 278 } 279 else 280 { 281 return NO; 282 } 283 } 284 default: return NO; 285 } 286 } 287 288 /* Function: 判断箱子原位置是不是目标点 */ 289 int JudgeBoxOri(int move, int *x, int *y, char(*map)[N]) 290 { 291 switch(move) 292 { 293 case UP: 294 { 295 if (map[(*y)-1][*x] == '$') /* 箱子原位置是目标点 */ 296 { 297 return NO; 298 } 299 else 300 { 301 return YES; 302 } 303 } 304 case DOWN: 305 { 306 if (map[(*y)+1][*x] == '$') /* 箱子原位置是目标点 */ 307 { 308 return NO; 309 } 310 else 311 { 312 return YES; 313 } 314 } 315 case LEFT: 316 { 317 if (map[*y][(*x)-1] == '$') /* 箱子原位置是目标点 */ 318 { 319 return NO; 320 } 321 else 322 { 323 return YES; 324 } 325 } 326 case RIGHT: 327 { 328 if (map[*y][(*x)+1] == '$') /* 箱子原位置是目标点 */ 329 { 330 return NO; 331 } 332 else 333 { 334 return YES; 335 } 336 } 337 default: return NO; 338 } 339 } 340 /* Function: 判断箱子移动后的位置是不是目标点 */ 341 int JudgeBoxDes(int move, int *x, int *y, char(*map)[N]) 342 { 343 switch(move) 344 { 345 case UP: 346 { 347 if (map[(*y)-2][*x] == '*') /* 箱子移动后是目标点 */ 348 { 349 return NO; 350 } 351 else /* 箱子移动后不是目标点 */ 352 { 353 return YES; 354 } 355 } 356 case DOWN: 357 { 358 if (map[(*y)+2][*x] == '*') 359 { 360 return NO; 361 } 362 else 363 { 364 return YES; 365 } 366 } 367 case LEFT: 368 { 369 if (map[*y][(*x)-2] == '*') 370 { 371 return NO; 372 } 373 else 374 { 375 return YES; 376 } 377 } 378 case RIGHT: 379 { 380 if (map[*y][(*x)+2] == '*') 381 { 382 return NO; 383 } 384 else 385 { 386 return YES; 387 } 388 } 389 default: return NO; 390 } 391 } 392 /* Function: 判断障碍物类别 */ 393 int JudgeBarrType(int move, int *x, int *y, char(*map)[N]) 394 { 395 switch (move) 396 { 397 case UP: 398 { 399 if (map[(*y)-1][*x] == '#') /* 如果目标地点是墙壁 */ 400 { 401 return NO; /* 无法移动 */ 402 } 403 else 404 { 405 return YES;/* 不是墙,需要进一步判断 */ 406 } 407 } 408 case DOWN: 409 { 410 if (map[(*y)+1][*x] == '#') 411 { 412 return NO; 413 } 414 else 415 { 416 return YES; 417 } 418 } 419 case LEFT: 420 { 421 if (map[*y][(*x)-1] == '#') 422 { 423 return NO; 424 } 425 else 426 { 427 return YES; 428 } 429 } 430 case RIGHT: 431 { 432 if (map[*y][(*x)+1] == '#') 433 { 434 return NO; 435 } 436 else 437 { 438 return YES; 439 } 440 } 441 default: return NO; 442 } 443 } 444 445 /* Function: 更新移动后的玩家位置 */ 446 void RefreshPlayer(int move, int *x, int *y, char(*map)[N]) 447 { 448 switch (move) 449 { 450 case UP: 451 { 452 if (JudgePlayerOri(move, x, y, map) == YES) /* 玩家原位置是空地 */ 453 { 454 if (JudgePlayerDes(move, x, y, map) == YES) /* 玩家移动后的位置是目标点 */ 455 { 456 map[*y][*x] = ' ';map[(*y)-1][*x] = '*';break; 457 } 458 else 459 { 460 map[*y][*x] = ' ';map[(*y)-1][*x] = 'I';break; 461 } 462 } 463 else /* 玩家原位置不是空地 */ 464 { 465 if (JudgePlayerDes(move, x, y, map) == YES) /* 玩家移动后的位置是目标点 */ 466 { 467 map[*y][*x] = '*';map[(*y)-1][*x] = '*';break; 468 } 469 else 470 { 471 map[*y][*x] = '*';map[(*y)-1][*x] = 'I';break; 472 } 473 } 474 } 475 case DOWN: 476 { 477 if (JudgePlayerOri(move, x, y, map) == YES) /* 玩家原位置是空地 */ 478 { 479 if (JudgePlayerDes(move, x, y, map) == YES) /* 玩家移动后的位置是目标点 */ 480 { 481 map[*y][*x] = ' ';map[(*y)+1][*x] = '*';break; 482 } 483 else 484 { 485 map[*y][*x] = ' ';map[(*y)+1][*x] = 'I';break; 486 } 487 } 488 else /* 玩家原位置不是空地 */ 489 { 490 if (JudgePlayerDes(move, x, y, map) == YES) /* 玩家移动后的位置是目标点 */ 491 { 492 map[*y][*x] = '*';map[(*y)+1][*x] = '*';break; 493 } 494 else 495 { 496 map[*y][*x] = '*';map[(*y)+1][*x] = 'I';break; 497 } 498 } 499 } 500 case LEFT: 501 { 502 if (JudgePlayerOri(move, x, y, map) == YES) /* 玩家原位置是空地 */ 503 { 504 if (JudgePlayerDes(move, x, y, map) == YES) /* 玩家移动后的位置是目标点 */ 505 { 506 map[*y][*x] = ' ';map[*y][(*x)-1] = '*';break; 507 } 508 else 509 { 510 map[*y][*x] = ' ';map[*y][(*x)-1] = 'I';break; 511 } 512 } 513 else /* 玩家原位置不是空地 */ 514 { 515 if (JudgePlayerDes(move, x, y, map) == YES) /* 玩家移动后的位置是目标点 */ 516 { 517 map[*y][*x] = '*';map[*y][(*x)-1] = '*';break; 518 } 519 else 520 { 521 map[*y][*x] = '*';map[*y][(*x)-1] = 'I';break; 522 } 523 } 524 } 525 case RIGHT: 526 { 527 if (JudgePlayerOri(move, x, y, map) == YES) /* 玩家原位置是空地 */ 528 { 529 if (JudgePlayerDes(move, x, y, map) == YES) /* 玩家移动后的位置是目标点 */ 530 { 531 map[*y][*x] = ' ';map[*y][(*x)+1] = '*';break; 532 } 533 else 534 { 535 map[*y][*x] = ' ';map[*y][(*x)+1] = 'I';break; 536 } 537 } 538 else /* 玩家原位置不是空地 */ 539 { 540 if (JudgePlayerDes(move, x, y, map) == YES) /* 玩家移动后的位置是目标点 */ 541 { 542 map[*y][*x] = '*';map[*y][(*x)+1] = '*';break; 543 } 544 else 545 { 546 map[*y][*x] = '*';map[*y][(*x)+1] = 'I';break; 547 } 548 } 549 } 550 } 551 } 552 553 /* Function: 判断玩家原位置是不是空地*/ 554 int JudgePlayerOri(int move, int *x, int *y, char(*map)[N]) 555 { 556 if (map[*y][*x] == '*') 557 { 558 return NO; 559 } 560 else 561 { 562 return YES; /* 是空地 */ 563 } 564 } 565 /* Function: 判断箱子移动之后的位置是不是目标点 */ 566 567 568 /* FunctionL 更新移动后的箱子位置 */ 569 void RefreshBox(int move, int *x, int *y, char(*map)[N]) 570 { 571 switch (move) 572 { 573 case UP: 574 { 575 SucCount(move, x, y, map, &suc); /* 通关条件计数 */ 576 if (JudgeBoxOri(move, x, y, map) == YES) /* 箱子原位置不是目标点 */ 577 { 578 if (JudgeBoxDes(move, x, y, map) == YES) /* 箱子移动后的位置不是目标点 */ 579 { 580 map[(*y)-1][*x] = ' ';map[(*y)-2][*x] = '@';break; 581 } 582 else 583 { 584 map[(*y)-1][*x] = ' ';map[(*y)-2][*x] = '$';break; 585 } 586 } 587 else /* 箱子原位置是目标点 */ 588 { 589 if (JudgeBoxDes(move, x, y, map) == YES) /* 箱子移动后的位置不是目标点 */ 590 { 591 map[(*y)-1][*x] = '*';map[(*y)-2][*x] = '@';break; 592 } 593 else 594 { 595 map[(*y)-1][*x] = '*';map[(*y)-2][*x] = '$';break; 596 } 597 } 598 } 599 case DOWN: 600 { 601 SucCount(move, x, y, map, &suc); /* 通关条件计数 */ 602 if (JudgeBoxOri(move, x, y, map) == YES) /* 箱子原位置不是目标点 */ 603 { 604 if (JudgeBoxDes(move, x, y, map) == YES) /* 箱子移动后的位置不是目标点 */ 605 { 606 map[(*y)+1][*x] = ' ';map[(*y)+2][*x] = '@';break; 607 } 608 else 609 { 610 map[(*y)+1][*x] = ' ';map[(*y)+2][*x] = '$';break; 611 } 612 } 613 else /* 箱子原位置是目标点 */ 614 { 615 if (JudgeBoxDes(move, x, y, map) == YES) /* 箱子移动后的位置不是目标点 */ 616 { 617 map[(*y)+1][*x] = '*';map[(*y)+2][*x] = '@';break; 618 } 619 else 620 { 621 map[(*y)+1][*x] = '*';map[(*y)+2][*x] = '$';break; 622 } 623 } 624 } 625 case LEFT: 626 { 627 SucCount(move, x, y, map, &suc); /* 通关条件计数 */ 628 if (JudgeBoxOri(move, x, y, map) == YES) /* 箱子原位置不是目标点 */ 629 { 630 if (JudgeBoxDes(move, x, y, map) == YES) /* 箱子移动后的位置不是目标点 */ 631 { 632 map[*y][(*x)-1] = ' ';map[*y][(*x)-2] = '@';break; 633 } 634 else 635 { 636 map[*y][(*x)-1] = ' ';map[*y][(*x)-2] = '$';break; 637 } 638 } 639 else /* 箱子原位置是目标点 */ 640 { 641 if (JudgeBoxDes(move, x, y, map) == YES) /* 箱子移动后的位置不是目标点 */ 642 { 643 map[*y][(*x)-1] = '*';map[*y][(*x)-2] = '@';break; 644 } 645 else 646 { 647 map[*y][(*x)-1] = '*';map[*y][(*x)-2] = '$';break; 648 } 649 } 650 } 651 652 case RIGHT: 653 { 654 SucCount(move, x, y, map, &suc); /* 通关条件计数 */ 655 if (JudgeBoxOri(move, x, y, map) == YES) /* 箱子原位置不是目标点 */ 656 { 657 if (JudgeBoxDes(move, x, y, map) == YES) /* 箱子移动后的位置不是目标点 */ 658 { 659 map[*y][(*x)+1] = ' ';map[*y][(*x)+2] = '@';break; 660 } 661 else 662 { 663 map[*y][(*x)+1] = ' ';map[*y][(*x)+2] = '$';break; 664 } 665 } 666 else /* 箱子原位置是目标点 */ 667 { 668 if (JudgeBoxDes(move, x, y, map) == YES) /* 箱子移动后的位置不是目标点 */ 669 { 670 map[*y][(*x)+1] = '*';map[*y][(*x)+2] = '@';break; 671 } 672 else 673 { 674 map[*y][(*x)+1] = '*';map[*y][(*x)+2] = '$';break; 675 } 676 } 677 } 678 } 679 } 680 /* Functioni: 判断箱子能否被推动 */ 681 int JudgeBoxBoun(int move, int *x, int *y, char(*map)[N]) 682 { 683 switch (move) 684 { 685 case UP: 686 { 687 if (map[(*y)-2][*x] == '#' || map[(*y)-2][*x] == '@' || map[(*y)-2][*x] == '$') /* 箱子被推动的方向 是墙壁,或者是另一个箱子*/ 688 { 689 return NO; 690 } 691 else 692 { 693 return YES; 694 } 695 } 696 case DOWN: 697 { 698 if (map[(*y)+2][*x] == '#' || map[(*y)+2][*x] == '@' || map[(*y)+2][*x] == '$') 699 { 700 return NO; 701 } 702 else 703 { 704 return YES; 705 } 706 } 707 case LEFT: 708 { 709 if (map[*y][(*x)-2] == '#' || map[*y][(*x)-2] == '@' || map[*y][(*x)-2] == '$') 710 { 711 return NO; 712 } 713 else 714 { 715 return YES; 716 } 717 } 718 case RIGHT: 719 { 720 if (map[*y][(*x)+2] == '#' || map[*y][(*x)+2] == '@' || map[*y][(*x)+2] == '$') 721 { 722 return NO; 723 } 724 else 725 { 726 return YES; 727 } 728 } 729 default: return NO; 730 } 731 } 732 733 /* Function: 判断移动方向上是否有箱子 */ 734 int IsBox(int move, int *x, int *y, char(*map)[N]) 735 { 736 switch (move) 737 { 738 case UP: 739 { 740 if (map[(*y)-1][*x] == '@' || map[(*y)-1][*x] == '$') /* 如果是在空地上的箱子 或 在目标点上的箱子 */ 741 { 742 return YES; 743 } 744 else 745 { 746 return NO; 747 } 748 } 749 case DOWN: 750 { 751 if (map[(*y)+1][*x] == '@' || map[(*y)+1][*x] == '$') 752 { 753 return YES; 754 } 755 else 756 { 757 return NO; 758 } 759 } 760 case LEFT: 761 { 762 if (map[*y][(*x)-1] == '@' || map[*y][(*x)-1] == '$') 763 { 764 return YES; 765 } 766 else 767 { 768 return NO; 769 } 770 } 771 case RIGHT: 772 { 773 if (map[*y][(*x)+1] == '@' || map[*y][(*x)+1] == '$') 774 { 775 return YES; 776 } 777 else 778 { 779 return NO; 780 } 781 } 782 default: return NO; 783 784 } 785 } 786 787 /* Function: 箱子移动 */ 788 void BoxMove(int move, int *x, int *y, char(*map)[N]) 789 { 790 switch (move) 791 { 792 case UP: 793 { 794 if (JudgeBoxOri(move, x, y, map) == YES) /* 箱子原位置不是目标点 */ 795 { 796 if (JudgeBoxDes(move, x, y, map) == YES) /* 箱子移动后的位置不是目标点 */ 797 { 798 gotoxy(*x+NTAB, (*y)-1);printf(" ");gotoxy(*x+NTAB, (*y)-2);printf("@");break; /* 箱子移动 */ 799 } 800 else /* 箱子移动后的位置是目标点 */ 801 { 802 gotoxy(*x+NTAB, (*y)-1);printf(" ");gotoxy(*x+NTAB, (*y)-2);printf("$");break; /* 箱子移动 */ 803 } 804 } 805 else /* 箱子原位置是目标点 */ 806 { 807 if (JudgeBoxDes(move, x, y, map) == YES) /* 箱子移动后的位置不是目标点 */ 808 { 809 gotoxy(*x+NTAB, (*y)-1);printf("*");gotoxy(*x+NTAB, (*y)-2);printf("@");break; /* 箱子移动 */ 810 } 811 else 812 { 813 gotoxy(*x+NTAB, (*y)-1);printf("*");gotoxy(*x+NTAB, (*y)-2);printf("$");break; /* 箱子移动 */ 814 } 815 } 816 } 817 case DOWN: 818 { 819 if (JudgeBoxOri(move, x, y, map) == YES) /* 箱子原位置不是目标点 */ 820 { 821 if (JudgeBoxDes(move, x, y, map) == YES) /* 箱子移动后的位置不是目标点 */ 822 { 823 gotoxy(*x+NTAB, (*y)+1);printf(" ");gotoxy(*x+NTAB, (*y)+2);printf("@");break; /* 箱子移动 */ 824 } 825 else /* 箱子移动后的位置是目标点 */ 826 { 827 gotoxy(*x+NTAB, (*y)+1);printf(" ");gotoxy(*x+NTAB, (*y)+2);printf("$");break; /* 箱子移动 */ 828 } 829 } 830 else /* 箱子原位置是目标点 */ 831 { 832 if (JudgeBoxDes(move, x, y, map) == YES) /* 箱子移动后的位置不是目标点 */ 833 { 834 gotoxy(*x+NTAB, (*y)+1);printf("*");gotoxy(*x+NTAB, (*y)+2);printf("@");break; /* 箱子移动 */ 835 } 836 else 837 { 838 gotoxy(*x+NTAB, (*y)+1);printf("*");gotoxy(*x+NTAB, (*y)+2);printf("$");break; /* 箱子移动 */ 839 } 840 } 841 } 842 case LEFT: 843 { 844 if (JudgeBoxOri(move, x, y, map) == YES) /* 箱子原位置不是目标点 */ 845 { 846 if (JudgeBoxDes(move, x, y, map) == YES) /* 箱子移动后的位置不是目标点 */ 847 { 848 gotoxy((*x+NTAB)-1, *y);printf(" ");gotoxy((*x+NTAB)-2, *y);printf("@");break; /* 箱子移动 */ 849 } 850 else /* 箱子移动后的位置是目标点 */ 851 { 852 gotoxy((*x+NTAB)-1, *y);printf(" ");gotoxy((*x+NTAB)-2, *y);printf("$");break; /* 箱子移动 */ 853 } 854 } 855 else /* 箱子原位置是目标点 */ 856 { 857 if (JudgeBoxDes(move, x, y, map) == YES) /* 箱子移动后的位置不是目标点 */ 858 { 859 gotoxy((*x+NTAB)-1, *y);printf("*");gotoxy((*x+NTAB)-2, *y);printf("@");break; /* 箱子移动 */ 860 } 861 else 862 { 863 gotoxy((*x+NTAB)-1, *y);printf("*");gotoxy((*x+NTAB)-2, *y);printf("$");break; /* 箱子移动 */ 864 } 865 } 866 } 867 case RIGHT: 868 { 869 if (JudgeBoxOri(move, x, y, map) == YES) /* 箱子原位置不是目标点 */ 870 { 871 if (JudgeBoxDes(move, x, y, map) == YES) /* 箱子移动后的位置不是目标点 */ 872 { 873 gotoxy((*x+NTAB)+1, *y);printf(" ");gotoxy((*x+NTAB)+2, *y);printf("@");break; /* 箱子移动 */ 874 } 875 else /* 箱子移动后的位置是目标点 */ 876 { 877 gotoxy((*x+NTAB)+1, *y);printf(" ");gotoxy((*x+NTAB)+2, *y);printf("$");break; /* 箱子移动 */ 878 } 879 } 880 else /* 箱子原位置是目标点 */ 881 { 882 if (JudgeBoxDes(move, x, y, map) == YES) /* 箱子移动后的位置不是目标点 */ 883 { 884 gotoxy((*x+NTAB)+1, *y);printf("*");gotoxy((*x+NTAB)+2, *y);printf("@");break; /* 箱子移动 */ 885 } 886 else 887 { 888 gotoxy((*x+NTAB)+2, *y);printf("*");gotoxy((*x+NTAB)+2, *y);printf("$");break; /* 箱子移动 */ 889 } 890 } 891 } 892 default: break; 893 } 894 } 895 896 /* Function:判断玩家移动方向上是否有障碍物 */ 897 int JudgeBarr(int move, int *x, int *y, char(*map)[N]) 898 { 899 switch (move) 900 { 901 case UP: 902 { 903 if (map[(*y)-1][*x] == '#' || map[(*y)-1][*x] == '@' || map[(*y)-1][*x] == '*' || map[(*y)-1][*x] == '$') /* 如果是墙壁、箱子、目标点 */ 904 { 905 return NO; /* 需要进一步判断 */ 906 } 907 else 908 { 909 return YES; /* 没有障碍物 */ 910 } 911 } 912 case DOWN: 913 { 914 if (map[(*y)+1][*x] == '#' || map[(*y)+1][*x] == '@' || map[(*y)+1][*x] == '*' || map[(*y)+1][*x] == '$') 915 { 916 return NO; 917 } 918 else 919 { 920 return YES; 921 } 922 } 923 case LEFT: 924 { 925 if (map[*y][(*x)-1] == '#' || map[*y][(*x)-1] == '@' || map[*y][(*x)-1] == '*' || map[*y][(*x)-1] == '$') 926 { 927 return NO; 928 } 929 else 930 { 931 return YES; 932 } 933 } 934 case RIGHT: 935 { 936 if (map[*y][(*x)+1] == '#' || map[*y][(*x)+1] == '@' || map[*y][(*x)+1] == '*' || map[*y][(*x)+1] == '$') 937 { 938 return NO; 939 } 940 else 941 { 942 return YES; 943 } 944 } 945 default: return NO; 946 } 947 } 948 949 /* Function:玩家移动 */ 950 void JudgePlayerMove(int move, int *x, int *y, char (*map)[N]) 951 { 952 switch (move) 953 { 954 case UP: 955 { 956 if (JudgePlayerOri(move, x, y, map) == YES) /* 如果玩家原位置是空地 */ 957 { 958 if (JudgeBarr(move, x, y, map) == YES) /* 玩家移动方向上是空地 */ 959 { /* 如果移动方向上是空地,那么就可以直接移动 */ 960 RefreshPlayer(move, x, y, map);/* 更新移动后的玩家位置 */ 961 PlayerMove(move, x, y, map); /* 玩家移动 */ 962 break; 963 } 964 else if (JudgeBarrType(move, x, y, map) == NO) /* 如果是墙壁 */ 965 { 966 break; /* 无法移动 */ 967 } 968 else if (IsBox(move, x, y, map) == YES) /* 移动方向上是箱子 */ 969 { 970 if (JudgeBoxBoun(move, x, y, map) == YES) /* 箱子能被推动 */ 971 { 972 BoxMove(move, x, y, map); 973 RefreshBox(move, x, y, map); 974 RefreshPlayer(move, x, y, map); 975 PlayerMove(move, x, y, map); 976 break; 977 } 978 else /* 箱子不能被推动 */ 979 { 980 break; 981 } 982 } 983 else if (JudgePlayerDes(move, x, y, map) == YES) /* 玩家移动后的位置是目标点*/ 984 { 985 RefreshPlayer(move, x, y, map); /* 更新移动后的玩家位置 */ 986 PlayerMove(move, x, y, map);/* 玩家移动 */ 987 break; 988 } 989 } 990 else /* 玩家原位置为目标点 */ 991 { 992 if (JudgeBarr(move, x, y, map) == YES) /* 玩家移动方向上是空地 */ 993 { /* 如果移动方向上是空地,那么就可以直接移动 */ 994 RefreshPlayer(move, x, y, map);/* 更新移动后的玩家位置 */ 995 PlayerMove(move, x, y, map); /* 玩家移动 */ 996 break; 997 } 998 else if (JudgeBarrType(move, x, y, map) == NO) /* 如果是墙壁 */ 999 { 1000 break; /* 无法移动 */ 1001 } 1002 else if (IsBox(move, x, y, map) == YES) /* 移动方向上是箱子 */ 1003 { 1004 if (JudgeBoxBoun(move, x, y, map) == YES) /* 箱子能被推动 */ 1005 { 1006 BoxMove(move, x, y, map); 1007 RefreshBox(move, x, y, map); 1008 RefreshPlayer(move, x, y, map); 1009 PlayerMove(move, x, y, map); 1010 break; 1011 } 1012 else /* 箱子不能被推动 */ 1013 { 1014 break; 1015 } 1016 } 1017 else if (JudgePlayerDes(move, x, y, map) == YES) /* 玩家移动后的位置是目标点*/ 1018 { 1019 RefreshPlayer(move, x, y, map); /* 更新移动后的玩家位置 */ 1020 PlayerMove(move, x, y, map);/* 玩家移动 */ 1021 break; 1022 } 1023 } 1024 } 1025 1026 case DOWN: 1027 { 1028 if (JudgePlayerOri(move, x, y, map) == YES) /* 如果玩家原位置是空地 */ 1029 { 1030 if (JudgeBarr(move, x, y, map) == YES) /* 玩家移动方向上是空地 */ 1031 { /* 如果移动方向上是空地,那么就可以直接移动 */ 1032 RefreshPlayer(move, x, y, map);/* 更新移动后的玩家位置 */ 1033 PlayerMove(move, x, y, map); /* 玩家移动 */ 1034 break; 1035 } 1036 else if (JudgeBarrType(move, x, y, map) == NO) /* 如果是墙壁 */ 1037 { 1038 break; /* 无法移动 */ 1039 } 1040 else if (IsBox(move, x, y, map) == YES) /* 移动方向上是箱子 */ 1041 { 1042 if (JudgeBoxBoun(move, x, y, map) == YES) /* 箱子能被推动 */ 1043 { 1044 BoxMove(move, x, y, map); 1045 RefreshBox(move, x, y, map); 1046 RefreshPlayer(move, x, y, map); 1047 PlayerMove(move, x, y, map); 1048 break; 1049 } 1050 else /* 箱子不能被推动 */ 1051 { 1052 break; 1053 } 1054 } 1055 else if (JudgePlayerDes(move, x, y, map) == YES) /* 玩家移动后的位置是目标点*/ 1056 { 1057 RefreshPlayer(move, x, y, map); /* 更新移动后的玩家位置 */ 1058 PlayerMove(move, x, y, map); /* 玩家移动 */ 1059 break; 1060 } 1061 } 1062 else 1063 { 1064 if (JudgeBarr(move, x, y, map) == YES) /* 玩家移动方向上是空地 */ 1065 { /* 如果移动方向上是空地,那么就可以直接移动 */ 1066 RefreshPlayer(move, x, y, map);/* 更新移动后的玩家位置 */ 1067 PlayerMove(move, x, y, map); /* 玩家移动 */ 1068 break; 1069 } 1070 else if (JudgeBarrType(move, x, y, map) == NO) /* 如果是墙壁 */ 1071 { 1072 break; /* 无法移动 */ 1073 } 1074 else if (IsBox(move, x, y, map) == YES) /* 移动方向上是箱子 */ 1075 { 1076 if (JudgeBoxBoun(move, x, y, map) == YES) /* 箱子能被推动 */ 1077 { 1078 BoxMove(move, x, y, map); 1079 RefreshBox(move, x, y, map); 1080 RefreshPlayer(move, x, y, map); 1081 PlayerMove(move, x, y, map); 1082 break; 1083 } 1084 else /* 箱子不能被推动 */ 1085 { 1086 break; 1087 } 1088 } 1089 else if (JudgePlayerDes(move, x, y, map) == YES) /* 玩家移动后的位置是目标点*/ 1090 { 1091 RefreshPlayer(move, x, y, map); /* 更新移动后的玩家位置 */ 1092 PlayerMove(move, x, y, map);/* 玩家移动 */ 1093 break; 1094 } 1095 } 1096 1097 case LEFT: 1098 { 1099 if (JudgePlayerOri(move, x, y, map) == YES) /* 如果玩家原位置是空地 */ 1100 { 1101 if (JudgeBarr(move, x, y, map) == YES) /* 玩家移动方向上是空地 */ 1102 { /* 如果移动方向上是空地,那么就可以直接移动 */ 1103 RefreshPlayer(move, x, y, map);/* 更新移动后的玩家位置 */ 1104 PlayerMove(move, x, y, map); /* 玩家移动 */ 1105 break; 1106 } 1107 else if (JudgeBarrType(move, x, y, map) == NO) /* 如果是墙壁 */ 1108 { 1109 break; /* 无法移动 */ 1110 } 1111 else if (IsBox(move, x, y, map) == YES) /* 移动方向上是箱子 */ 1112 { 1113 if (JudgeBoxBoun(move, x, y, map) == YES) /* 箱子能被推动 */ 1114 { 1115 BoxMove(move, x, y, map); 1116 RefreshBox(move, x, y, map); 1117 RefreshPlayer(move, x, y, map); 1118 PlayerMove(move, x, y, map); 1119 break; 1120 } 1121 else /* 箱子不能被推动 */ 1122 { 1123 break; 1124 } 1125 } 1126 else if (JudgePlayerDes(move, x, y, map) == YES) /* 玩家移动后的位置是目标点*/ 1127 { 1128 RefreshPlayer(move, x, y, map); /* 更新移动后的玩家位置 */ 1129 PlayerMove(move, x, y, map);/* 玩家移动 */ 1130 break; 1131 } 1132 } 1133 else 1134 { 1135 if (JudgeBarr(move, x, y, map) == YES) /* 玩家移动方向上是空地 */ 1136 { /* 如果移动方向上是空地,那么就可以直接移动 */ 1137 RefreshPlayer(move, x, y, map);/* 更新移动后的玩家位置 */ 1138 PlayerMove(move, x, y, map); /* 玩家移动 */ 1139 break; 1140 } 1141 else if (JudgeBarrType(move, x, y, map) == NO) /* 如果是墙壁 */ 1142 { 1143 break; /* 无法移动 */ 1144 } 1145 else if (IsBox(move, x, y, map) == YES) /* 移动方向上是箱子 */ 1146 { 1147 if (JudgeBoxBoun(move, x, y, map) == YES) /* 箱子能被推动 */ 1148 { 1149 BoxMove(move, x, y, map); 1150 RefreshBox(move, x, y, map); 1151 RefreshPlayer(move, x, y, map); 1152 PlayerMove(move, x, y, map); 1153 break; 1154 } 1155 else /* 箱子不能被推动 */ 1156 { 1157 break; 1158 } 1159 } 1160 else if (JudgePlayerDes(move, x, y, map) == YES) /* 玩家移动后的位置是目标点*/ 1161 { 1162 RefreshPlayer(move, x, y, map); /* 更新移动后的玩家位置 */ 1163 PlayerMove(move, x, y, map);/* 玩家移动 */ 1164 break; 1165 } 1166 } 1167 } 1168 case RIGHT: 1169 { 1170 if (JudgePlayerOri(move, x, y, map) == YES) /* 如果玩家原位置是空地 */ 1171 { 1172 if (JudgeBarr(move, x, y, map) == YES) /* 玩家移动方向上是空地 */ 1173 { /* 如果移动方向上是空地,那么就可以直接移动 */ 1174 RefreshPlayer(move, x, y, map);/* 更新移动后的玩家位置 */ 1175 PlayerMove(move, x, y, map); /* 玩家移动 */ 1176 break; 1177 } 1178 else if (JudgeBarrType(move, x, y, map) == NO) /* 如果是墙壁 */ 1179 { 1180 break; /* 无法移动 */ 1181 } 1182 else if (IsBox(move, x, y, map) == YES) /* 移动方向上是箱子 */ 1183 { 1184 if (JudgeBoxBoun(move, x, y, map) == YES) /* 箱子能被推动 */ 1185 { 1186 BoxMove(move, x, y, map); 1187 RefreshBox(move, x, y, map); 1188 RefreshPlayer(move, x, y, map); 1189 PlayerMove(move, x, y, map); 1190 break; 1191 } 1192 else /* 箱子不能被推动 */ 1193 { 1194 break; 1195 } 1196 } 1197 else if (JudgePlayerDes(move, x, y, map) == YES) /* 玩家移动后的位置是目标点*/ 1198 { 1199 RefreshPlayer(move, x, y, map); /* 更新移动后的玩家位置 */ 1200 PlayerMove(move, x, y, map);/* 玩家移动 */ 1201 break; 1202 } 1203 } 1204 else 1205 { 1206 if (JudgeBarr(move, x, y, map) == YES) /* 玩家移动方向上是空地 */ 1207 { /* 如果移动方向上是空地,那么就可以直接移动 */ 1208 RefreshPlayer(move, x, y, map);/* 更新移动后的玩家位置 */ 1209 PlayerMove(move, x, y, map); /* 玩家移动 */ 1210 break; 1211 } 1212 else if (JudgeBarrType(move, x, y, map) == NO) /* 如果是墙壁 */ 1213 { 1214 break; /* 无法移动 */ 1215 } 1216 else if (IsBox(move, x, y, map) == YES) /* 移动方向上是箱子 */ 1217 { 1218 if (JudgeBoxBoun(move, x, y, map) == YES) /* 箱子能被推动 */ 1219 { 1220 BoxMove(move, x, y, map); 1221 RefreshBox(move, x, y, map); 1222 RefreshPlayer(move, x, y, map); 1223 PlayerMove(move, x, y, map); 1224 break; 1225 } 1226 else /* 箱子不能被推动 */ 1227 { 1228 break; 1229 } 1230 } 1231 else if (JudgePlayerDes(move, x, y, map) == YES) /* 玩家移动后的位置是目标点*/ 1232 { 1233 RefreshPlayer(move, x, y, map); /* 更新移动后的玩家位置 */ 1234 PlayerMove(move, x, y, map);/* 玩家移动 */ 1235 break; 1236 } 1237 } 1238 } 1239 default: break; 1240 } 1241 } 1242 } 1243 1244 /* Function: 打印地图 */ 1245 void DisplyMap(char (*map)[N]) 1246 { 1247 int i, j; 1248 1249 for (i = 0; i < N ;i++) 1250 { 1251 printf("\t\t\t"); 1252 for (j = 0; j < N; j++) 1253 { 1254 if (map[i][j] == -1) 1255 { 1256 break; 1257 } 1258 if (map[i][j] != '\n') 1259 { 1260 printf("%c", map[i][j]); 1261 } 1262 else if (map[i][j] == '\n') 1263 { 1264 printf("%c", map[i][j]); 1265 break; 1266 } 1267 1268 } 1269 if (map[i][j] == -1) 1270 { 1271 break; 1272 } 1273 } 1274 } 1275 1276 /* Function: 读取地图 */ 1277 void ReadMap(char (*map)[N], FILE *fp, int *x, int *y,int *suc) 1278 { 1279 int i, j; 1280 int n; 1281 1282 i = j = 0; 1283 while(!feof(fp)) /* 未读到文件末尾 */ 1284 { 1285 fscanf_s(fp, "%c", &map[i][j], sizeof(char)); 1286 if (map[i][j] == '*') 1287 { 1288 (*suc)++; /* suc的值为当前关卡目标点的个数 */ 1289 } 1290 if (map[i][j] == 'I') /* 读取到玩家图标 */ 1291 { 1292 *x = j; 1293 *y = i; 1294 } 1295 n = j; /* 存储j自增之前的值,方便判断是不是换行符*/ 1296 j++; 1297 if (map[i][n] == '\n') 1298 { 1299 i++; 1300 j = 0; 1301 } 1302 1303 } 1304 map[i][j-1] = EOF;/* 作为文件结束标志的EOF不会被读取存储到二维数组中,需要手动添加 */ 1305 } 1306 1307 /* Function: 初始化地图 */ 1308 void InitMap(char (*map)[N]) 1309 { 1310 int i, j; 1311 1312 for (i = 0;i < N; i++) 1313 { 1314 for (j = 0; j < N; j++) 1315 { 1316 map[i][j] = ' '; 1317 } 1318 } 1319 } 1320 1321 /* Function: 判断文件打开是否成功 */ 1322 void JudgeFopen_s(errno_t err) 1323 { 1324 if (err != 0) 1325 { 1326 printf("地图文件打开失败,请检查地图文件\n"); 1327 system("pause"); 1328 exit(0); 1329 } 1330 }View Code
刚开始想尝试下多文件编程就把两个子函数写在另外一个c文件里面了,函数的声明放在的Game.h里面
SRE实战 互联网时代守护先锋,助力企业售后服务体系运筹帷幄!一键直达领取阿里云限量特价优惠。Move.c

1 #include <Windows.h> 2 #include "Game.h" 3 4 /* Function: WASD移动*/ 5 /* Date:2019/4/10 */ 6 int MoveByWasd(int move) 7 { 8 switch(move) 9 { 10 case 'A':case 'a': return LEFT; 11 case 'D':case 'd': return RIGHT; 12 case 'W':case 'w': return UP; 13 case 'S':case 's': return DOWN; 14 default: return WRONG; 15 } 16 } 17 18 /* Function: 隐藏光标 */ 19 /* Date:2019/4/10 */ 20 void HideCursor () 21 { 22 HANDLE hOut; 23 CONSOLE_CURSOR_INFO cur; 24 25 cur.bVisible = 0; /* 光标不可见 */ 26 cur.dwSize = 1; /* 光标大小必须要设定一个1~100之间的值,不然光标无法隐藏 */ 27 hOut = GetStdHandle(STD_OUTPUT_HANDLE); /* 获取标准输出句柄 */ 28 SetConsoleCursorInfo(hOut, &cur); /* 隐藏光标 */ 29 } 30 31 /* Function: 光标转移到指定位置 */ 32 /* Date:2019/4/12 */ 33 void gotoxy(int x, int y) 34 { 35 COORD pos = {x, y}; /* 光标坐标 */ 36 HANDLE hOut; 37 38 hOut = GetStdHandle(STD_OUTPUT_HANDLE); /* 获取标准输出句柄 */ 39 SetConsoleCursorPosition(hOut,pos); /* 移动光标到指定位置 */ 40 }View Code
Game.h

1 int MoveByWasd(int move); 2 void gotoxy(int x, int y); 3 void HideCursor (); 4 5 #ifndef _GAME_H 6 #define _GAME_H 7 8 #define LEFT 1 9 #define RIGHT 2 10 #define UP 3 11 #define DOWN 4 12 #define WRONG 5 13 14 #endifView Code
代码本身存在很多问题,函数命名不规范、if-else嵌套过多、switch重复判断,后面会尝试优化下逻辑,将代码行数控制到1000行以内
最终效果:

更多精彩