💣功能需求:有一个矩阵,里面随机分布雷,翻开全部非雷区域,则游戏胜利;如果翻开了炸弹所在区域,则游戏失败。在翻开的过程中,会有一些提示(在翻开位置显示雷数)。
💡实现:
一个矩阵做显示,另一个矩阵保存雷所在位置;
从键盘捕捉输入:要翻开的位置的坐标;
根据输入的坐标,判断是否有雷。如果有雷则游戏失败;如果没有雷且全部非雷位置均被翻开,则游戏胜利。
🚩流程设计:
有两个矩阵,一个为雷区分布,另一个为显示数字矩阵;
初始化两个矩阵:显示矩阵:初始化为空格表示没有被翻开;
雷区矩阵:第一次翻开后再去初始化(第一次翻开的位置不能是雷);
翻开矩阵对应位置(初始化雷区);
判断是否踩雷:踩雷则游戏失败;没有踩雷且没有胜利,则统计周围雷区数目,并将数字显示在显示矩阵中;
刷新显示。
欢迎界面
int welcome()
{
printf("**********欢迎进入扫雷游戏**********\n");
printf("********** 1. 开始游戏 **********\n");
printf("********** 2. 退出游戏 **********\n");
printf("************************************\n");
printf("请输入你的选择:");
int input;
scanf("%d", &input);
return input;
}
初始化两个矩阵
#define ROW 3
#define COL 3
#define ROWS 4
#define COLS 4
void init_show(char matrix[][COLS], int row, int col)
{
for (int i = 0; i < row; i++)
{
for (int j = 0; j < col; j++)
{
matrix[i][j] = ' ';
}
}
}
void display(char matrix[][COLS], int row, int col)
{
for (int i = 0; i < row; i++)
{
for (int j = 0; j < col; j++)
{
if (i == 0)//第0行的列号显示
{
printf(" %d |", j);
continue;
}
if (j == 0)//第0列的行号显示
{
printf(" %d |", i);
}
else //不在0行0列时
{
printf(" %c |", matrix[i][j]);
}
}
printf("\n---|---|---|---|\n");
}
}
void game()
{
char mine[ROWS][COLS];
char show[ROWS][COLS];
init_show(show,ROWS,COLS);
display(show, ROWS, COLS);
}
运行结果:
![](https://i-blog.csdnimg.cn/blog_migrate/d429c1b079cbf69e752e0fcdbbc1c3c7.png)
初始化显示矩阵
将矩阵内容设置为空格,表示没有被翻开。
int Judge_win(char matrix[][COLS], int row, int col)
{
int count = 0;
for (int i = 1; i < row; i++)//第0行和第0列不计算在内
{
for (int j = 1; j < col; j++)
{
if (matrix[i][j] == 0)
{
matrix[i][j] = ' ';
count++;//计算没有被翻开位置的数量
}
}
}
if (count = MINE_COUNT)//没有被翻开位置的数量等于雷的数量时游戏胜利
{
return 1;
}
return 0;
}
设置雷区
void init_mine(char matrix[][COLS], int x,int y,int row, int col)
{
//在雷区矩阵中,1表示有雷,0表示没有雷,此时x和y坐标位置不能有雷
for (int i = 0; i < row; i++)
{
for (int j = 0; j < col; j++)
{
matrix[i][j] = 0;
}
}
int count = MINE_COUNT;
while (count>0)
{
int mx = (rand() % ROW) + 1;
int my = (rand() % COL) + 1;//产生一个随机坐标用来放置雷
if ((mx == x) && (my == y))
{
continue;//x,y位置不能放雷
}
if (matrix[mx][my] == 1)
{
continue;//已经有雷的位置不能放雷
}
matrix[mx][my] = 1;
count -= 1;//每布雷一次,剩余雷的数量-1
}
}
统计排雷位置附近的数量
show
1 | 0 | 0 |
1 | 1 | 1 |
0 | 1 | 0 |
mine
4 | 2 | |
3 | 3 |
int count_mine(char matrix[][COLS], int row, int col, int x, int y)
{
//注意x+1,x-1,y+1,y-1是不能超出矩阵范围的
int count = 0;
if (x - 1 >= 1 && y - 1 >= 1)
count += matrix[x - 1][y - 1];
if (x - 1 >= 1)
count += matrix[x - 1][y ];
if (x - 1 >= 1 && y + 1 < col)
count += matrix[x - 1][y + 1];
if (y - 1 >= 1)
count += matrix[x][y - 1];
count += matrix[x][y];
if (y + 1 < col)
count += matrix[x][y + 1];
if (x + 1 < row && y - 1 >= 1)
count += matrix[x + 1][y - 1];
if (x + 1 < row)
count += matrix[x + 1][y];
if (x + 1 < row && y + 1 < col)
count += matrix[x + 1][y + 1];
return count;
}
🌈最终代码
#include<stdio.h>
#include<stdlib.h>
int welcome()
{
printf("**********欢迎进入扫雷游戏**********\n");
printf("********** 1. 开始游戏 **********\n");
printf("********** 2. 退出游戏 **********\n");
printf("************************************\n");
printf("请输入你的选择:");
int input;
scanf("%d", &input);
return input;
}
#define ROW 3
#define COL 3
#define ROWS 4
#define COLS 4
void init_show(char matrix[][COLS], int row, int col)
{
for (int i = 0; i < row; i++)
{
for (int j = 0; j < col; j++)
{
matrix[i][j] = ' ';
}
}
}
void display(char matrix[][COLS], int row, int col)
{
for (int i = 0; i < row; i++)
{
for (int j = 0; j < col; j++)
{
if (i == 0)//第0行的列号显示
{
printf(" %d |", j);
continue;
}
if (j == 0)//第0列的行号显示,从第一列开始
{
printf(" %d |", i);
}
else //不在0行0列时
{
printf(" %c |", matrix[i][j]);
}
}
printf("\n---|---|---|---|\n");
}
}
void mine_clear(int *x, int *y)
{
printf("请输入排雷位置<x,y>:");
scanf("%d,%d", x, y);
}
#define MINE_COUNT 5
void init_mine(char matrix[][COLS], int x,int y,int row, int col)
{
//在雷区矩阵中,1表示有雷,0表示没有雷,此时x和y坐标位置不能有雷
for (int i = 0; i < row; i++)
{
for (int j = 0; j < col; j++)
{
matrix[i][j] = 0;
}
}
int count = MINE_COUNT;
while (count>0)
{
int mx = (rand() % ROW) + 1;
int my = (rand() % COL) + 1;//产生一个随机坐标用来放置雷
if ((mx == x) && (my == y))
{
continue;//x,y位置不能放雷
}
if (matrix[mx][my] == 1)
{
continue;//已经有雷的位置不能放雷
}
matrix[mx][my] = 1;
count -= 1;//每布雷一次,剩余雷的数量-1
}
}
int Judge_fail(char matrix[][COLS], int x, int y)
{
//在矩阵的x,y位置判断是否有雷
if (matrix[x][y] == 1)
{
return 0;//表示踩雷了
}
return 1;//返回1表示没有踩雷
}
int Judge_win(char matrix[][COLS], int row, int col)
{
int count = 0;
for (int i = 1; i < row; i++)//第0行和第0列不计算在内
{
for (int j = 1; j < col; j++)
{
if (matrix[i][j] == ' ')
{
count++;//计算没有被翻开位置的数量
}
}
}
if ((count-1) == MINE_COUNT)//没有被翻开位置的数量等于雷的数量时游戏胜利
{
return 1;
}
return 0;
}
int count_mine(char matrix[][COLS], int row, int col, int x, int y)
{
//注意x+1,x-1,y+1,y-1是不能超出矩阵范围的
int count = 0;
if (x - 1 >= 1 && y - 1 >= 1)
count += matrix[x - 1][y - 1];
if (x - 1 >= 1)
count += matrix[x - 1][y ];
if (x - 1 >= 1 && y + 1 < col)
count += matrix[x - 1][y + 1];
count += matrix[x][y];
if (y - 1 >= 1)
count += matrix[x][y - 1];
if (y + 1 < col)
count += matrix[x][y + 1];
if (x + 1 < row && y - 1 >= 1)
count += matrix[x + 1][y - 1];
if (x + 1 < row)
count += matrix[x + 1][y];
if (x + 1 < row && y + 1 < col)
count += matrix[x + 1][y + 1];
return count;
}
void set_show(char matrix[][COLS], int x, int y, int count)
{
matrix[x][y] = count + '0';
//因为count是数字,显示矩阵显示的是字符,因此要将对应位置设置为数字字符
}
void game()
{
//定义两个矩阵
char mine[ROWS][COLS];
char show[ROWS][COLS];
//初始化显示矩阵
init_show(show,ROWS,COLS);
int flag = 0;
while (1)
{
//刷新显示矩阵
system("cls");//清屏操作
display(show, ROWS, COLS);
//玩家排雷
int x, y;
mine_clear(&x, &y);//将x和y的坐标地址传递进去
//获取排雷坐标,如果是第一次排雷则初始化雷区
if (flag == 0)
{
init_mine(mine, x, y, ROWS, COLS);
flag = 1;//设置为1,是为了防止后面重新初始化雷区
}
//判断是否踩雷
int ret = Judge_fail(mine, x, y);
if (ret == 0)
{
printf("游戏失败!!!\n");
return 0;
}
//判断是否胜利
ret = Judge_win(show, ROWS, COLS);
if (ret == 1)
{
printf("你真棒!\n");
return 0;
}
//统计排雷位置附近的数量
int count=count_mine(mine, ROWS, COLS, x, y);
//将雷数统计显示到显示矩阵的对应位置
set_show(show, x, y, count);
//刷新显示
}
}
int main()
{
srand(time(NULL));//随机数种子
while (1)
{
int input = welcome();
switch (input)
{
case 1:
game();
break;
case 2:
return 0;//退出程序
default:
printf("输入错误,请重新输入你的选择:\n");
break;
}
}
system("pause");
return 0;
}