前言
扫雷是一种经典的小游戏。游戏中提供了一个n*n的网格,在网格后含有
若干个雷。玩家可以根据当前的状况选择一个网格翻开,若其后边有雷则
游戏失败,若没有雷则会显示该网格周围雷的个数。直到未翻开的网格全
雷时游戏胜利。
一、需求分析
(1)需要在页面显示出这个n*n的网格,且处于未翻开的状态
(2)可以在接收用户想要排雷的位置。
(3)对于用户输入的位置进行判断,若该位置是雷游戏结束。
否则显示该网格周围8个格子中雷的个数。
(4)注意为了避免第一次就扫到雷的情况,需要做特别处理。
(5)应该利用随机数来表示网格中雷的个数,使得每一次雷的位置都不一样。
二、设计
(1)为用户设计一次菜单,可以选择游戏的开始结束。
(2)设计两个矩阵:
显示矩阵:向用户展示当前的雷区矩阵。
布雷矩阵:用于表示和存储雷的所在位置。
(3)初始化显示矩阵,将该矩阵的内容都表示为空格,表示未翻开的状态。在该步骤应该设计一个函数用于显示矩阵的打印。
(4)利用scanf让玩家输入矩阵的坐标,分别用x,y来存储行和列的坐标。
(5)利用x,y坐标来翻开矩阵的对应位置。注意当第一次翻开的时候根据x,y坐标来初始化布雷矩阵,解决第一次扫就扫到雷的情况。若不是第一次翻开则进行判断:
(判断步骤)
1、判断是否扫到了雷,若是则游戏结束,若不是则进行下一步判断。
2、显示矩阵中剩余没有翻开的数量是否等于雷的数量。如果是则游戏胜利,若不是则 进行下一步判断
3、统计排雷位置一圈有多少个雷,得到附近的雷数。
4、将雷数输入到显示矩阵当中
5、刷新显示
三、具体实现
游戏界面的实现(welcome函数应该和main函数中的switch语句搭配使用)
int welcome(){ //欢迎界面的打印
printf("********欢迎来到扫雷游戏************\n");
printf("******* 1、开始游戏 ************\n");
printf("******* 2、退出游戏 ************\n");
printf("请输入您的选择:\n");
int input = 0;
scanf("%d", &input);
return input;
}
mian函数的switch语句
while (1){
int input = welcome();
switch (input){
case 1: game(); break;
case 2:return; break;
default:printf("请输入正确的选择\n"); break;
}
}
show矩阵即显示矩阵的初始化
void init_show(char martix[][CLOS],int row,int col){ //二维数组必须声明列数
for (int i = 0; i < row; i++){
for (int j = 0; j < col; j++){
martix[i][j] = ' '; //将show矩阵的元素初始化为空格
}
}
}
show矩阵的显示
void display(char martix[][CLOS], int row, int col){ //show矩阵的显示
for (int i = 0; i < row; i++){
for(int j = 0; j < col; j++){
//打印第0行的内容
if (i == 0){
printf(" %d |", j);
continue;
}
if (j == 0){
printf(" %d |", i);
}
else {
printf(" %c |",martix[i][j]);
}
}
printf("\n---|---|---|---|\n");
}
}
确定用户的扫雷位置
void mine_clear(int *x, int *y){ //确定用户的扫雷位置
printf("请输入排雷位置\n");
scanf("%d,%d", x, y);
return;
}
雷区矩阵的初始化
void intit_mine(char martix[][CLOS], int row, int col,int x,int y){ //雷区的初始化
//雷区矩阵中 ,1表示有雷,0表示没有雷;
int count = 0;
for (int i = 0; i < row; i++){
for (int j = 0; j < col; j++){
martix[i][j] = 0;
}
}
while (count < MINE_COUNT){ //放雷
int mx = (rand() % ROW)+1; //产生一个随机坐标
int my = (rand() % ROW) + 1;
if ((mx == x&&my == y) || martix[mx][my]==1){
continue;
} //避免第一次就扫到雷
//printf("(%d,%d)\n", mx, my);
martix[mx][my] = 1;
count++;
}
}
判断是否胜利和和失败
int judge_fali(char martix[][CLOS], int x, int y){ //判断是否踩雷了
if (martix[x][y]==1){
return 0;
}
return 1;
}
int judge_win(char martix[][CLOS], int row, int col){ //判断胜利
int count = 0;
for (int i = 1; i < row; i++){
for (int j = 1; j < col; j++){//第0行和第0列不计算在内
if (martix[i][j] == ' '){
count++;
}
}
}
if ((count-1)== MINE_COUNT){ //没有翻开数量等于雷的数量,则胜利
return 1;
}
return 0;
}
统计周围的雷数
int count_mine(char martix[][CLOS], 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 =count +martix[x - 1][y - 1];
if (x - 1 >= 1)
count = count + martix[x - 1][y];
if (x - 1 >= 1 && y + 1 < col)
count = count + martix[x - 1][y+1];
if (y - 1 >= 1)
count = count + martix[x][y - 1];
count = count + martix[x][y];
if (y+1<col)
count = count + martix[x][y+1];
if (x + 1 < row&&y - 1 >= 1)
count = count + martix[x + 1][y - 1];
if (x + 1 < row)
count = count + martix[x + 1][y];
if (x + 1 < row&&y + 1 < col)
count = count + martix[x + 1][y+1];
return count;
}
将雷数写入显示矩阵
void set_show(char martix[][CLOS], int x, int y, int count){
martix[x][y] = count + '0';
}
结果展示