发布时间:2023-09-11 13:00
目录
前言
一、扫雷游戏
二、整体分析
三、游戏的实现
1.实现test文件
2.实现game.h文件
3.实现game.c文件
3.1 初始化棋盘
3.2 打印棋盘
3.3 埋放地雷
3.4 判断行动(选择操作方式)
四、总结
五、全部代码
要学习扫雷游戏,可以先学会我写的五子棋详细教学,这个看起来就简单很多很多,但其实这个也不难,只不过这个稍微复杂一点点,根据自己的能力来进行学习~
扫雷游戏是作者在小学微机课天天玩的游戏,多么值得回忆的一款游戏,因为win11没有扫雷小游戏了~!于是我现在就把它用自己的方式写出来了~!!!不仅我要写出来,我还要帮助你们学会这个小游戏,包学包会,学不会给我评论,我手把手教会你~!
想必这个游戏也不需要我教学吧,大家应该都会玩,就是n×n的表格,然后在雷区中把所有地雷排查出来,就是这么简单~
我们先看看下面的图片~!
我先说明我要设计一个12×12的雷区,可能你们会好奇为什么不是9×9的大众方式,那是因为……我就喜欢剑走偏锋~
当然这时骗你们的,因为9×9的每个格子对应给的坐标比较好设计,10以上的就稍微细节一点,10以上的都会写了,那9×9岂不是信手拈来~
我是用多文件进行编写的,我也希望你们也这样写,因为到以后工作的时候都是分工完成一个项目,所以要学会封装自己的代码~!我将我每一个文件名先列出来,后面我也会写到~!
- game.h(用来定义和函数说明)
- test.c(用来执行程序)
- game.c(用来实现执行程序里的函数)
好~!接下来正式分析。
首先你开始就有三个操作方式:
- 可以直接点格子,进行排查雷区;
- 可以右键格子进行插小旗子进行标识;
- 可以右键插小旗子的格子进行解除标识;
当我们排查雷区的时候又有三种情况:
- 排查的地方不是雷,而且周围8个格子也不是雷,这时一下翻开一大片区域;
- 排查的地方不是雷,但是周围的8个格子中有雷,这时候只翻开一个区域;
- 排查的时候正好是雷,你直接就被炸飞了;
到这里,已经大概分析出来了,还有最基础的一点就是因为你每次排查雷区的时候,要有一个模板进行对照,再对是雷或者不是雷进行判断,所以要用到两个二维数组进行表示,一个用来展示给玩家看加密的,一个用来存放地雷(当然这个不能给玩家看,要不就是等于开挂了~),然后就是改将分析换算成代码,并且再添加细节,就大功告成了,接下来让我来详细讲解~!
玩家进入后会展示一个菜单供玩家选择,如果进入游戏PLAY就开始游戏,没玩过瘾就继续PLAY,被炸飞了,炸蒙了就可以退出EXIT。
所以这里要用到循环语句并对选择加以判断。
我们看game()这个函数,先是要定义两个二维函数,一个是用来埋放地雷的,一个是供给玩家看的。
然后就是初始化棋盘,你们可以看到不仅传了棋盘和ROWS、COLS(这个后面就会讲,先不要着急),还传了'0'和'*',这里'0'代表的是埋放地雷的二维数组用它来初始化,代表的是0个地雷,这里'*'代表的是给玩家看的,没有被排查的地方用它来表示。
然后就是设置雷,用时间戳(跟我用五子棋的那里一样~)生成随机坐标进行埋雷,然后将'0'变为'1'。
然后就是打印棋盘,这个下面详细讲。
然后就是判断行动,这里面也有一个菜单,分别是:
1.排查雷(外加拓展)
2.插旗子
3.取消旗子
#define _CRT_SECURE_NO_WARNINGS 1
#include"game.h"
void menu()
{
printf("\n");
printf("************ 菜单 *************\n");
printf("**************************************\n");
printf("****** 1.PLAY ****** 0.EXIT ******\n");
printf("**************************************\n");
printf("\n");
}
void game()
{
char mine[ROWS][COLS] = { 0 };
char show[ROWS][COLS] = { 0 };
//初始化棋盘
Init_Board(mine, ROWS, COLS, '0');
Init_Board(show, ROWS, COLS, '*');
//设置雷
Set_Mine(mine, ROW, COL);
//打印棋盘
Display_Board(show, ROW, COL);
//判断行动
Judge_Action(mine, show, ROW, COL);
//排查雷
//Find_Mine(mine, show, ROW, COL);
插旗子
//Set_Flag(show, ROW, COL);
//拓展(重要~!)
//Expansion(show, ROW, COL);
}
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");
default:
printf("输入错误,请重新输入~!\n");
}
} while (input);
return 0;
}
首先由下面的代码ROW、COL、ROWS、COLS,定义的这四个常数的意思是如图:
然后就是定义MINE_COUNT也就是雷的个数,用于调试难度,
下面的就是对游戏中用到的函数进行说明,方便再game.c中实现。
#pragma once
#include
#include
#include
//扫雷界面的行和列
#define ROW 12
#define COL 12
//实际的行和列
#define ROWS ROW + 2
#define COLS COL + 2
//雷的个数
#define MINE_COUNT 20
void Init_Board(char board[ROWS][COLS], int rows, int cols, int set);//初始化棋盘
void Display_Board(char board[ROWS][COLS], int row, int col);//打印棋盘
void Set_Mine(char board[ROWS][COLS], int row, int col);//埋放地雷
void Judge_Action(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col);//选择以下三个条件中的一个进行运行
//void Find_Mine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col);//排查雷
//void Set_Flag(char board[ROWS][COLS], int row, int col);//插旗子
//void Cancel_Set_Flag(char board[ROWS][COLS], int row, int col)//取消插旗子
将二维数组初始化为想要的情况。
void Init_Board(char board[ROWS][COLS], int rows, int cols, int set)//初始化棋盘
{
int i = 0;
for (i = 0; i < rows; i++)
{
int j = 0;
for (j = 0; j < cols; j++)
{
board[i][j] = set;//注意set是传过来的 '0'和'*'
}
}
}
用循环函数嵌套进行对棋盘的打印,注意看代码给的注解,里面说明了为什么这么写,这也是12×12需要考虑的地方~!
void Display_Board(char board[ROWS][COLS], int row, int col)//打印棋盘
{
int i = 0;
int j = 0;
printf("---------------扫雷游戏---------------\n");
for (j = 0; j <= col; j++)
{
if (j == 0)
{
printf(" ");
}
else
{
printf("%2d ", j);//2d是为了棋盘是10以上的时候与棋盘一一对应,否则对应不上~!
}
}
printf("\n");
for (i = 1; i <= row; i++)
{
printf("%2d ", i);//2d是为了棋盘是10以上的时候与棋盘一一对应,否则对应不上~!
for (j = 1; j <= col; j++)
{
printf("%c ", board[i][j]);//按照要求打印棋盘
}
printf("\n");
}
printf("\n");
}
这就是打印出棋盘的样子~左边是玩家看到的,右边是埋下的雷~!
采用时间戳的方式埋放地雷。
void Set_Mine(char board[ROWS][COLS], int row, int col)//设置炸弹
{
int count = MINE_COUNT;//设置炸弹的个数
while (count)
{
int x = rand() % row + 1;//采用时间戳,产生随机坐标
int y = rand() % col + 1;
if (board[x][y] == '0')
{
board[x][y] = '1';//用'1'代表炸弹
count--;
}
}
}
根据菜单对:
- 排雷.
- 插旗子.
- 取消旗子.
- 重新开始.
进行实施操作~!
void Menu()
{
printf("\n");
printf("**************************\n");
printf("***** 1.排雷 *****\n");
printf("**** 2.插旗子 *****\n");
printf("**** 3.取消旗子 *****\n");
printf("*** 0.重新开始游戏 ***\n");
printf("**************************\n");
printf("\n");
}
void Judge_Action(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col)//判断
{
int input = 0;
int win = 0;
int ret = 0;
do
{
Menu();
printf("\n请选择操作:>");
scanf("%d", &input);
switch (input)
{
case 1:
ret = Find_Mine(mine, show, row, col, &win);
if (ret == 1)
{
return;
}
break;
case 2:
Set_Flag(show, row, col);//设置旗子
break;
case 3:
Cancel_Set_Flag(show, row, col);//取消旗子
break;
case 0:
printf("\n已经为你跳转到菜单~!\n");
break;
default:
printf("\n输入错误,请重新输入~!\n");
Display_Board(show, row, col); //每次错误后都打印一遍棋盘,更容易观看,不用往上翻找~!
break;
}
} while (input);
}
3.4.1 排雷
先输入要排雷的坐标,并判断在不在棋盘有效范围内,在的话进行排雷,不在重新输入。
进行一系列的对坐标合法性的判断,下面的代码注解也的很详细,跟着看就能看懂。
重要的是Expansion(拓展),这个是用来实现点一下,如果这个坐标周围没有雷,直接展开一片,这样就会节省很多不必要的麻烦。
因为我们要的效果是一展一片,但是这样会很繁琐,所以我们就会想到用递归的方式去解决这个问题,因为递归的特点就是“把大事化小”。
写出一个你想要的效果,然后让坐标+1 -1,进行重复调用自己实现递归,这样就完成的展开一片的效果。
因为我们在排雷的时候要考虑到赢的情况,但是如果盲目的排雷,到最后剩余的都是雷你也胜利不了,所以这里一边拓展的时候,一边要用win++来代替我们拓展了多少个,也就是我们已经排了多少不是雷的地方,然后因为COL*ROW也就是游戏中格子的个数就应该等于MINE_COUNT雷的个数+win排查不是雷的个数,当他们相等的时候,就说明你已经排完所有的雷了,你就胜利了。
还要注意的就是我们获取雷的个数时,因为我们是以'1','0'来存放的,存放的是ASCII码,不是数字0和1,所以我们要用'1'和'0'分别减去'0'即可得到数字也就是雷的个数。(原理就是:'1'的ASCII码是49,'0'的ASCII码是48,相减得到的就是数字啦~!)
int Get_Mine_Count(char mine[ROWS][COLS], int x, int y)//获取周围炸弹的数量
{
return mine[x - 1][y - 1] +
mine[x - 1][y] +
mine[x - 1][y + 1] +
mine[x][y - 1] +
mine[x][y + 1] +
mine[x + 1][y - 1] +
mine[x + 1][y] +
mine[x + 1][y + 1] - 8 * '0';
}
void Expansion(char mine[ROWS][COLS],char show[ROWS][COLS], int x, int y, int *win)//如果周围没有炸弹就拓展
{
{//防止和下面的else混淆
if (x<1 || x>ROW || y<1 || y>COL)//防止边上一圈也被赋值
{
return;
}
if (show[x][y] != '*')
{
return;
}
}//防止和下面的else混淆
int count = Get_Mine_Count(mine, x, y);
if (count > 0)
{
(*win)++;
show[x][y] = count + '0';
return;
}
else//采用递归的方式进行拓展,上面的条件是为了防止死递归~!
{
(*win)++;
show[x][y] = ' ';
Expansion(mine, show, x - 1, y - 1, win);//win这里就是地址
Expansion(mine, show, x - 1, y, win);
Expansion(mine, show, x - 1, y + 1, win);
Expansion(mine, show, x, y - 1, win);
Expansion(mine, show, x, y + 1, win);
Expansion(mine, show, x + 1, y - 1, win);
Expansion(mine, show, x + 1, y, win);
Expansion(mine, show, x + 1, y + 1, win);
}
}
int Find_Mine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col, int* win)//排查雷
{
int x = 0;
int y = 0;
again:
printf("\n请输入一个坐标:>");
scanf("%d %d", &x, &y);
if (x >= 1 && x <= row && y >= 1 && y <= col)
{
if (show[x][y] != '*' && show[x][y] != '!')//排查的条件~!
{
printf("\n该坐标已经被排查过,或者这里有标记,请排查其他位置~!\n");
printf("如果需要排查,请先取消标记后再排查~!\n");
Display_Board(show, row, col);//每次错误后都打印一遍棋盘,更容易观看,不用往上翻找~!
goto again;//跳转到again
}
else
{
if (mine[x][y] == '1')
{
system("cls");
printf("\n游戏结束,你被炸飞了~!\n");
Display_Board(mine, ROW, COL);//每次错误后都打印一遍棋盘,更容易观看,不用往上翻找~!
return 1;
}
else
{
Expansion(mine, show, x, y, win);//展开
Display_Board(show, ROW, COL);//打印棋盘
}
}
}
else
{
printf("\n输入的坐标非法,请重新输入合法坐标\n");
Display_Board(show, row, col);//每次错误后都打印一遍棋盘,更容易观看,不用往上翻找~!
goto again;//跳转到again
}
if (*win == row * col - MINE_COUNT)//胜利条件是雷的个数加上排查过的坐标的个数与总格数相同~!
{
system("cls");//清屏
printf("\n恭喜你,排雷成功,没有别炸飞~!\n");
Display_Board(mine, ROW, COL);//每次错误后都打印一遍棋盘,更容易观看,不用往上翻找~!
return 1;
}
}
3.4.2 插旗子
一样的道理,先判断坐标的非法性,如果这个坐标是'*'但不是'!'那就可以插旗子('!'就是旗子的标识,已经插过就不要再插旗了嘛),如果不是就不能插旗子(因为要是数字的话说明周围有雷,但是这个数字不是雷,空格的话这个空格也不是雷,所以没有意义,所以只是'*')
void Set_Flag(char board[ROWS][COLS], int row, int col)//插旗子
{
int x = 0;
int y = 0;
while (1)
{
printf("\n请输入要标记的坐标:>");
scanf("%d %d", &x, &y);
if (x >= 1 && x <= row && y >= 1 && y <= col)
{
if (board[x][y] == '!')
{
printf("\n该坐标已标记,请重新输入~!\n");
Display_Board(board, row, col);//每次错误后都打印一遍棋盘,更容易观看,不用往上翻找~!
break;
}
else if (board[x][y] == ' ')
{
printf("\n该坐标不需要被标记,请重新输入~!\n");
Display_Board(board, row, col);//每次错误后都打印一遍棋盘,更容易观看,不用往上翻找~!
break;
}
else
{
board[x][y] = '!';
Display_Board(board, row, col);//每次错误后都打印一遍棋盘,更容易观看,不用往上翻找~!
break;
}
}
else
{
printf("\n输入坐标非法,请重新输入~!\n");
Display_Board(board, row, col);//每次错误后都打印一遍棋盘,更容易观看,不用往上翻找~!
break;
}
}
}
3.4.3 取消旗子
这里跟上面插旗子差不了多少,就是如果是旗子就可以取消,不是旗子就不可以取消,然后旗子取消之后就换成'*',因为'*'是没有排查的标志嘛~
void Cancel_Set_Flag(char board[ROWS][COLS], int row, int col)
{
int x = 0;
int y = 0;
while (1)
{
printf("\n请输入要取消标记的坐标:>");
scanf("%d %d", &x, &y);
if (x >= 1 && x <= row && y >= 1 && y <= col)
{
if (board[x][y] == '!')//有'!'就取消,没有就取消不了~!
{
board[x][y] = '*';
Display_Board(board, row, col);//每次错误后都打印一遍棋盘,更容易观看,不用往上翻找~!
break;
}
else
{
printf("\n该坐标没有被标记,无需取消标记~!\n");
Display_Board(board, row, col);//每次错误后都打印一遍棋盘,更容易观看,不用往上翻找~!
break;
}
}
else
{
printf("\n输入坐标非法,请重新输入~!\n");
Display_Board(board, row, col);//每次错误后都打印一遍棋盘,更容易观看,不用往上翻找~!
break;
}
}
}
我以文字打再外面的都是很重要的,代码里面的都是详细解释,可以根据详细解释进行理解,如果还有看不懂的,可以在评论区留言,我都会看,如果有问题,我都会解答~!
扫雷和五子棋一样,都是对数组的考察,只要你数组认识的还可以,你就可以写出这两个小游戏,当然你如果写出来这两个小游戏后,你会发现数组你已经了如指掌了~!
还有就是锻炼逻辑思维能力,如果这个你能搞懂,那么你现在的脑袋瓜肯定可以飞速运转,并且再将来遇到这种用逻辑写的题或者游戏,那不都是小喽喽么~
| game.h |
#pragma once
#include
#include
#include
//扫雷界面的行和列
#define ROW 12
#define COL 12
//实际的行和列
#define ROWS ROW + 2
#define COLS COL + 2
//雷的个数
#define MINE_COUNT 20
void Init_Board(char board[ROWS][COLS], int rows, int cols, int set);//初始化棋盘
void Display_Board(char board[ROWS][COLS], int row, int col);//打印棋盘
void Set_Mine(char board[ROWS][COLS], int row, int col);//埋放地雷
void Judge_Action(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col);//选择以下三个条件中的一个进行运行
//void Find_Mine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col);//排查雷
//void Set_Flag(char board[ROWS][COLS], int row, int col);//插旗子
//void Cancel_Set_Flag(char board[ROWS][COLS], int row, int col)//取消插旗子
| text.c |
#define _CRT_SECURE_NO_WARNINGS 1
#include"game.h"
void menu()
{
printf("\n");
printf("************ 菜单 *************\n");
printf("**************************************\n");
printf("****** 1.play ****** 0.exit ******\n");
printf("**************************************\n");
printf("\n");
}
void game()
{
char mine[ROWS][COLS] = { 0 };
char show[ROWS][COLS] = { 0 };
//初始化棋盘
Init_Board(mine, ROWS, COLS, '0');
Init_Board(show, ROWS, COLS, '*');
//设置雷
Set_Mine(mine, ROW, COL);
//打印棋盘
Display_Board(show, ROW, COL);
Display_Board(mine, ROW, COL);
Judge_Action(mine, show, ROW, COL);
//排查雷
//Find_Mine(mine, show, ROW, COL);
插旗子
//Set_Flag(show, ROW, COL);
//拓展(重要~!)
//Expansion(show, ROW, COL);
}
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");
default:
printf("输入错误,请重新输入~!\n");
}
} while (input);
return 0;
}
| game.c |
#define _CRT_SECURE_NO_WARNINGS 1
#include"game.h"
void Menu()
{
printf("\n");
printf("**************************\n");
printf("***** 1.排雷 *****\n");
printf("**** 2.插旗子 *****\n");
printf("**** 3.取消旗子 *****\n");
printf("*** 0.重新开始游戏 ***\n");
printf("**************************\n");
printf("\n");
}
void Init_Board(char board[ROWS][COLS], int rows, int cols, int set)//初始化棋盘
{
int i = 0;
for (i = 0; i < rows; i++)
{
int j = 0;
for (j = 0; j < cols; j++)
{
board[i][j] = set;//注意set是传过来的 '0'和'*'
}
}
}
void Display_Board(char board[ROWS][COLS], int row, int col)//打印棋盘
{
int i = 0;
int j = 0;
printf("---------------扫雷游戏---------------\n");
for (j = 0; j <= col; j++)
{
if (j == 0)
{
printf(" ");
}
else
{
printf("%2d ", j);//2d是为了棋盘是10以上的时候与棋盘一一对应,否则对应不上~!
}
}
printf("\n");
for (i = 1; i <= row; i++)
{
printf("%2d ", i);//2d是为了棋盘是10以上的时候与棋盘一一对应,否则对应不上~!
for (j = 1; j <= col; j++)
{
printf("%c ", board[i][j]);//按照要求打印棋盘
}
printf("\n");
}
printf("\n");
}
void Set_Mine(char board[ROWS][COLS], int row, int col)//设置炸弹
{
int count = MINE_COUNT;//设置炸弹的个数
while (count)
{
int x = rand() % row + 1;//采用时间戳,产生随机坐标
int y = rand() % col + 1;
if (board[x][y] == '0')
{
board[x][y] = '1';//用'1'代表炸弹
count--;
}
}
}
int Get_Mine_Count(char mine[ROWS][COLS], int x, int y)//获取周围炸弹的数量
{
return mine[x - 1][y - 1] +
mine[x - 1][y] +
mine[x - 1][y + 1] +
mine[x][y - 1] +
mine[x][y + 1] +
mine[x + 1][y - 1] +
mine[x + 1][y] +
mine[x + 1][y + 1] - 8 * '0';
}
void Expansion(char mine[ROWS][COLS],char show[ROWS][COLS], int x, int y, int *win)//如果周围没有炸弹就拓展
{
{//防止和下面的else混淆
if (x<1 || x>ROW || y<1 || y>COL)//防止边上一圈也被赋值
{
return;
}
if (show[x][y] != '*')
{
return;
}
}//防止和下面的else混淆
int count = Get_Mine_Count(mine, x, y);
if (count > 0)
{
(*win)++;
show[x][y] = count + '0';
return;
}
else//采用递归的方式进行拓展,上面的条件是为了防止死递归~!
{
(*win)++;
show[x][y] = ' ';
Expansion(mine, show, x - 1, y - 1, win);//win这里就是地址
Expansion(mine, show, x - 1, y, win);
Expansion(mine, show, x - 1, y + 1, win);
Expansion(mine, show, x, y - 1, win);
Expansion(mine, show, x, y + 1, win);
Expansion(mine, show, x + 1, y - 1, win);
Expansion(mine, show, x + 1, y, win);
Expansion(mine, show, x + 1, y + 1, win);
}
}
int Find_Mine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col, int* win)//排查雷
{
int x = 0;
int y = 0;
again:
printf("\n请输入一个坐标:>");
scanf("%d %d", &x, &y);
if (x >= 1 && x <= row && y >= 1 && y <= col)
{
if (show[x][y] != '*' && show[x][y] != '!')//排查的条件~!
{
printf("\n该坐标已经被排查过,或者这里有标记,请排查其他位置~!\n");
printf("如果需要排查,请先取消标记后再排查~!\n");
Display_Board(show, row, col);//每次错误后都打印一遍棋盘,更容易观看,不用往上翻找~!
goto again;
}
else
{
if (mine[x][y] == '1')
{
system("cls");
printf("\n游戏结束,你被炸飞了~!\n");
Display_Board(mine, ROW, COL);//每次错误后都打印一遍棋盘,更容易观看,不用往上翻找~!
return 1;
}
else
{
Expansion(mine, show, x, y, win);//展开
Display_Board(show, ROW, COL);//打印棋盘
}
}
}
else
{
printf("\n输入的坐标非法,请重新输入合法坐标\n");
Display_Board(show, row, col);//每次错误后都打印一遍棋盘,更容易观看,不用往上翻找~!
goto again;
}
/*}*/
if (*win == row * col - MINE_COUNT)//胜利条件是雷的个数加上排查过的坐标的个数与总格数相同~!
{
system("cls");
printf("\n恭喜你,排雷成功,没有别炸飞~!\n");
Display_Board(mine, ROW, COL);//每次错误后都打印一遍棋盘,更容易观看,不用往上翻找~!
return 1;
}
}
void Set_Flag(char board[ROWS][COLS], int row, int col)//插旗子
{
int x = 0;
int y = 0;
while (1)
{
printf("\n请输入要标记的坐标:>");
scanf("%d %d", &x, &y);
if (x >= 1 && x <= row && y >= 1 && y <= col)
{
if (board[x][y] == '!')
{
printf("\n该坐标已标记,请重新输入~!\n");
Display_Board(board, row, col);//每次错误后都打印一遍棋盘,更容易观看,不用往上翻找~!
break;
}
else if (board[x][y] == ' ')
{
printf("\n该坐标不需要被标记,请重新输入~!\n");
Display_Board(board, row, col);//每次错误后都打印一遍棋盘,更容易观看,不用往上翻找~!
break;
}
else
{
board[x][y] = '!';
Display_Board(board, row, col);//每次错误后都打印一遍棋盘,更容易观看,不用往上翻找~!
break;
}
}
else
{
printf("\n输入坐标非法,请重新输入~!\n");
Display_Board(board, row, col);//每次错误后都打印一遍棋盘,更容易观看,不用往上翻找~!
break;
}
}
}
void Cancel_Set_Flag(char board[ROWS][COLS], int row, int col)
{
int x = 0;
int y = 0;
while (1)
{
printf("\n请输入要取消标记的坐标:>");
scanf("%d %d", &x, &y);
if (x >= 1 && x <= row && y >= 1 && y <= col)
{
if (board[x][y] == '!')//有'!'就取消,没有就取消不了~!
{
board[x][y] = '*';
Display_Board(board, row, col);//每次错误后都打印一遍棋盘,更容易观看,不用往上翻找~!
break;
}
else
{
printf("\n该坐标没有被标记,无需取消标记~!\n");
Display_Board(board, row, col);//每次错误后都打印一遍棋盘,更容易观看,不用往上翻找~!
break;
}
}
else
{
printf("\n输入坐标非法,请重新输入~!\n");
Display_Board(board, row, col);//每次错误后都打印一遍棋盘,更容易观看,不用往上翻找~!
break;
}
}
}
void Judge_Action(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col)//判断
{
int input = 0;
int win = 0;
int ret = 0;
do
{
Menu();
printf("\n请选择操作:>");
scanf("%d", &input);
switch (input)
{
case 1:
ret = Find_Mine(mine, show, row, col, &win);
if (ret == 1)
{
return;
}
break;
case 2:
Set_Flag(show, row, col);//设置旗子
break;
case 3:
Cancel_Set_Flag(show, row, col);//取消旗子
break;
case 0:
printf("\n已经为你跳转到菜单~!\n");
break;
default:
printf("\n输入错误,请重新输入~!\n");
Display_Board(show, row, col); //每次错误后都打印一遍棋盘,更容易观看,不用往上翻找~!
break;
}
} while (input);
}
到这里已经接近尾声了,作者也是用了一天的时候想出来,写出来,然后各种测试代码然后发教学,如果可以的话,我想要你们的点赞、留言和收藏,当然你们也可以关注我,我也会出更多更多有用东西,现在把这两个游戏都做完,我就要开始整理知识点了,喜欢的朋友可以多多关注我哦,我说的有问题的地方也可以告诉我,我们一起进步,一起秃头~