文章目录
完整扫雷
1. 说明
扫雷大家应该都知道,翻开一个格子,显示的数字就是周围 8 格所含的雷数。例如,红色框框里的 1 周围 8 格就只有一个雷。
2. 思路
-
我们定义两个数组来实现,show 数组存放玩家看到的棋盘,mine 数组存放隐藏的雷盘
-
这两个数组搭配使用,就能计算某个位置周围的雷数,并且修改 show 数组来显示这个位置的雷数。
-
但是如果计算边缘格子周围的雷数时,数组会越界。
-
我们只要在周围留一圈就能解决这个问题
- 如下图所示,假设我们要玩 9x9 的大小,我们的数组大小就定义为 11x11
3. 各个功能实现
3.1 雷盘初始化与打印
1)雷盘定义
- 初始化雷盘
- 初始化 show,mine 两个数组,show 存放 ‘*’ , mine 存放 ‘0’
void init_board(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;
}
}
}
打印雷盘
//打印 show 雷盘
void display_board(char board[ROWS][cols], int row, int col)
{
int i = 0;
int j = 0;
//这里打印上面一行数字
printf("|");
for (j = 0; j <= col; j++)
{
printf(" %-2d |", j);
}
printf("\n");
for (i = 1; i <= row; i++)
{
printf("|");
for (j = 0; j <= col; j++)
{
printf("----|");//打印两行之间的分割线
}
printf("\n");
printf("|");
printf(" %-2d |", i);//打印左边一列数字
for (j = 1; j <= col; j++)
{
printf(" %2c |",board[i][j]);//打印show数组
}
printf("\n");
}
}
效果图:
2) 随机布置雷
-
随机布置雷,将 mine 中的 ‘0’ 改为 ‘1’
-
随机布置雷,在 mine 数组里随机设置 COUNT 个雷
void set_mine(char mine[ROWS][cols], int row, int col)
{
int count = COUNT;
while (count)
{
int x = rand() % row + 1;
int y = rand() % col + 1;
if (mine[x][y] == '0')
{
mine[x][y] = '1'; //地雷设置为 '1'
count--;
}
}
}
3.2 玩家排查雷
1) 获取坐标周围雷数
1… 计算该坐标在 mine 中 周围 '1’的个数
2… 获取一个格子周围的雷数
int get_mine_count(char mine[ROWS][cols], int x, int y)
{
//mine 中存放的是字符'0' 和 '1'
return (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] +
mine[x + 1][y] +
mine[x + 1][y + 1] - 8 \* '0');
}
2) 递归展开
- 我们玩扫雷时,翻开一个格子会展开一片,如上图所示,翻开黑格子,展开紫色区域。
- 我们可以用递归来实现
- 当这个格子周围没雷时,显示空白,然后继续递归它周围的八个格子
- 有雷时,显示雷数,停止递归。
void expand(char mine[ROWS][cols], char show[ROWS][cols], int x, int y, int\* win)
{
i