下面是我在学习扫雷后,自己整理思路写出的代码,并完成了拓展以及优化,还有对胜利条件,失败条件设立彩蛋,分为三个文件,两个源文件,一个头文件,我会在附属文件里定义函数,在头文件声明,而主函数所在的源文件短小精悍。
//这个是附属源文件 #define _CRT_SECURE_NO_WARNINGS 1 #include "game.h" void menu() { printf("*************************\n"); printf("*******1. 进入游戏*******\n"); printf("*******0. 退出游戏*******\n"); printf("*************************\n"); } void print_board(char show[ROWS][COLS], int row, int col) { printf("-----------------扫雷------------------\n"); int i, j; for (j = 1; j <= col + 1; j++) { printf("--- "); } printf("\n"); for (j = 0; j <= col; j++) printf(" %d】", j); printf("\n"); for (j = 0; j <= col; j++) printf("--- "); printf("\n"); for (i = 1; i <= row; i++) { printf(" %d】", i); for (j = 1; j <= col; j++) { printf(" %c |", show[i][j]); } printf("\n"); for (j = 1; j <= col + 1; j++) { printf("--- "); } printf("\n"); } } void init_board(char show[ROWS][COLS], int row, int col, char a) { int i, j; for (i = 0; i < row; i++) { for (j = 0; j < col; j++) show[i][j] = a; } } void setmine(char mine[ROWS][COLS], int row, int col) { int i; for (i = 0; i < NUM; i++) { int x = rand() % row + 1; int y = rand() % col + 1; if (mine[x][y] == '0') mine[x][y] = '1'; else i--; } } int get_mine_num(char mine[ROWS][COLS], int row, int col) { return (mine[row + 1][col + 1] + mine[row][col + 1] + mine[row + 1][col] + mine[row - 1][col + 1] + mine[row + 1][col - 1] + mine[row - 1][col - 1] + mine[row][col - 1] + mine[row - 1][col] - '0' * 8); } void it_is_0(char mine[ROWS][COLS], char show[ROWS][COLS],int x,int y) { int i , j; if (get_mine_num(mine, x, y) == 0) { show[x][y] = ' '; for (i = -1; i <= 1; i++) { if (x + i == 0 || x + i == ROW + 1) continue; for (j = -1; (j <= 1) && (y + i != 0) && (y + i != COL + 1); j++) { if (y + j == 0 || y + j != COL + 1) if (!(i == 0 && j == 0) && show[x + i][y + j] == '*') { show[x + i][y + j] = get_mine_num(mine, x + i, y + j) + '0'; it_is_0(mine, show, x+i, y+j); } } } } } int howmany_mine(char show[ROWS][COLS], int row, int col) { int n = 0, i, j; for (i = 1; i <= row; i++) { for (j = 1; j <= col; j++) { if (show[i][j] == '*') n++; } } return n; } void find_mine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col) { int x = 0, y = 0; while ((howmany_mine(show,ROW,COL))>NUM) { printf("\n请输入你要排查的位置:>"); scanf("%d%d", &x, &y); if (x >= 1 && x <= row && y >= 1 && y <= col) { if (show[x][y] != '*') { printf("这个位置被排查过了!\n"); Sleep(2500); } if (mine[x][y] == '1') { system("cls"); printf("Oh!"); Sleep(1000); system("cls"); printf("NO!"); Sleep(1000); system("cls"); printf("脑子被雷炸没了!\n"); print_board(show, ROW, COL); printf("这个是答案坐标,1就是雷的位置,0是安全点\n"); print_board(mine, ROW, COL); break; } else { show[x][y] = get_mine_num(mine, x, y) + '0'; it_is_0(mine, show, x, y); system("cls"); print_board(show, ROW, COL); } } else { printf("输入错误,请重新输入\n"); print_board(mine, ROW, COL); } } if ((howmany_mine(show, ROW, COL)) == NUM) { system("cls"); char arr5[] = "ohhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh"; char arr6[] = " "; int left2 = 0; int right2 = strlen(arr5) - 1;//用sizeof会把\0算进去。 for (; left2 <= right2; left2++) { arr6[left2] = arr5[left2]; printf("%s\n", arr6); printf("%s\n", arr6); printf("%s\n", arr6); printf("%s\n", arr6); printf("%s\n", arr6); printf("%s\n", arr6); printf("%s\n", arr6); printf("%s\n", arr6); Sleep(25); system("cls"); } char arr1[] = "gong xi ni cheng gong la !"; char arr2[] = " "; int left = 0; int right = strlen(arr1) - 1; for (; left <= right; left++, right--) { arr2[left] = arr1[left]; arr2[right] = arr1[right]; printf("%s\n", arr2); Sleep(250); system("cls"); } printf("gong xi ni cheng gong la !"); Sleep(1000); system("cls"); char arr3[] = "CONGRATULATION!"; char arr4[] = " "; int left1 = 0; int right1 = strlen(arr3) - 1; for (; left1 <= right1; left1++, right1--) { arr4[left1] = arr3[left1]; arr4[right1] = arr3[right1]; printf("%s\n", arr4); Sleep(250); } system("cls"); printf("CONGRATULATION!"); Sleep(1000); system("cls"); printf("恭喜你!!!!!!!!!!!!!!!!!"); system("cls"); printf("恭喜你呀恭喜你\n"); Sleep(500); printf(" 恭喜你呀恭喜你~\n"); Sleep(500); printf("恭喜你呀恭喜你\n"); Sleep(500); printf(" 恭喜你呀恭喜你~\n"); Sleep(500); printf("恭喜你呀恭喜你\n"); Sleep(500); printf(" 恭喜你呀恭喜你~\n"); Sleep(500); printf("恭喜你呀恭喜你\n"); Sleep(500); printf(" 恭喜你呀恭喜你~\n"); Sleep(500); system("cls"); print_board(show, ROW, COL); printf("恭喜你成功了!\n这个是布雷的坐标图,1因为雷点,0为安全点\n"); print_board(mine, ROW, COL); } } void game() { char mine[ROWS][COLS] = { 0 }; char show[ROWS][COLS] = { 0 }; init_board(mine, ROWS, COLS, '0'); init_board(show, ROWS, COLS, '*'); print_board(show, ROW, COL); setmine(mine, ROW, COL); find_mine(mine, show, ROW, COL); } void start() { srand((unsigned int)time(NULL)); int count = 2; int n = 0; do { menu(); printf("请玩家选择:>"); scanf("%d", &n); switch (n) { case 1: { system("cls"); game(); break; } case 0: { if (count == 1) printf("好吧,下次再玩!\n"); if (count == 2) printf("你确定要退出游戏?\n"); count--; break; } default: printf("\n请重新输入:>"); break; } } while (count); }
这个是主函数所在源文件 #define _CRT_SECURE_NO_WARNINGS 1 #include "game.h" int main() { start(); return 0; }
而对于游戏创作,应该定好功能,分好模块,设立函数(先直接写函数名,然后再去定义),再去想算法,(临时的想法有可能成立,敢于尝试!!!)
这个扫雷有个很巧妙的地方,就是设立了两个棋盘,一个是布置雷的,一个是展示的,但也很正常,因为布置雷的是“答案”,而我们展示肯定是不能给答案的。
还有一个就是表格扩大一圈,目的是为了测试边边的地点周围的雷的个数,而打印什么,还是自己说了算。
还有优化方面,我优化了表格可以自定义(数组定义时不能填变量,但是可以填宏),还有使用递归去使得判定雷的个数是0的时候自动扩张,但是这样判定胜利条件的方法就要改变。
而观感优化了表格的形式,我加了一些线条,还有坐标提示,eg 0】| 1】.......,使得填的时候更加舒适,以及结束时候失败以及胜利设立有趣的彩蛋。
总而言之就是先定好框架,有自己的思路,一步一步来,需要什么函数大胆设立下来,然后去定义去实现,想到一些算法就大胆去干!