扫雷作为受众很广泛的一款小游戏,操作简单易上手,那么应该如何引用多文件实现一个小小的扫雷小游戏项目呢?
思路
根据多文件的性质,我们应该把这个项目分为三个文件,头文件、主函数的库文件和调用函数的库文件。
其中主要进行编程思考的是调用函数,本项目要实现的功能应该有:
- 玩家第一次选坐标不被炸死
- 初始化棋盘(随机布雷)
- 显示九宫格内雷的总数
- 展示棋盘
- 菜单选择界面
1.首先我们需要一个棋盘
我们需要用二维数组来打印两个棋盘,假如我们要打印10X10的棋盘,那我们的二维数组元素也要为10X10个吗?,不能,因为我们在设计算法时需要统计坐标周围8个方位雷的个数,假如要统计边界坐标周围雷的个数,那么就会有数组越界的问题,那我们就要在10X10的边界多上一圈元素,也就要定义12X12的数组元素,当然展示棋盘的时候这些元素我们不要打印出来
如图:
我们打印设计者棋盘要用数组mine[ROW][COL],打印要展示给玩家的数组board[ROW][COL],两个数组在开始必须要初始化,在设计棋盘中字符0代表不是雷,字符*代表显示棋盘的未点开的位置,先初始化两个数组
代码如下:
头文件包含:
#define ROW 12 //设计者棋盘横坐标
#define COL 12 //设计者棋盘纵坐标
#define TOTAL 10*10 //玩家棋盘的总数
#define MINE_NUM 20 //雷的个数
Game函数包含:
char mine[ROW][COL];
char board[ROW][COL];
memset(mine, '0', sizeof(mine));//初始化数组
memset(board, '*', sizeof(board));
2.布雷,我们使用随机函数生成。
int GetRandIndex(int start, int end)//保证随机数在1-10
{
return rand() % (end - start + 1) + start;
}
void SetMine(char mine[][COL], int row, int col)
{
srand((unsigned long)time(NULL));
int count = 0;//count计算已经布雷的总数
while (count < MINE_NUM) {
int x = GetRandIndex(1, 10);
int y = GetRandIndex(1, 10);
if (mine[x][y] == '0') {
mine[x][y] = '1';
count++;
}
}}
3.打印雷阵
void ShowBoard(char board[][COL], int row, int col)
{
printf(" ");
int i = 1;
for (; i <= 10; i++) {
printf(" %d ", i);
}
printf("\n----");
for (i = 1; i <= 10; i++) {
printf("---");
}
printf("\n");
for (i = 1; i <= 10; i++) {
printf("%3d|", i);int j = 1;
for (; j <= 10; j++) {
printf("%2c|", board[i][j]);
}
printf("\n");
int k = 1;
for (k = 1; k <= 11; k++) {
printf("---");
}
printf("\n");
}
}
4.根据游戏规则,要在已经展开的地方的九宫格中心显示的地雷总数。
char GetMines(char mine[][COL], int row, int col)//char->'0'-'8'
{
return mine[row - 1][col - 1] + mine[row - 1][col] + \mine[row - 1][col + 1] + mine[row][col - 1] + mine[row][col + 1] + \
mine[row + 1][col - 1] + mine[row + 1][col] + \
mine[row + 1][col + 1] - 7 * '0';
}
5.游戏总函数
void Game()
{
char mine[ROW][COL]; //set/judge mine
char board[ROW][COL]; //show
memset(mine, '0', sizeof(mine));
memset(board, '*', sizeof(board));
SetMine(mine, ROW, COL);
int count = TOTAL;
int x = 0;
int y = 0;
int times = 0;
while (1) {
ShowBoard(board, ROW, COL);
printf("请选择坐标: ");
scanf("%d,%d", &x, &y);
times++;
if (x >= 1 && x <= ROW - 2 && y >= 1 && y <= COL - 2) {
if (times == 1) {
mine[x][y] = '0';
}
if (mine[x][y] == '0') {
if (mine[x - 1][y - 1] == '0')
board[x - 1][y - 1] = GetMines(mine, x - 1, y - 1);
if(mine[x - 1][y] == '0')
board[x - 1][y] = GetMines(mine, x - 1, y);
if(mine[x - 1][y + 1] == '0')
board[x - 1][y + 1] = GetMines(mine, x - 1, y + 1);
if(mine[x][y - 1] == '0')
board[x][y - 1] = GetMines(mine, x, y - 1);
if(mine[x][y + 1] == '0')
board[x][y + 1] = GetMines(mine, x, y + 1);
if(mine[x + 1][y - 1] == '0')
board[x + 1][y - 1] = GetMines(mine, x + 1, y - 1);
if( mine[x + 1][y] == '0')
board[x + 1][y] = GetMines(mine, x + 1, y);
if(mine[x + 1][y + 1] == '0' )
board[x + 1][y + 1] = GetMines(mine, x + 1, y + 1);
char num = GetMines(mine, x, y);
board[x][y] = num;
count--;
if (count <= 20) {
printf("你赢了,厉害!\n");
break;
}
}
else {
printf("不好意思,你被炸死了!\n");
ShowBoard(mine, ROW, COL);
break;
}
}
else {
printf("你输入的坐标有误,请重新输入!\n");
}
}
}
其中
为了像我们以往玩的那样,点开一个空的地方就展开旁边空的地方。需要做一个判断才能实现
if (mine[x - 1][y - 1] == '0')
board[x - 1][y - 1] = GetMines(mine, x - 1, y - 1);
if(mine[x - 1][y] == '0')
board[x - 1][y] = GetMines(mine, x - 1, y);
if(mine[x - 1][y + 1] == '0')
board[x - 1][y + 1] = GetMines(mine, x - 1, y + 1);
if(mine[x][y - 1] == '0')
board[x][y - 1] = GetMines(mine, x, y - 1);
if(mine[x][y + 1] == '0')
board[x][y + 1] = GetMines(mine, x, y + 1);
if(mine[x + 1][y - 1] == '0')
board[x + 1][y - 1] = GetMines(mine, x + 1, y - 1);
if( mine[x + 1][y] == '0')
board[x + 1][y] = GetMines(mine, x + 1, y);
if(mine[x + 1][y + 1] == '0' )
board[x + 1][y + 1] = GetMines(mine, x + 1, y + 1);
另外为了保证客户对游戏愉悦性,不能第一次就被炸死,所以:
times++;//计算第几次输入坐标
if (x >= 1 && x <= ROW - 2 && y >= 1 && y <= COL - 2) {
if (times == 1) {
mine[x][y] = '0';
}
6.菜单选择
为了代码的简洁,分区清楚,菜单部分可以再建立一个.c文件
void Menu()
{
printf("###################################\n");
printf("## 1. Play 2. Exit ##\n");
printf("###################################\n");
printf("Please Select: ");
}
int main()
{
int quit = 0;
int select = 0;
while (!quit){
Menu();
scanf("%d", &select);
switch (select)
{
case 1:
Game();
break;
case 2:
printf("拜拜!\n");
quit = 1;
break;
default:
printf("选择错误,请重新选择!\n");
break;
}
}
system("pause");
return 0;
}
最后奉上整体的代码:
https://github.com/GagaAutom/C-programming-language/tree/master/mine%20clearance
参考大佬来源:
C语言实现扫雷——详解
https://blog.csdn.net/yc1515707718/article/details/78744978