目录
扫雷游戏的头文件:
1.首先先打印游戏菜单
2.将游戏的整体用函数的形式表达。
3.我定义的游戏主体为4个部分
4.接下来开始实现初始化棋盘
5.打印棋盘(即打印展示棋盘)
6.设置雷
7查雷(最重要的一节)
1.查雷的主体
2.如果点到一个安全区域,则要显示出附近含有的雷数
#pragma once
#include
#include
#include
#define ROW 9
#define COL 9
#define ROWS ROW+2
#define COLS COL+2
#define EASY_COUNT 10
//函数的声明
//初始化棋盘
void InitBoard(char board[ROWS][COLS], int rows, int cols, char set);
//打印棋盘的
void DisplayBoard(char board[ROWS][COLS], int rows, int cols);
//布置雷
void SetMine(char mine[ROWS][COLS], int row, int col);
//排查雷
void FindMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col);
用do while 循环(必执行一次),srand函数用来将rand函数的伪随机数定义为真的随机数,switch语句将游戏开始设为1结束设为0,将input作为循环判断语句。0为假则退出游戏。
int main()
{
int input = 0;
srand((unsigned int)time(NULL));
do
{
menu();
printf("请选择:>");
scanf("%d", &input);
switch (input)
{
case 1:
game();
break;
case 0:
printf("退出游戏\n");
break;
default:
printf("选择错误,重新选择\n");
break;
}
//...
} while (input);
return 0;
}
menu是游戏菜单,可按自己的喜好打印。game则为游戏主体,较为重要,且其中利用嵌套函数,在另一个源文件中填写,这样的习惯可以在后续工作中有很大的帮助,毕竟工作以后都是分工合作,有分文件做事的话更高效!!!!
因为扫雷是在棋盘上工作,正常来说只显示一个棋盘,但一个棋盘的构思方法,对于初学者来说暂时不能实现,所以我采用的是两个棋盘的形式。分别为打印雷区,和棋盘展现。由于整体的棋盘更像是一个大的正方形,所以采用二维数组进行打印。mine为种雷的棋盘数组,show为棋盘展现的数组。
1初始化棋盘,2打印展示棋盘,3生成地雷,4排查雷。
void menu()
{
printf("***********************\n");
printf("****** 1. play *****\n");
printf("****** 0. exit *****\n");
printf("***********************\n");
}
void game()
{
//数组
char mine[ROWS][COLS];//'0'
char show[ROWS][COLS];//'*'
InitBoard(mine, ROWS, COLS, '0');
InitBoard(show, ROWS, COLS, '*');
//棋盘打印
//DisplayBoard(mine, ROW, COL);
DisplayBoard(show, ROW, COL);
//布置雷
SetMine(mine, ROW, COL);
//DisplayBoard(mine, ROW, COL);
//排查雷
FindMine(mine, show, ROW, COL);
}
这里采用一个函数输出两个棋盘,char board数组代表了两个棋盘mine和show的数组,而rows和cols则是头文件里定义的ROWS和COLS,char set则是为两个棋盘的初始字符。因为棋盘只要求9*9格式但是需要定义11*11的数组,因为外面的一圈用来防止等会种雷的查雷的bug
用两个for循环将棋盘数组内容全定义下来。
void InitBoard(char board[ROWS][COLS], int rows, int cols,char set)
{
int i = 0;
for (i = 0; i < rows; i++)
{
int j = 0;
for (j = 0; j < cols; j++)
{
board[i][j] = set;
}
}
}
用上下两个printf为棋盘加入边框。
第一个for循环用来打印棋盘的横坐标,第二个for循环用来打印棋盘的纵坐标和展示棋盘的内容。
void DisplayBoard(char board[ROWS][COLS], int row, int col)
{
int i = 0;
printf("--------扫雷游戏-------\n");
for (i = 0; i <= row; i++)
{
printf("%d ", i);
}
printf("\n");
for (i = 1; i <= row; i++)
{
printf("%d ", i);
int j = 0;
for (j = 1; j <= col; j++)
{
printf("%c ", board[i][j]);
}
printf("\n");
}
printf("--------扫雷游戏-------\n");
}
设置雷则是在mine数组棋盘上执行。
在头文件中定义了EASY_COUNT为炸弹个数,所以count为炸弹个数
利用while循环,当count为0时跳出循环。其中设置炸弹的坐标因为要为随机数,所以利用rand函数,因为rand函数的范围时0 -- 30000以上,因为row和col分别为棋盘的行和列,所以rand函数,和他们的余数必定是与他们是同位数,可以思考一个多位数除以一个 个位数的余数,+1是为了防止x y 的坐标为0,因为为0的话就在外面一圈的地方种雷,会导致函数出现bug。
void SetMine(char mine[ROWS][COLS], int row, int col)
{
int count = EASY_COUNT;
while (count)
{
int x = rand() % row + 1;
int y = rand() % col + 1;
if (mine[x][y] == '0')
{
mine[x][y] = '1';
count--;
}
}
}
查雷的代码我分为两个函数进行。
while循环的表达式含义为win是排查出的安全区域个数,row*col-EASY_COUNT则是表示总共的安全区域个数。
while循环中先输入两个数字作为你想要查找的坐标,如果坐标处的字符为‘1’,则你被炸死游戏结束并且将炸弹棋盘打印出来,如果没选到炸弹则继续向下进行,每次打印出新的展示棋盘,并且win++
如果最后找到了win ==表达式的个数的区域,那就你获胜。
void FindMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col)
{
int x = 0;
int y = 0;
int win = 0;
while (win");
scanf("%d %d", &x, &y);
if (x >= 1 && x <= row && y >= 1 && y <= col)
{
if (mine[x][y] == '1')
{
printf("很遗憾,你被炸死了\n");
DisplayBoard(mine, ROW, COL);
break;
}
else
{
int count = GetMineCount(mine, x, y);
show[x][y] = count + '0';
DisplayBoard(show, ROW, COL);
win++;
}
}
else
{
printf("坐标非法,重新输入\n");
}
}
if (win == row * col - EASY_COUNT)
{
printf("恭喜你,排雷成功\n");
DisplayBoard(mine, ROW, COL);
}
}
一个9宫格里你点击了一个中间区域,则要告诉你附近有多少个雷,这样游戏才能进行下去。
这里新写一个函数在种雷的棋盘上将这8个格子里的字符可能是‘0’可能是‘1’,用这8个格子里的字符的ascll码减去8个0的ascll码,则得出一个整数,这个整数则为这个安全区域附近含有的雷数,将其带入上一个函数中。完成扫雷代码初阶
int GetMineCount(char mine[ROWS][COLS], int x, int y)
{
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');
}