效果展示

必要设置

我们需要两个11*11的二维数组。 因为如果只设置9*9,那么矩阵的边、角将会受到限制。

具体模块代码

实现扫雷游戏的必要头文件以及部分函数声明(game.h文件)
//需要的头文件 #include <stdio.h> #include <stdlib.h> #include <time.h> //需要的宏定义
#define ROW 9 #define COL 9 #define ROWS ROW+2 #define COLS COL+2 #define COUNT
10 //需要使用的函数(不完全) void InitBoard(char board[ROWS][COLS], int rows, int cols,
char set);//初始化数组的函数声明 void PrintBoard(char board[ROWS][COLS], int row, int
col);//打印数组的函数声明 void Set_Mine(char mine[ROWS][COLS], int row, int
col);//埋雷函数声明 void Find_Mine(char mine[ROWS][COLS],char show[ROWS][COLS], int
row, int col);//排雷函数声明
 扫雷游戏的主函数(test.c文件)
void game() { //定义两个数组,一个用来实操,一个用来展示 char mine[ROWS][COLS] = { 0 }; char
show[ROWS][COLS] = { 0 }; //初始化数组 InitBoard(mine, ROWS, COLS, '0');
InitBoard(show, ROWS, COLS, '*'); //打印 PrintBoard(show, ROW, COL); //对实操数组埋雷
Set_Mine(mine, ROW, COL); //PrintBoard(mine, ROW, COL); //对实操数组进行排雷,即玩家游戏
Find_Mine(mine,show, ROW, COL); } void menu() { printf("\n"); printf("\n");
printf("\n"); printf("***************************************\n");
printf("******1.PLAY 0.EXIT**********\n");
printf("***************************************\n"); printf("\n");
printf("\n"); printf("\n"); } int main() { srand((unsigned int)time(NULL)); int
input = 0; do { menu();//简易菜单 printf("请选择:>"); scanf("%d", &input); switch
(input) { case 1: game();//游戏主体逻辑函数 break; case 0: printf("退出游戏\n"); break;
default: break; } } while (input); return 0; }
扫雷游戏具体功能函数(game.c文件)
void InitBoard(char board[ROWS][COLS], int rows, int cols, char set) { int i =
0; int j = 0; for (i = 0; i < rows; i++) { for (j = 0; j < cols; j++) {
board[i][j] = set; } } } //打印数组 void PrintBoard(char board[ROWS][COLS], int
row, int col) { int i = 0; int j = 0; //显示坐标列序 for (j = 0; j <= col; j++) {
printf("%d ", j); } printf("\n"); for (i = 1; i <= row; i++) { printf("%d ",
i);//显示坐标行序 for (j = 1; j <= col; j++) { printf("%c ", board[i][j]); }
printf("\n"); } } //埋雷 void Set_Mine(char mine[ROWS][COLS], int row, int col) {
int x = 0; int y = 0; int count = 10; while (count) { x = rand() % row+1; y =
rand() % col+1; if (mine[x][y] == '0') { mine[x][y] = '1'; count--; } } } void
Expand(char mine[ROWS][COLS], char show[ROWS][COLS], int x, int y) {
//不满足显示条件的一律退出递归 if (x == 0 || y == 0 || x == ROWS - 1 || y == COLS - 1)
return; if (show[x][y] != '*') return; //递归实现展开功能 int count = Num_Mine(mine, x,
y); if (count > 0) { show[x][y] = count+'0'; } else if (count == 0) {
show[x][y] = '0'; Expand(mine, show, x-1, y); Expand(mine, show, x-1, y-1);
Expand(mine, show, x, y-1); Expand(mine, show, x+1, y-1); Expand(mine, show,
x+1, y); Expand(mine, show, x+1, y+1); Expand(mine, show, x, y+1); Expand(mine,
show, x-1, y+1); } } //目的坐标周边雷的个数 int Num_Mine(char mine[ROWS][COLS], int x,
int y) { return mine[x - 1][y] + mine[x - 1][y - 1] + mine[x][y - 1] + mine[x +
1][y + 1] + mine[x + 1][y] + mine[x + 1][y - 1] + mine[x][y + 1] + mine[x -
1][y + 1] - 8 * '0'; } //排雷函数(玩家游戏方式) void Find_Mine(char mine[ROWS][COLS],char
show[ROWS][COLS], int row, int col) { int x = 0; int y = 0; int win = 0; while
(win<row*col-COUNT) { printf("请输入坐标:>"); scanf("%d%d", &x, &y); if (x >= 1 && x
<= 9 && y >= 1 && y <= 9) { if (mine[x][y] == '1') { printf("你被炸死了\n");
PrintBoard(mine, ROW, COL); break; } else if (mine[x][y] == '0') { Expand(mine,
show, x, y);//递归展开 PrintBoard(show, ROW, COL); win++; } } else {
printf("坐标非法,请重新输入\n"); break; } } if (win == row * col - COUNT) {
printf("恭喜你,通关游戏\n"); } }
 问题分析

问题一:为什么统计目的坐标周围雷的个数的代码是这样写的?
int Num_Mine(char mine[ROWS][COLS], int x, int y) { return mine[x - 1][y] +
mine[x - 1][y - 1] + mine[x][y - 1] + mine[x + 1][y + 1] + mine[x + 1][y] +
mine[x + 1][y - 1] + mine[x][y + 1] + mine[x - 1][y + 1] - 8 * '0'; }
答:我们可以先分析ASCLL码表。

 

可以看到字符1和字符0的差为1,我们的代码就是把周边8个坐标的字符相加,减去8个字符0,就能够得到确切的雷个数。

问题二:递归是如何实现的?

答:递归的核心思想非常简单,就如我们写代码时一样,如果我们的目的坐标周围8个坐标没有雷,那么目的坐标打印出来的是0。既然是0,那么我们就可以向外拓展(因为周围8个坐标没有雷),直到拓展到某一坐标周围8个坐标有雷为止。

 当我们选中(8,5)这个坐标,因为周围没雷,所以就得向外扩展。

 

我们假定扩展这个0(实际上目的坐标旁边的每个0都会扩展),可以看到,只能继续往右上角的0扩展。这个规则我们已经写进代码里面了。

技术
下载桌面版
GitHub
百度网盘(提取码:draw)
Gitee
云服务器优惠
阿里云优惠券
腾讯云优惠券
华为云优惠券
站点信息
问题反馈
邮箱:ixiaoyang8@qq.com
QQ群:766591547
关注微信