这里我们分三个文件来解决此问题,分别是
test.c------用来测试游戏逻辑
扫雷.h----头文件
扫雷.c------用来编修游戏具体程序
首先是test.c
#define _CRT_SECURE_NO_WARNINGS 1
#include"扫雷.h"
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] = {0};//创建排查雷的数组
//初始化数组一个全为0;一个全为*(想要呈现的形式);
InitBoard(mine, rows, cols, '0');//由于此要初始化两个数组,考虑在设置一个参数控制初始化为什么
InitBoard(show, rows, cols, '*');//由于此要初始化两个数组,考虑在设置一个参数控制初始化为什么
//打印棋盘,由于11*11是为了防止越界,对于用户来说只需要看到9*9即可
//检验初始化是否正确,先设置打印操作
//Displayboard(mine,row,col);//不给用户看雷在哪里
Displayboard(show, row, col);
//布置雷
Setmine(mine, row, col);//布置雷也只与9*9的棋盘格有关
//Displayboard(mine, row, col);//检查一下是否布置成功,成功
//排查雷
FindMine(mine, show, row, col);//由于排查雷与mine和show都有关,故填入两个参数
}
void test()
{
int input = 0;
srand((unsigned int)time(NULL));//以时间为种子,达到生成真正的随机数,srand的参数类型是unsigned int类型,编译器可能不理解故强制转换
do
{
menu();
printf("请选择->");
scanf("%d", &input);
switch (input)
{
case 1:
printf("ready!\n");
game();
break;
case 0:
printf("退出游戏\n");
break;
default:
printf("选择错误,请重新选择\n");
break;
}
} while (input);//此处当为0时退出循环即退出游戏,当为其他数字时,要么重开一把,要么重新选择
}
int main()
{
test();
return 0;
}
然后是扫雷.h
#define _CRT_SECURE_NO_WARNINGS 1
#define row 9//为了方便随时更改数据,所以这里设置一个名字
#define col 9
#define cols col+2
#define rows row+2
#define Easy_Count 80//雷的个数
//声明参数
void InitBoard(char arr[rows][cols], int Rows, int Cols,char set);//棋盘初始化函数
void Displayboard(char arr[rows][cols],int Row,int Col);//打印棋盘
void Setmine(char arr[rows][cols], int Row,int Col);//布置雷也只与9*9的棋盘格有关
void FindMine(char mine[rows][cols], char show[rows][cols],int Row,int Col);//排查雷函数
#include<stdlib.h>//随机数的库函数
#include<time.h>//随机数的库函数
#include<stdio.h>
最后是扫雷.c
#include"扫雷.h"
void InitBoard(char arr[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++)
{
arr[i][j] = set;
}
}
}
void Displayboard(char arr[rows][cols], int Row, int Col)
{
int i = 0;
printf("----扫雷游戏开始----\n");
for (i = 0;i <= col;i++)
{
printf("%d ", i);
}
printf("\n");//打印的行号
for (i = 1;i <= row;i++)
{
int j = 0;
printf("%d ", i);//打印的列号
for (j = 1;j <= col;j++)
{
printf("%c ",arr[i][j]);//打印了一行
}
printf("\n");//打印完一行后换行操作
}
}
void Setmine(char arr[rows][cols], int Row, int Col)
{
int count = Easy_Count;//设置10个雷
while (count)
{
//这里设置随机数,rand函数生成的是伪随机数,故需要在游戏逻辑测试中加入srand
int x = rand() % row + 1;
int y = rand() % col + 1;//分别设置两个坐标,不能超过9*9格子范围
if (arr[x][y] == '0')//注意这里是字符0
{
arr[x][y] = '1';//安置炸弹
count--;//安一个剪出一个
}
}
}
static int Getminecount(char mine[rows][cols], int x, int y)
{
int i = 0;
int count = 0;
for (i = x - 1;i <= x + 1;i++)
{
int j = 0;
for (j = y - 1;j <= y + 1;j++)
{
count += (mine[i][j] - '0');//因为字符一为49,字符零为48,相减正好为一,故可以把他们相加,再减去八个字符零的值即可,这里用循环表达了类似的意思
}
}
return count;
}
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<Row*Col- Easy_Count)//为了可以结束游戏,当把81-10=71个位置全排查完毕时既可以结束优秀
{
printf("请输入要排查的坐标:\n");
scanf("%d %d", &x, &y);
if (x >= 1 && x <= col && 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("victory!!!^-^");
Displayboard(mine, row, col);
}
}