# 用C写小游戏（扫雷）

2022-08-06 08:11:46深夜吞食

# 实现的基本要素

## 菜单

``````void Meun()
{

printf("|----------------------------------------|\n");
printf("| 1.开始游戏 0.退出游戏 |\n");
printf("|----------------------------------------|\n");
}
``````

main函数的主体逻辑

``````int main()
{

int input = 0;
do
{

printf("请选择：");
scanf("%d", &input);
switch (input)
{

case 1:
game();
break;
case 0:
printf("退出游戏!\n");
break;
default:
system("cls");
printf("输入错误，请重新输入!\n");
break;
}
} while (input);
return 0;
}
``````

## 雷区设置与打印

### 1. 雷区

``````//雷区有效区我们用ROW和COL表示，我们改变ROW和COL就可以随意改变雷区大小。
#define ROW 9
#define COL 9
//二维数组大小我们用ROWS和COLS来表示下标。
#define ROWS ROW + 2
#define COLS COL + 2

#define MINE 10 //雷的数目
``````

``````void game()
{

//定义用于存放雷和显示雷的数组
char mine[ROWS][COLS];
char show[ROWS][COLS];
}
``````

``````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;   //set表示要初识化的字符
}
}
}

void game()
{

//定义用于存放雷和显示雷的数组
char mine[ROWS][COLS];
char show[ROWS][COLS];
InitBoard(mine, ROWS, COLS, '0');
InitBoard(show, ROWS, COLS, '*');
}
``````

### 2.布置雷

``````void SetMine(char board[ROWS][COLS], int row, int col)
{

int count = MINE; //宏定义雷，好让我们随意改变
while (count)
{

int x = rand() % row + 1;      //随机生成雷的坐标
int y = rand() % col + 1;
if (board[x][y] == '0')        //检查该位置是否已经有雷
{

board[x][y] = '1';
count--;                  //每生成一个雷就减一次
}
}
}
``````

### 3. 打印雷区

``````void PrintBorad(char board[ROWS][COLS], int row, int col)
{

int i = 0;
int j = 0;
for (i = 1; i <= row; i++)
{

for (j = 1; j <= col; j++)
{

printf("%c ", board[i][j]);
}
printf("\n");
}
}
``````
``````	SetMine(mine, ROW, COL);
PrintfBoard(mine, ROW, COL);
PrintfBoard(show, ROW, COL);
``````

``````void PrintBoard(char board[ROWS][COLS], int row, int col)
{

int i = 0;
int j = 0;
for (i = 0; i <= row; i++)   //打印行号
printf("%d ", i);
printf("\n");
for (i = 1; i <= row; i++)
{

printf("%d|", i);   //打印列号
for (j = 1; j <= col; j++)
{

printf("%c ", board[i][j]);
}
printf("|");
printf("\n");
}
for (i = 0; i <= 2 * row+2; i++)
printf("-");
printf("\n");
}
``````

## 雷范围标识与排雷

### 1. 雷范围标识

``````int MineCount(char board[ROWS][COLS], int x, int y)
{

int i = 0;
int j = 0;
int count = 0;
for (i = x - 1; i <= x + 1; i++)
{

for (j = y - 1; j <= y + 1; j++)
{

if (board[i][j] == '1')
{

count++;
}
}
}
return count;
}
``````

### 2. 排雷

1. 玩家坐标是否走过同样的位置
2. 玩家是不是踩雷
3. 玩家排雷坐标是不是超过雷区或者输入其他字符
4. 排雷结束的条件

``````void FindMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col)
{

int x = 0;
int y = 0;
int judge = 0; //判断是否排完雷
int* sz = judge;
while (judge < row * col - MINE) // 若是坐标还没有排完雷继续游戏
{

printf("请输入坐标->");
scanf("%d %d", &x, &y);
if (x >= 1 && x <= row && y >= 1 && y <= col)   //判断坐标合法性
{

if (mine[x][y] == '1')
{

system("cls");
printf("很遗憾，你被炸死了!\n");
PrintBoard(mine, row, col);
break;
}
else
{

if (show[x][y] != '*')   //判断是否重复排查
{

printf("该坐标已被排查，请重新输入!\n");
continue;  //直接进入下一次循环
}
else
{

ShowBlanks(mine, show, row, col, x, y, sz);  //展示一片除提示雷的空白
system("cls");
PrintBoard(show, row, col);
}
}
}
else
{

printf("输入错误，请重新输入!\n");
system("pause");
getchar(); 防止输入错误造成死循环
}
}
if (judge == row * col - MINE_COUNT)
{

system("cls");
printf("恭喜你，排雷成功!\n");
PrintBoard(show, row, col);
return;
}
}
``````

``````void ShowBlanks(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col, int x, int y, int* sz)
{

if (x >= 1 && x <= row && y >= 1 && y <= col)  //判断坐标是否为排查范围内
{

int num = MineCount(mine, x, y);   //获取坐标周围雷的个数
if (num == 0)
{

(*sz)++;
show[x][y] = ' ';   //如果该区域没有雷就设置成空格
int i = 0;
int j = 0;
for (i = x - 1; i <= x + 1; i++)
{

for (j = y - 1; j <= y + 1; j++)
{

if (show[i][j] == '*')    //防止已经排查过的坐标再次递归
ShowBlanks(mine, show, row, col, i, j, sz);
}
}
}
else
{

(*sz)++;
show[x][y] = num + '0';
}
}
}
``````

# 代码展示

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

#define ROW 9
#define COL 9
#define ROWS ROW + 2
#define COLS COL + 2
#define MINE 10

void Meun()
{

printf("|----------------------------------------|\n");
printf("| 1.开始游戏 0.退出游戏 |\n");
printf("|----------------------------------------|\n");
}

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 SetMine(char board[ROWS][COLS], int row, int col)
{

int count = MINE;
while (count)
{

int x = rand() % row + 1;
int y = rand() % col + 1;
if (board[x][y] == '0')
{

board[x][y] = '1';
count--;
}
}
}

void PrintBoard(char board[ROWS][COLS], int row, int col)
{

int i = 0;
int j = 0;
for (i = 0; i <= row; i++)
printf("%d ", i);
printf("\n");
for (i = 1; i <= row; i++)
{

printf("%d|", i);
for (j = 1; j <= col; j++)
{

printf("%c ", board[i][j]);
}
printf("|");
printf("\n");
}
for (i = 0; i <= 2 * row+2; i++)
printf("-");
printf("\n");
}

int MineCount(char board[ROWS][COLS], int x, int y)
{

int i = 0;
int j = 0;
int count = 0;
for (i = x - 1; i <= x + 1; i++)
{

for (j = y - 1; j <= y + 1; j++)
{

if (board[i][j] == '1')
{

count++;
}
}
}
return count;
}

void ShowBlanks(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col, int x, int y, int* sz)
{

if (x >= 1 && x <= row && y >= 1 && y <= col)
{

int num = MineCount(mine, x, y);
if (num == 0)
{

(*sz)++;
show[x][y] = ' ';
int i = 0;
int j = 0;
for (i = x - 1; i <= x + 1; i++)
{

for (j = y - 1; j <= y + 1; j++)
{

if (show[i][j] == '*')
ShowBlanks(mine, show, row, col, i, j, sz);
}
}
}
else
{

(*sz)++;
show[x][y] = num + '0';
}
}
}

void FindMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col)
{

int x = 0;
int y = 0;
int judge = 0;
int* sz = &judge;
while (judge < row * col - MINE)
{

printf("请输入坐标->");
scanf("%d %d", &x, &y);
if (x >= 1 && x <= row && y >= 1 && y <= col)
{

if (mine[x][y] == '1')
{

system("cls");
printf("很遗憾，你被炸死了!\n");
PrintBoard(mine, row, col);
printf("1是雷0是安全区\n");
break;
}
else
{

if (show[x][y] != '*')
{

printf("该坐标已被排查，请重新输入!\n");
continue;
}
else
{

ShowBlanks(mine, show, row, col, x, y, sz);
system("cls");
PrintBoard(show, row, col);
}
}
}
else
{

printf("输入错误，请重新输入!\n");
system("pause");
getchar();
}
}
if (judge == row * col - MINE)
{

system("cls");
printf("恭喜你，排雷成功!\n");
PrintBoard(show, row, col);
return;
}
}

void game()
{

char mine[ROWS][COLS];
char show[ROWS][COLS];
InitBoard(mine, ROWS, COLS, '0');
InitBoard(show, ROWS, COLS, '*');
SetMine(mine, ROW, COL);
system("cls");   //清除菜单，美观整洁
PrintBoard(show, ROW, COL);
FindMine(mine, show, ROW, COL);
}

int main()
{

//设置随机数的种子
srand((unsigned int)time(NULL));
int input = 0;
do
{

Meun();
printf("请选择：");
scanf("%d", &input);
switch (input)
{

case 1:
game();
break;
case 0:
printf("退出游戏!\n");
break;
default:
system("cls");
printf("输入错误，请重新输入!\n");
break;
}
} while (input);
return 0;
}

``````

https://blog.csdn.net/weixin_57663528/article/details/126087140