上一期咱们用C语言实现了三子棋的小游戏 C语言实现三子棋
今天我们再来写个扫雷的游戏,说起扫雷,相信大家都不陌生,可能许多朋友还是玩扫雷的高手。
其实扫雷和三子棋有许多相似之处,都需要用到数组的知识。
今天的扫雷也是相当有趣的
由于博主是一个编程学习的小白,所以这只是扫雷的初级版,此版本有一些功能还无法实现,在后续的学习中,我会持续更新,不断对这个小游戏进行优化,期待大家的关注,还有,这篇文章中若有错误或不当的地方,欢迎大家指正!
目录
一.游戏的整体思路
为了让代码的可读性更高,思维性更强,我们需要创建三个文件来完成这个项目
- test.c —— 测试游戏
- game.h—— 游戏函数的声明
- game.c—— 游戏函数的实现
然后我们需要建立两个棋盘,为什么呢?
我们先想一下扫雷的游戏规则,如图,如果我选中的方块不是雷,那么它上面就会显示一个数字,这个数字代表它以它为中心的这个3*3区域内(红色方框)地雷的个数,它的范围是0~8,我们初步的设想是:无雷的放数字0,有雷的放数字1
但是如果我这个方块不是雷,显示它周围的雷的格式时,如果它的周围有一个雷,需要显示
数字1时 ,我们就会分不清这个1 是雷?还是排查出的周围雷的个数?所以我们需要建立两个棋盘
一个棋盘用来存放布置好的雷的信息(这是游戏结束前不让玩家看到的)
另一个棋盘存放排查好的雷的信息(这是游戏过程中玩家看到的)
还有一个问题
如果我们布置的棋盘是9*9的
当我们选择了排查这个位置的周围的雷的个数时,它的旁边就没有了,所以我们要将棋盘扩展为11*11
(但是打印时只打印9*9的棋盘 )
如图,这样我们就能排查这格周围的地雷的个数了
我们具体这样操作
二.创建游戏菜单
与之前的三子棋游戏一样,我们首先需要设置一个游戏菜单
由于一进入游戏,我们首先就要看到菜单,所以这里我们采用do...while循环
我们的菜单需要实现的功能有:
- 游戏的进入
- 游戏的退出
- 非法输入的返回提示和说明
void menu()
{
printf("************************\n");
printf("***** 1.play *******\n");
printf("***** 0.exit *******\n");
printf("************************\n");
}
void test()
{
int input = 0;
do
{
menu();
printf("请选择");
scanf("%d", &input);
switch (input)
{
case 1:
game();
break;
case 0:
printf("退出游戏\n");
break;
default:
printf("选择错误\n");
break;
}
} while (input);
}
int main()
{
test();
return 0;
}
这里我们创建了test函数和menu函数,为的是让逻辑更清晰,现在我们的菜单部分就完成了
对于这个游戏菜单,我们能实现的游戏功能有:
- 输入1进入游戏
- 输入0退出游戏
- 输入其他数字提示选择错错误,将重新输入
这是菜单的运行效果
三.游戏主体的实现
1.创建棋盘(数组)
//创建数组
char mine[ROWS][COLS] = { 0 };//存放布置好的雷的信息
char show[ROWS][COLS] = { 0 };//存放排查好的雷的信息
2.初始化棋盘
我们把mine数组作为存放布置好的雷的信息的棋盘
把show数组作为存放排查好的雷的信息棋盘
我们用一个InitBoard函数来初始化这两个棋盘
看代码:
//函数的声明
void InitBoard(char board[ROWS][COLS], int rows,int cols,char set);
//函数的定义
void InitBoard(char board[ROWS][COLS], int rows, int cols, char set)
{
int i = 0;
int j = 0;
for(i = 0;i < rows;i++)
{
for (j = 0;j < cols;j++)
{
board[i][j] = set;
}
}
}
//函数的调用
//初始化mine数组为全字符'0'
InitBoard(mine,ROWS,COLS,'0');
//初始化show数组为全'*'
InitBoard(show,ROWS,COLS,'*');
我们把mine数组全部初始化为字符 ' 0 '
把show数组全部初识化为字符 ' * '
3.打印棋盘
我们与两个棋盘
其中 mine数组代表的棋盘时游戏结束后或者游戏测试人员才能看到的
另一个show数组代表的棋盘是玩家玩游戏时能看到的
我们上代码
//函数的定义
void DisplayBoard(char board[ROWS][COLS], int row, int col);
//函数的定义
void DisplayBoard(char board[ROWS][COLS], int row, int col)
{
//1-9
int i = 0;
int j = 0;
printf("\n");
printf("---扫雷游戏---\n");
//打印列号
for (i = 0;i <= col;i++)
{
printf("%d ", i);
}
printf("\n");
for (i = 1;i <= row;i++)
{
printf("%d ", i);
for (j = 1;j <= col;j++)
{
printf("%c ", board[i][j]);
}
printf("\n");
}
}
//函数的调用
DisplayBoard(show, ROW, COL);//只打印9*9的内容
4.布置雷
下面我们就可以来布置雷啦,由于雷是随机布置的,于是我们就要用到rand函数
srand((unsigned int)time(NULL)); //进行初始化
x = rand() % row+1; //x的范围是1~9
y = rand() % col+1; //y的范围是1~9
下面看代码:
//函数的声明
void SetMine(char mine[ROWS][COLS],int row,int col);
//函数的定义
void SetMine(char mine[ROWS][COLS], int row, int col)
{
//布置10个雷
int count = EASY_COUNT;
while (count)
{
//生产随机的下标
int x = rand() % row + 1;//范围1到9
int y = rand() % col + 1;
if (mine[x][y] == '0')
{
mine[x][y] = '1';
count--;
}
}
}
//函数的调用
SetMine(mine, ROW, COL);
我们加上mine棋盘的打印,并将它注释掉,这是为了方便我们测试游戏或这检查游戏出现的问题的
这里的EASY_COUNT是雷的个数,我们用define定义它
5.排查雷
关于排查雷,我们是这样实现的:
- 输入排查雷的坐标
- 检查该坐标是不是雷
- (1)是雷 --> 很遗憾炸死了
- (0)不是雷 --> 统计坐标周围有几个雷-->存储排查雷的信息到show数组,游戏继续
这里我们用了 get_mine_count 和 FindMine 两个函数
get_mine_count函数用来统计坐标周围有几个雷
看代码
//声明
void FindMine(char mine[ROWS][COLS],char show[ROWS][COLS], int row, int col);//从mine中排查放到show中
//排查雷
int get_mine_count(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+1] +
mine[x + 1][y] +
mine[x][y + 1] +
mine[x - 1][y + 1] - 8 * '0';
}
void FindMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col)
{
//1.输入排查雷的坐标
//2.检查该坐标是不是雷
//(1)是雷 --> 很遗憾炸死了
//(0)不是雷 --> 统计坐标周围有几个雷-->存储排查雷的信息到show数组,游戏继续
int x = 0;
int y = 0;
int win = 0;
while (win<row*col- EASY_COUNT)
{
printf("请输入要排查的坐标: ");
scanf("%d %d", &x, &y);//x的范围是1~9,y的范围是1~9
//判断坐标的合法性
if (x >= 1 && x <= col && y >= 1 && y <= row)
{
if (mine[x][y] == '1')
{
printf("很遗憾,你被炸死了\n");
DisplayBoard(mine, row, col);//把怎么被炸死的显现出来
break;
}
else
{
//不是雷的话统计(x,y)坐标周围有几个雷
int count = get_mine_count(mine, x, y);
show[x][y] = count+'0';
//显示排查出的信息
DisplayBoard(show, row, col);
win++;
}
}
else
{
printf("坐标不合法,请重新输入\n");
}
}
if (win == row * col - EASY_COUNT)
{
printf("恭喜你,排雷成功!");
DisplayBoard(mine, row, col);
}
}
//调用
FindMine(mine,show,ROW,COL);
这里有几个需要说明的点:
1.
这里函数有两个形参,是为了从mine中排查然后放到show中
2.
这些代表查找的坐标的周围其他格子的坐标
3.由于我们在棋盘中存放的是字符 '0 '和字符 '1'
我们先看一下 ASCII码 表
我们可以发现'0' '1' '2'这些字符的ASCII码值都是连续的,我们想显示出排查格子周围雷的个数,需要先将字符'0','1','2'...转化为数字 0,1 ,2,3...
我们只需要把每个字符减去一个'0',它的ASCII码值是48就可以了,看看我们是如何操作的吧:
之后再转化成字符的形式存到数组中
4.我们还要判断玩家输入坐标的合法性:
6.递归展开一片
//递归展开一片
void board(char** mine, char** show, int x, int y)
{
//判断坐标是否越界
if (x >= 1 && x <= col && y >= 1 && y <= row)
{
//判断是否已经被排除
if (show[x][y] != '*' && show[x][y] != '@')
{
return;
}
int count = get_mine_count(mine, x, y);
if (count > 0)
{
show[x][y] = count + '0';
return;
}
//递归拓展地图
else if (count == 0)
{
show[x][y] = '0';
board(mine, show, x - 1, y);
board(mine, show, x - 1, y - 1);
board(mine, show, x, y - 1);
board(mine, show, x + 1, y - 1);
board(mine, show, x + 1, y);
board(mine, show, x + 1, y + 1);
board(mine, show, x, y + 1);
board(mine, show, x - 1, y + 1);
}
}
}
7.排行榜(文件操作)
我们需要定义一个结构体 来记录玩家的姓名,成绩
成绩采取两个时间戳的差值作为成绩,单位是毫秒
排序我们用到的是qsort 快速排序函数
int cmp(const void* a, const void* b)
{
Rank* aa = (Rank*)a;
Rank* bb = (Rank*)b;
return aa->time > bb->time;
}
//排行榜
void Update_Rank(Rank info)
{
Rank arr[6] = { 0 };
for (int i = 0; i < 6; i++)
{
arr[i].time = INT_MAX;
}
FILE* fp1 = fopen("rank.bin", "ab+"); //防止打开失败
if (!fp1)
{
printf("open failed");
return;
}
fseek(fp1, 0, SEEK_SET);
int num = fread(arr, sizeof(Rank), 5, fp1);
arr[num] = info;
qsort(arr, num + 1, sizeof(Rank), cmp);
for (int i = 0; i <= num; i++)
{
printf("%-20s %-20d 您的排名是:%d\n", arr[i].name, arr[i].time,i+1);
}
FILE* fp2 = fopen("rank.bin", "wb"); //不能用ab+
if (!fp2)
{
printf("open failed");
return;
}
num = num < 5 ? num + 1 : 5;
fwrite(arr, sizeof(Rank), num, fp2);
fclose(fp1);
fclose(fp2);
}
8.难度选择(二维指针动态开辟)
switch (input)
{
case 1:row = 4, col = 4, mine_num = 1; break;
case 2:row = 9, col = 9, mine_num = 10; break;
case 3:row = 11, col = 11, mine_num = 15; break;
default: printf("选择错误");
}
//创建数组
char** mine = (char**)malloc(sizeof(char*) *(row + 2));
char** show = (char**)malloc(sizeof(char*) *(row + 2));
for (int i = 0; i < row+2; i++)
{
mine[i] = (char*)malloc(sizeof(char) * (col + 2));
show[i] = (char*)malloc(sizeof(char) * (col + 2));
}
四.最初版本的代码(无排行榜,难度选择,展开一片,标记)
game.h—— 游戏函数的声明
#pragma once
#include<stdio.h>
#include<time.h>
#include<stdlib.h>
#define ROW 9
#define COL 9
#define EASY_COUNT 10
#define ROWS ROW+2
#define COLS COL+2
//初始化棋盘
void InitBoard(char board[ROWS][COLS], int rows,int cols,char set);
//打印棋盘
void DisplayBoard(char board[ROWS][COLS], int row, int col);
//布置雷
void SetMine(char mine[ROWS][COLS],int row,int col);
//排查雷
void FindMine(char mine[ROWS][COLS],char show[ROWS][COLS], int row, int col);
game.c—— 游戏函数的实现
#define _CRT_SECURE_NO_WARNINGS
#include"game.h"
//初始化
void InitBoard(char board[ROWS][COLS], int rows, int cols, char set)
{
int i = 0;
int j = 0;
for(i = 0;i < rows;i++)
{
for (j = 0;j < cols;j++)
{
board[i][j] = set;
}
}
}
//打印棋盘
void DisplayBoard(char board[ROWS][COLS], int row, int col)
{
//1-9
int i = 0;
int j = 0;
printf("\n");
printf("---扫雷游戏---\n");
//打印列号
for (i = 0;i <= col;i++)
{
printf("%d ", i);
}
printf("\n");
for (i = 1;i <= row;i++)
{
printf("%d ", i);
for (j = 1;j <= col;j++)
{
printf("%c ", board[i][j]);
}
printf("\n");
}
}
//布置雷
void SetMine(char mine[ROWS][COLS], int row, int col)
{
//布置10个雷
int count = EASY_COUNT;
while (count)
{
//生产随机的下标
int x = rand() % row + 1;//范围1到9
int y = rand() % col + 1;
if (mine[x][y] == '0')
{
mine[x][y] = '1';
count--;
}
}
}
int get_mine_count(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+1] +
mine[x + 1][y] +
mine[x][y + 1] +
mine[x - 1][y + 1] - 8 * '0';
}
//排查雷
void FindMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col)
{
//1.输入排查雷的坐标
//2.检查该坐标是不是雷
//(1)是雷 --> 很遗憾炸死了
//(0)不是雷 --> 统计坐标周围有几个雷-->存储排查雷的信息到show数组,游戏继续
int x = 0;
int y = 0;
int win = 0;
while (win<row*col- EASY_COUNT)
{
printf("请输入要排查的坐标: ");
scanf("%d %d", &x, &y);//x的范围是1~9,y的范围是1~9
//判断坐标的合法性
if (x >= 1 && x <= col && y >= 1 && y <= row)
{
if (mine[x][y] == '1')
{
printf("很遗憾,你被炸死了\n");
DisplayBoard(mine, row, col);//把怎么被炸死的显现出来
break;
}
else
{
//不是雷的话统计(x,y)坐标周围有几个雷
int count = get_mine_count(mine, x, y);
show[x][y] = count+'0';
//显示排查出的信息
DisplayBoard(show, row, col);
win++;
}
}
else
{
printf("坐标不合法,请重新输入\n");
}
}
if (win == row * col - EASY_COUNT)
{
printf("恭喜你,排雷成功!");
DisplayBoard(mine, row, col);
}
}
test.c —— 测试游戏
#define _CRT_SECURE_NO_WARNINGS
#include"game.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 };//存放排查好的雷的信息
//初始化mine数组为全字符'0'
InitBoard(mine,ROWS,COLS,'0');
//初始化show数组为全'*'
InitBoard(show,ROWS,COLS,'*');
//打印棋盘
DisplayBoard(show, ROW, COL);//只打印9*9的内容
//布置雷
SetMine(mine, ROW, COL);
/*DisplayBoard(mine, ROW, COL);*/
//这是不给玩家看到的
//排查雷
FindMine(mine,show,ROW,COL);//从mine中排查放到show中
}
void test()
{
int input = 0;
srand((unsigned int)time(NULL));
do
{
menu();
printf("请选择:\n");
scanf("%d", &input);
switch (input)
{
case 1:
//扫雷
game();
break;
case 0:
break;
default:
printf("选择错误");
break;
}
} while (input);
}
int main()
{
test();
return 0;
}
好了,这样我们就把扫雷游戏编写完成了
五.改进后的代码
如果你玩过正宗的扫雷游戏,那你肯定知道,扫雷游戏还有两个功能:
- 如果不是雷并且周围没有雷-->展开一片
- 如果我们确定哪个位置我们可以标记雷
这就是我们以后给这个游戏的优化方案
其中第一个功能我们需要使用递归实现
这些都会再以后更新,欢迎持续关注 !
更新内容:
- 实现了递归展开一片的功能
- 实现了标记地雷的功能
源代码
game.h
#pragma once
#include<stdio.h>
#include<time.h>
#include<stdlib.h>
#include<string.h>
//全局变量
extern int row;//行数
extern int col;//列数
extern int mine_num;//类的个数
//定义了一个Rank结构体
typedef struct Rank
{
char name[20];//用户名
int time;//时间(代表游戏的成绩)
}Rank;
//初始化棋盘
void InitBoard(char** board, char set);
//打印棋盘
void DisplayBoard(char** board);
//布置雷
void SetMine(char**mine);
//标记雷
void SignMine(char** show);
//递归展开一片
void board(char** mine, char** show, int x, int y);
//获取雷的个数
int get_mine_count(char** mine, int x, int y);
//排查雷
int FindMine(char** mine, char** show);//从mine中排查放到show中
//获取排名函数
void Update_Rank(Rank info);
game.c
#define _CRT_SECURE_NO_WARNINGS
#include"game.h"
//初始化
void InitBoard(char**board, char set)
{
int i = 0;
int j = 0;
//初始化
for (i = 0;i < row+2;i++)
{
for (j = 0;j < col+2;j++)
{
board[i][j] = set;
}
}
}
//打印棋盘
void DisplayBoard(char** board)
{
printf(" ");//考虑到y轴占两格
for (int j = 0; j < col; j++)//打印x轴坐标
{
printf(" %d ", j + 1);
}
printf("\n");
printf(" |");
for (int j = 0; j < col; j++)//打印棋盘封顶
{
printf("---|");
}
printf("\n");
for (int i = 1; i <= row; i++)
{
for (int j = 0; j <= col; j++)
{
if (j == 0)
{
printf("%2d|", i);//顺带打印y轴坐标
}
else
printf(" %c |", board[i][j]);//打印数据
}
printf("\n");
for (int j = 1; j <= col + 1; j++)//注意col应该+1,因为j==1的情况
{
if (j == 1)
printf(" |");
else
printf("---|");
}
printf("\n");
}
}
//设置雷
void SetMine(char** mine)
{
int count = mine_num;//雷的个数
while (count)
{
//生产随机的下标
int x = rand() % row + 1;//范围是1~row
int y = rand() % col + 1;//范围是1~col
if (mine[x][y] == '0')//避免重复设置雷
{
mine[x][y] = '1';//设置为雷
count--;
}
}
}
//标记雷
void SignMine(char** show)
{
while (1)
{
int input = 0;
printf("-----------------------\n");
printf("******你想标记地雷吗****\n");
printf("***** 1.标记 *******\n");
printf("***** 0.不标记 *******\n");
printf("-----------------------\n");
scanf("%d", &input);
if (0 == input)
{
break;
//不想标记就退出循环
}
else
{
int x = 0;
int y = 0;
printf("请输入你想标记的坐标: ");
scanf("%d %d", &x, &y);
//坐标合法性检验
if (x >= 1 && x <= col && y >= 1 && y <= row)
{
show[x][y] = '@';//标记你认为的雷的位置为@
DisplayBoard(show);//显示标记的结果
}
else
{
printf("非法的坐标,请重新标记\n");
}
}
}
}
//获取雷的个数
int get_mine_count(char** mine, 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 + 1] +
mine[x + 1][y] +
mine[x][y + 1] +
mine[x - 1][y + 1] - 8 * '0';
}
//递归展开一片
void board(char** mine, char** show, int x, int y)
{
//判断坐标是否越界
if (x >= 1 && x <= col && y >= 1 && y <= row)
{
//判断是否已经被排除
if (show[x][y] != '*' && show[x][y] != '@')
{
return;
}
int count = get_mine_count(mine, x, y);//周围雷的个数
if (count > 0)
{
show[x][y] = count + '0';//数字再转换为字符
return;
}
//递归拓展地图
else if (count == 0)
{
show[x][y] = '0';
board(mine, show, x - 1, y);
board(mine, show, x - 1, y - 1);
board(mine, show, x, y - 1);
board(mine, show, x + 1, y - 1);
board(mine, show, x + 1, y);
board(mine, show, x + 1, y + 1);
board(mine, show, x, y + 1);
board(mine, show, x - 1, y + 1);
}
}
}
//排查雷
int FindMine(char** mine, char** show)
{
//1.输入排查雷的坐标
//2.检查该坐标是不是雷
//(1)是雷 --> 很遗憾炸死了
//(0)不是雷 --> 统计坐标周围有几个雷-->存储排查雷的信息到show数组,游戏继续
int x = 0;
int y = 0;
int win = 0;
while (win < row*col - mine_num)//还没排查完就进入循环
{
SignMine(show);//标记雷
printf("请输入要排查的坐标: ");
scanf("%d %d", &x, &y);//x的范围是1~9,y的范围是1~9
//判断坐标的合法性
if (x >= 1 && x <= col && y >= 1 && y <= row)
{
if (mine[x][y] == '1')
{
printf("很遗憾,你被炸死了\n");
DisplayBoard(mine);//把怎么被炸死的显现出来
break;
}
else
{
//不是雷的话统计(x,y)坐标周围有几个雷
board(mine, show, x, y);
//显示排查出的信息
DisplayBoard(show);
win++;
}
}
else
{
printf("坐标不合法,请重新输入\n");
}
}
if (win == row * col - mine_num)//全部都排查完了
{
printf("恭喜你,排雷成功!\n");
return 1;
}
return 0;
}
test.c
#define _CRT_SECURE_NO_WARNINGS
#include"game.h"
int row = 0;//行
int col = 0;//列
int mine_num = 0;//雷的个数
int cmp(const void* a, const void* b)//传给qsort函数的参数比较函数
{
Rank* aa = (Rank*)a;
Rank* bb = (Rank*)b;
return aa->time > bb->time;//比较时间
}
//排行榜
void Update_Rank(Rank info)
{
Rank arr[6] = { 0 };//定义了一个结构体数组
for (int i = 0; i < 6; i++)
{
arr[i].time = INT_MAX;//默认为int范围的最大值
}
FILE* fp1 = fopen("rank.bin", "ab+"); //防止打开失败
if (!fp1)
{
printf("open failed");
return;
}
fseek(fp1, 0, SEEK_SET);//文件位置指针回到文件开头
int num = fread(arr, sizeof(Rank), 5, fp1);//读文件
arr[num] = info;//将结构体变量info存入数组下标为num处
qsort(arr, num + 1, sizeof(Rank), cmp);//排序
//打印排名
if (num <= 4)
{
for (int i = 0; i <= num; i++)
{
printf("%-20s %-20d 您的排名是:%d\n", arr[i].name, arr[i].time, i + 1);
}
}
else if (num >=5)
{
for (int i = 0; i <= 4; i++)
{
printf("%-20s %-20d 您的排名是:%d\n", arr[i].name, arr[i].time, i + 1);
}
}
FILE* fp2 = fopen("rank.bin", "wb"); //不能用ab+
if (!fp2)
{
printf("open failed");
return;
}
num = num < 5 ? num + 1 : 5;//最多只有5个
fwrite(arr, sizeof(Rank), num, fp2);//写文件
//关闭
fclose(fp1);
fclose(fp2);
}
void menu()
{
printf("**********************\n");
printf("***** 1.play *******\n");
printf("***** 0.exit *******\n");
printf("**********************\n");
}
void game()
{
int input = 0;
char name[20] = { 0 };
printf("请输入用户名: ");
scanf("%s", name);
printf("请选择游戏难度: \n");
printf("***** 1.easy *****\n");
printf("***** 2.normal *****\n");
printf("***** 3.hard *****\n");
scanf("%d", &input);
//选择难度
do {
scanf("%d", &input);
//选择难度
switch (input)
{
case 1:row = 4, col = 4, mine_num = 15;break;
case 2:row = 9, col = 9, mine_num = 10;break;
case 3:row = 11, col = 11, mine_num = 15;break;
default:printf("选择错误,请重新输入\n");
break;
}
} while (input!=1&& input!= 2&& input != 3);
//创建数组
char** mine = (char**)malloc(sizeof(char*) *(row + 2));
char** show = (char**)malloc(sizeof(char*) *(row + 2));
for (int i = 0; i < row+2; i++)
{
mine[i] = (char*)malloc(sizeof(char) * (col + 2));
show[i] = (char*)malloc(sizeof(char) * (col + 2));
}
//初始化mine数组为全字符'0'
InitBoard(mine, '0');
//初始化show数组为全'*'
InitBoard(show, '*');
//打印棋盘
DisplayBoard(show);//只打印9*9的内容
//布置雷
SetMine(mine);
DisplayBoard(mine);
//这是不给玩家看到的
//排查雷
int start = (int)clock();
int ret = FindMine(mine, show);//从mine中排查放到show中
Rank info;
strncpy(info.name, name, 20);
int end = (int)clock();
info.time = end - start;
if (ret)
Update_Rank(info);
free(mine);
free(show);
}
void test()
{
int input = 0;
srand((unsigned int)time(NULL));
do
{
menu();
printf("请选择: ");
scanf("%d", &input);
switch (input)
{
case 1:
//扫雷
game();
break;
case 0:
break;
default:
printf("选择错误");
break;
}
} while (input);
}
int main()
{
test();
return 0;
}