目录
这个版本的扫雷是最基础的版本,想要实现更多功能就要亲自动手哟。哈哈哈,这里的小白是要至少会函数和数组的知识才行哟~!源码在最下边。
相信大家,都玩过扫雷。如果玩过的兄弟就不用看这了,如果还没玩过的话。建议大家去玩一下,再来看这篇博客。这样,也会有更深的理解yo~。
首先我们还是来看几张图
我在实现时这是我们能看到的部分每个*代表雷,这是一个9*9的雷图。我们知道当我们排雷时会返回对应位置周围的雷的个数。
这时就有人问最周边的位置怎么办?带着这个疑问我们再看一张图。
其实在我们箭头指的方向其实还有隐藏的一排,只是我们没有让它显示出来。
然后我们又是怎样输入一个雷的坐标后返回周围雷的个数的呢?
我们看图其中1就是表示有雷的地方,我们也隐藏了它周围的一排,其中这周围的一排全部都为0。但是我们再玩这个扫雷时,我们是看不见的。这时候你大概就有点悟了,但又没有完全悟。知道你很急,但是你先别急。
ok这是我们能看到棋盘和我们不能看见的内部的简单说明。可能现在你已经汗流浃背了。但是你再往下看,可能就看懂了。
我们创建了的一个扫雷的头文件,用来声明函数。
创建一个game.cpp文件来实现我们的部分函数。
再创建一个text.cpp文件来实现我们的主要功能。
此时我们只需要在扫雷.h里面引头文件。在源文件里引头文件就行了。(如果在头文件已经引了头文件,在源文件中引了头文件,就不用引新的头文件)。
void menu()
{
printf("########################\n");
printf("#### 1. paly #######\n");//提示按1进入游戏
printf("#### 0. exit #######\n");//提升按1退出游戏
printf("########################\n");
}
void game()
{
}
void test()
{
int input = 0;//创建一个输入数input
do //do while循环至少运行一次
{
menu(); // 打印选选
printf("请选择->");
scanf("%d", &input);//输入input
switch (input)
{
case 1: //输入1就进入游戏
{
printf("------扫雷------\n");
game();
break;
}
case 0:
printf("退出游戏\n"); //输入0跳出
break;
default:
printf("选择错误,从新选择喵~\n");//如果选择其他数就会让你重新选择。
break;
}
} while (input); //输入0时就退出
}
int main(){
test(); //我们把游戏放在一个test函数里面实现
return 0;
}
这就是游戏的初步设计,主要是创建创建一个menu菜单,根据菜单实现它的基本功能。再在基本功能之上去实现游戏函数。所以初始化的步骤里我们还没有去实现扫雷游戏的函数。
当我们运行代码时
就可以打印菜单了。
首先我们在上边已经说明我们在打印时是少打印了一圈的。
我们看到的是9*9的棋盘所以在当我们初始化棋盘时我们要多初始化两行两列,也就是初始化11*11的棋盘和雷的布置。
看图理解,我们主要看6 7 8 9行代码。
我们定义两组数
6 7,打印的数(后面要用)。
8 9,生成棋盘的行数和列的数。
这里我们直接在game函数里来生成我们的两个棋盘
我们初始化生成一个雷的棋盘(这个部分在运行当中玩家是看不到的)和一个玩家能看到的棋盘。我们命名为mine(雷) 和 show
然后就是初始化两个棋盘。我们用一个函数来实现
我们来看函数(不要忘是在game。cpp中实现的)
void initboard(char ROW[][rows], int R, int C,char set)//传入要初始化的数组,R为行(横着的)
的长度,C为列(竖着的),set为初始化
的参数。
{
int i = 0;
for (i = 0; i < R; i++)
{
int j = 0;
for (j = 0; j < C; j++)
{
ROW[i][j] = set; //全部为set
}
}
}
然后要在头文件中声明,就像这样。
我们在这看6 7行代码
我们用一个print函数来打印棋盘。
注意row,col 是9哟
我们要打印成这个样子。
所以请跟着我这样做(不要忘是在game。cpp中实现的)
void print(char arr[][rows], int R, int C)//传入要打印的数组,R为行(横着的)
的长度,C为列(竖着的)
{
int i = 0;
for (i = 0; i <=col; i++) //先在第一排打印0-9,打印后添加一个空格,
{
printf("%d ", i);
}
printf("\n");
for (i = 1; i <= R; i++) //从每行的第二开始打印(横着的),打印到第九列
{
int j = 1; //打印之前打印每行的行数。
printf("%d", i);
for (j = 1; j <=C; j++) //从每列的第二个开始打印(竖着的),打印到第九列
{
printf(" %-1c", arr[i][j]);//用-1空一格。
}
printf("\n"); //每打印一列换行
}
}
不要忘在头文件声明函数
我们还是用函数来实现布置雷
注意我们的雷只能在九行九列中生成,所以传row,和col。
我们先在头文件中定义一个要生成雷的个数(第十行)
我们再来看实现的函数(在game.cpp中实现的)
void setmine(char arr[][cols], int R, int C)//传的mine字符数组,R为9,C为9
{
int count = EASR_COUNT; //十个雷
while (count)
{
int x = rand() % row + 1; //x为竖着的坐标,y为横着的坐标
int y = rand() % col + 1; //rand()生成随机数。%row为0-8,加1变成1-9;
if (arr[x][y] == '0') //判断是否已经生成过雷
{
arr[x][y] = '1'; //用1来表示雷。
count--; //每生成一个雷count就减一,直到生成10个1
}
}
}
为了使生成的随机数为正数且更随机。我们再main函数中这样写
注意不要忘引头文件和声明函数
4行 rand(),srand()的头文件
5行 time的函数的头文件。
打印一下生成雷的棋盘看看(意味着可以作弊哟~)
我们还是用一个函数来实现
传入我们的mine,和show的棋盘,找的是9*9的棋盘所以都传的是九。
我们来看实现的函数(game.cpp中实现)
static int get_mine_conut(char mine[][cols], int x, int y)//static只在本源文件用
{
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';
//返回周围坐标的ascall码
}
void findmine(char mine[][cols], char show[][cols], int R, int C)
{
int win = 0;//win用来判断是否胜利。
//基本逻辑
//1.输入坐标
//2.检查坐标是不是雷
//(1).是雷--被炸死,游戏结束
//(2).不是雷--统计周边有多少个雷--存储排查雷的信息到数组
while (win"); //输入坐标x为竖着的,y为横着的。
int x = 0;
int y = 0;
scanf("%d %d", &x, &y);//(取值为1到9)
//判断合法性
if (x >= 1 && x <= 9 && y >= 1 && y <= 9)
{
if (mine[x][y] == '1') //如果为1就被炸死
{
printf("被炸死了喵~\n");
print(mine, row, col); //让你死得瞑目,给你打印一下生成雷的棋盘
break; //跳出循环
}
else
{
//不是雷,统计坐标周围的雷的个数
int count= get_mine_conut(mine, x, y);//用一个函数来实现
show[x][y] = count+'0'; //注意看这是字符的数字哟!所以我们要加个'0',不是0哟
//有几个就是对应的ascall码(字符对应的数字)。
print(show, row, col); //打印一下棋盘(玩家能看见的棋盘)
win++; //每排除一个win就加1
}
}
else
{
printf("坐标不合法喵~\n");//如果不为1-9的化就重新输入。
}
}
if (win == row * col - EASR_COUNT)//win为71就胜利了
{
printf("恭喜喵~你太有耐心了,简直就是卡密撒嘛");//夸夸你
}
}
注意声明函数
至此我们的扫雷代码就实现了哟~,其实并不复杂。
如果你没看懂,可能是我的问题,不用怀疑自己
如果有任何问题都可以私信我(ᕑᗢᓫ∗)˒
喵~
源码在这哟
源码地址:https://github.com/zgw486/zgw486/
我知道你想要源码。