准备工作
目录
这里我们设定为:输入1就进入游戏,输入2就退出游戏,下面实现代码:
int main()
{
int input = 0;
do
{
menu();
printf("请输入:\n");
scanf("%d", &input);
switch (input)
{
case 1:
game(); break;
case 0:
break;
default :
printf("输入错误,请重新输入\n");
break;
}
} while (input);
return 0;
}
老一套的模版,采用while循环+switch,这里不在过多讲述.关键就在于game()函数的实现;
正文
游戏功能总结
游戏功能分为以上几个:
1.首先整个扫雷的面板就如同下棋的棋盘一样,因此.我们需要先制造表面的棋盘,关于棋盘分为两个。
a.展示在玩家面前的棋盘(show):无法看到雷的位置,但是可以在排过的位置看到周围的雷的个数
b.布置雷的棋盘(mine):在这个棋盘上进行雷的布置
2.棋盘的初始化:show棋盘初始化为全“*”;mine棋盘初始化为全"0",这里我们之后用“1”代表雷;
3.打印棋盘;
4.进行布置地雷;
5.玩家进行排查雷;
符号的准备
1.行、列:这里我们制造一个9行9列的棋盘;ROW、COL分别代表行和列,但是我们如果只打印9行9列的话不好看,所以我们通常将外围也进行打印(外围不进行布置雷),定义ROWS、COLS分别为加上外围的棋盘的行和列.
2.雷的个数:雷的个数是可以进行调整的,这里直接定义为EASY COUNT为雷的个数;
游戏内置函数的实现
1.制造棋盘
很简单,就是定义两个字符二维数组,如图:
行和列都是大行和大列,小行和小列是后边用来处理棋盘的有效部分的;
2.初始化棋盘
void init(char board[ROWS][COLS], int rows, int cols, char s);
先来看这个函数,board是要初始化的棋盘,rows、cols是行和列的形参,初始化为字符s;
//初始化函数
void init(char board[ROWS][COLS], int rows, int cols, char s)
{
for (int i = 0; i < rows; i++)
{
for (int j = 0; j < cols; j++)
{
board[i][j] = s;
}
}
}
3.打印棋盘
如果仅仅初始化后打印是不行的,我们还需做些处理,在棋盘的外围打印上行数,和列数
就像这样,就prefect了。
函数内部很明显需要先打印一行0-9;然后再接下来的每一列的开头都打印行数,
//打印
void display(char board[ROWS][COLS], int row, int col)
{
printf("********扫雷********\n");
for (int i = 0; i <= row; i++)
{
printf("%d ", i);
}
printf("\n");
for (int i = 1; i <= row; i++)
{
printf("%d ", i);
for (int j = 1; j <= col; j++)
{
printf("%c ", board[i][j]);
}
printf("\n");
}
printf("********扫雷********\n");
}
如图,先来个printf打印扫雷,然后再打印列数,接下来的每一行都要先打印行数,在打印初始化的字符s,最后在打印扫雷;这样一来棋盘就打印完成了;值得一提的虽然我们上面初始化的是11行11列的棋盘,但是外围的字符我们并没有使用,所以没有打印,在后面我们直接输入坐标就图中行和列对应的坐标;
4.放置雷
a.放置地雷是在我们的mine棋盘中,'1'代表雷,‘0’代表无雷。
b.这里需要用到随机数产生器来进行产生随机数坐标。
//放置雷
void setmine(char board[ROWS][COLS], int row, int col)
{
int x = 0, y = 0;
srand((int)time(NULL));
int count = EASY_COUNT;
while (count)
{
x = rand() % 9 + 1;
y = rand() % 9 + 1;//坐标为1-9
if (board[x][y] == '0')
{
board[x][y] = '1';
count--;
}
}
}
雷的坐标为x,y(这里的x,y不需要再进行-1,因为我们打印的内部部分就是从第二行第二列),x,y都是1-9的数,然后将坐标对应的mine棋盘的字符换成字符‘1’;同时要将雷的个数减1;
5.排查雷
//排查坐标
void FindMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col)
{
int x = 0, y = 0;
int win = 0;
while (win < row*col-EASY_COUNT)
{
printf("请重新要排查的坐标\n");
scanf("%d%d", &x, &y);
if (x >= 1 && x <= row && y >= 1 && y <= col)
{
if (mine[x][y] == '1')
{
printf("很遗憾,你被炸死了\n");
display(mine, ROW, COL);
break;
}
else
{
//判断周围雷的个数
int n = GetMine(mine, x, y);
show[x][y] = n + '0';
display(show, ROW, COL);
win++;
}
}
else
{
printf("输入非法,请重新输入\n");
}
}
if (win == row * col - EASY_COUNT)
{
printf("恭喜你,排雷成功\n");
}
}
定义x,y是玩家输入的坐标,win是排过安全位置的个数,row*col-EAST_COUNT是除了雷之外的安全位置个数;
a.判断条件是:没有将所有的安全位置排完就不会结束,除非排到雷,被炸死,
b.检查坐标的合法性:坐标得在棋盘内部之中,范围是1到9;
c.然后进行判断位置的安全性:如果该位置有雷,那么玩家被炸死,游戏结束,打印mine棋盘,让玩家死个明白,反之,这个位置没有雷,就需要说明这位置周围有多少个雷,这里我们用函数进行操作。
int GetMine(char mine[ROWS][COLS], int x, int y)
{
return mine[x - 1][y] + mine[x - 1][y + 1] + mine[x - 1][y] + mine[x][y - 1] + mine[x][y + 1] + mine[x + 1][y - 1] + mine[x + 1][y] + mine[x + 1][y + 1] - 8 * '0';
}
因为位置上不是字符0就是字符1,所以我们将周围一圈进行相加,然后最后减去8个字符0,就可以得出有几个字符‘1’;
将函数返回值储存在n中,接下来在show 盘上就要显示出字符n,所以直接用n加上字符0即可;然后打印棋盘show,win++,让玩家继续输入坐标。
如果跳出循环了,说明排除的安全位置已满,剩下的位置都是地雷,那么就可以宣布游戏胜利了。