我把扫雷分成了以下的部分来实现
1 打印游戏菜单
2 在主函数中初始化两个棋盘再打印棋盘
3 在mine棋盘上随机生成boom个雷
4 选择标记模式还是扫雷模式,然后执行标记模式或者扫雷模式
5 判定是否胜利
关于棋盘,我选择了使用两个二维数组,第一个数组mine用来藏雷,第二个数组show用来给玩家看,通过show来反映翻开点附近的雷的个数
关于地雷数的统计
我定义的时字符类型的数组,因为show放的是*
对应ASCLL码表,'0'对应48,'9'对应57
'1'对应49,减去48就是数字1,也就表示有一个雷,
所以a[x-1][y-1]+a[x-1][y]+...九个数相加再减去9*48,就是a[x][y]这个位置九宫格的地雷数
先说明一下我使用的宏定义
#define COL 9 //列
#define ROW 9 //行
#define COLS 11 //列加2
#define ROWS 11 //行加2
#define boom 1 //地雷个数
#define tag 10 //允许的最大标记个数
因为扫雷需要判定选择点的九宫格位置的地雷个数,如果该点位于边界,比如a[0][0]那么定义的数组就无法凑出九宫格,所以我上下左右各加了一行或一列,全赋值为字符0,这样数组就多了两行两列,这时候我输入a[1][1]就是上面的a[0][0],a[0][0]+a[0][1]+...九个数相加再减去9*48,这样得到的值就是地雷的个数,边界的值本就没有雷,所以赋值为'0'没有任何不良影响,反而使得编程简化
int main 函数,主函数部分
int main()
{
int input = 0;
do
{
char mine[ROWS][COLS] = { '0' }; //初始化两数组
char show[ROWS][COLS] = { '0' };
srand((unsigned int)time(NULL));
for (int i = 0; i < ROWS; i++)
{
for (int j = 0; j < COLS; j++)
{
mine[i][j] = '0';
show[i][j] = '*';
}
}
menu(); //打印菜单
scanf("%d", &input); //是否进行游戏
switch (input)
{
case 1:
game(mine, show, ROW, COL); //上面输入1,则进入game函数
break;
case 0:
break;
}
} while (input == 1); //当输入的input不为1时退出循环,即退出游戏
}
game函数的实现,是联系所有函数的主题代码,判断胜利的函数也在这里面,建议先看其他部分函数的功能再看该函数
void game(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col)
{
int flag = 0; //flag是剩下的未被翻开的位置
int h = 1;
int a = 0;
int b = 0;
int c = 1;
produce_mine(mine, row, col);
printboard_mine(mine, row, col);
printboard_show(show, row, col);
while (flag != boom&& find(mine,show,row,col)!=boom) //当剩下的位置数等于炸弹数,或者标记正确的雷数等于炸弹数,说明玩家赢了,跳出循环
{
printf("输入1表示接下来是扫雷,输入0表示自己要标记雷或者取消标记\n"); //选择模式
scanf("%d", &h );
switch (h)
{
case 0:
mark_mine(mine,show,row,col); //记录标记位置
printboard_show(show, row, col);
break;
case 1:
scanf("%d %d",&a,&b);
scanf_mine(mine, show, row, col,a,b,&c); //翻开某个位置
if (c == 0) //c=0代表玩家踩到雷了,游戏结束
goto end1; //用goto跳转
else
{
for (int i = 1; i <= row; i++) //如果不是0就开始计算还有多少未被翻开的位置
{
for (int j = 1; j <= col; j++)
{
if (show[i][j] == '*')
flag = flag + 1;
}
}
printboard_show(show, row, col);
break;
}
}
}
end1:
if (c != 0)
{
printf("玩家赢了\n");
printf("\n");
}
}
第一部分:打印游戏菜单
void menu()
{
printf("****** 扫雷 ********\n");
printf("******************************\n");
printf("****** 1 . 开始游戏 *******\n");
printf("****** 0 . 退出游戏 *******\n");
printf("******************************\n");
}
第二部分
初始化棋盘:
char mine[ROWS][COLS] = { '0' }; //初始化两数组
char show[ROWS][COLS] = { '0' };
srand((unsigned int)time(NULL));
for (int i =