# 2. 扫雷游戏的初步实现

## 2.1 建立扫雷分布模块

``````void menu()
{
printf("********************************n");
printf("**********  1.play   ***********n");
printf("**********  0.exit   ***********n");
printf("********************************n");
}

``````

``````int main()
{
int input = 0;

do
{
printf("请选择选项:>");
scanf("%d", &input);
switch (input)
{
case 1:
game();
break;
case 0:
printf("退出扫雷游戏n");
break;
default:
printf("选择错误，请重新开始选择n");
break;
}
} while (input);
return 0;
}
``````

## 2.2 创建名为board的二维数组并进行棋盘初始化

（11X11的棋盘是为了方便统计棋盘边缘的雷的数量，这样就不会越界访问了，用户进行扫雷的棋盘是9X9）

``````#define ROW 9
#define COL 9
#define ROWS ROW+2
#define COLS COL+2

#define EASY_COUNT 10

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

//初始化棋盘
void InitBoard(char board[ROWS][COLS], int rows, int cols, char set);
``````

set变量代表着两个初始化11*11的棋盘，用0和 * 代替
ROW和COL是我们对两个数组操作时需要用到的，ROWS和COLS是我们传递数组给函数时告诉函数这是11X11的数组。

``````#include "game.h"

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;
}
}
}
``````

## 2.3 打印棋盘

game.h声明

``````//打印棋盘
void DisplayBoard(char board[ROWS][COLS], int row, int col);
``````

game.c打印

``````void DisplayBoard(char board[ROWS][COLS], int row, int col)
{
int i = 0;
int j = 0;
printf("******* 扫雷 *******n");
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");
}
}
``````

# 3. 接下来该讨论的事情

## 3.1 布置雷

game.h声明

``````//布置雷
void SetMine(char mine[ROWS][COLS], int row, int col);
``````

game.c打印

``````void SetMine(char mine[ROWS][COLS], int row, int col)
{
int count = EASY_COUNT;
while (count)
{
//rand能产生的随机数范围是0~32767
//0~8+1
//1~9
//srand((unsigned int)time(NULL))使用rand
int x = rand() % row + 1;
int y = rand() % col + 1;
if (mine[x][y] == '0')
{
mine[x][y] = '1';
count--;
}
}
}
``````

## 3.2 排查雷

game.h声明

``````//排查雷
void FindMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col);
``````

game.c打印

``````void FindMine(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-EASY_COUNT)
{
printf("请输入要排查的坐标:>");
scanf("%d %d", &x, &y);
if (x >= 1 && x <= row && y >= 1 && y <= col)
{
if (show[x][y] == '*')
{
if (mine[x][y] == '1')
{
printf("很遗憾，你被炸死n");
DisplayBoard(mine, ROW, COL);
break;
}
else
{
//如果该坐标不是雷，就要统计这个坐标周围有几个雷
int count = GetMineCount(mine, x, y);
show[x][y] = count + '0';
DisplayBoard(show, ROW, COL);
win++;
}
}
else
{
printf("该位置已经被排查n");
}
}
else
{
printf("排查的坐标非法，请重新输入n");
}
}
if (win == row * col - EASY_COUNT)
{
printf("恭喜你，排雷成功n");
DisplayBoard(mine, ROW, COL);
}
}
``````

## 3.3 统计坐标周围有几个雷

``````int GetMineCount(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');
}
``````

# 4. 完整扫雷游戏的实现

## 4.1 game.h

``````#define ROW 9
#define COL 9
#define ROWS ROW+2
#define COLS COL+2

#define EASY_COUNT 10

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

//初始化棋盘
void InitBoard(char board[ROWS][COLS], int rows, int cols, char set);

//打印棋盘
void DisplayBoard(char board[ROWS][COLS], int row, int col);

//布置雷
void SetMine(char mine[ROWS][COLS], int row, int col);

//排查雷
void FindMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col);

``````

## 4.2 game.c

``````#include "game.h"

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 DisplayBoard(char board[ROWS][COLS], int row, int col)
{
int i = 0;
int j = 0;
printf("******* 扫雷 *******n");
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 SetMine(char mine[ROWS][COLS], int row, int col)
{
int count = EASY_COUNT;
while (count)
{
//0~32767
//0~8+1
//1~9
int x = rand() % row + 1;
int y = rand() % col + 1;
if (mine[x][y] == '0')
{
mine[x][y] = '1';
count--;
}
}
}

int GetMineCount(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 FindMine(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-EASY_COUNT)
{
printf("请输入要排查的坐标:>");
scanf("%d %d", &x, &y);
if (x >= 1 && x <= row && y >= 1 && y <= col)
{
if (show[x][y] == '*')
{
if (mine[x][y] == '1')
{
printf("很遗憾，你被炸死n");
DisplayBoard(mine, ROW, COL);
break;
}
else
{
//如果该坐标不是雷，就要统计这个坐标周围有几个雷
int count = GetMineCount(mine, x, y);
show[x][y] = count + '0';
DisplayBoard(show, ROW, COL);
win++;
}
}
else
{
printf("该位置已经被排查n");
}
}
else
{
printf("排查的坐标非法，请重新输入n");
}
}
if (win == row * col - EASY_COUNT)
{
printf("恭喜你，排雷成功n");
DisplayBoard(mine, ROW, COL);
}
}
``````

## 4.3 扫雷.c

``````#include "game.h"

{
printf("*******************************n");
printf("*******    1. play      *******n");
printf("*******    0. exit      *******n");
printf("*******************************n");
}

void game()
{
//mine数组是专门存放布置好的雷的信息
char mine[ROWS][COLS] = {0};
//show数组是专门存放排查出的雷的信息
char show[ROWS][COLS] = {0};
//初始化棋盘
InitBoard(mine, ROWS, COLS, '0');//'0'
InitBoard(show, ROWS, COLS, '*');//'*'
//打印棋盘
DisplayBoard(show, ROW, COL);

//布置雷
SetMine(mine, ROW, COL);
//DisplayBoard(mine, ROW, COL);
//排查雷
FindMine(mine, show, ROW, COL);
}

int main()
{
int input = 0;
srand((unsigned int)time(NULL));
do
{
printf("请选择:>");
scanf("%d", &input);
switch (input)
{
case 1:
game();
break;
case 0:
printf("退出游戏n");
break;
default:
printf("选择错误n");
break;
}
} while (input);

return 0;
}
``````

THE END