目录
一、明确思路
//菜单-开始游戏-退出游戏-输入错误
//开始游戏:
//创建原始棋盘,用于设置雷;
//创建玩家操作棋盘,用于玩家排查雷时,展示棋盘及提示;
//初始化两个棋盘,并将雷设置在原始棋盘;
//展示玩家操作棋盘,开始排查雷;
//输入要排查的坐标,该坐标是雷则游戏失败;不是雷,则计算该坐标周围一格距离内雷的数量,并将该数字作为提示打印在排查的坐标上;
//直到将棋盘上不是雷的位置全部排查完毕,游戏胜利;
二、编译代码
1.编译入口代码
//代码实现打印菜单,并通过输入的input选择开始或退出游戏;
void menu()//菜单;
{
printf("----menu----\n1.Start\n0.Exit\n------------\n");
}
int main()
{
int input;
do
{
menu();
scanf("%d", &input);
switch (input)
{
case 1:
game();
break;
case 0:
printf("退出游戏\n");
break;
default:
printf("选择错误,请重新输入\n");
break;
}
} while (input);
return 0;
}
2.编译game函数
为方便棋盘行数列数和雷数量的更改,可进行预定义;
应注意,由于计算雷数量功能的代码实现是遍历坐标周围一格,所以当需要排查的坐标处于棋盘边缘,排查时,需避免越界情况;因此,棋盘的实际大小应比可操作棋盘大一圈,即行数+2,列数+2;
#define ROW 3 //ROW 行;
#define COL 3 //COL 列;
#define ROWS ROW+2 //ROWS 外围行;
#define COLS COL+2 //COLS 外围列;
#define MINE_COUNT 2 //MINE_COUNT 雷数量;
根据已明确的思路,编译game函数,则game函数中应有以下函数;(以下函数逻辑正确,后文不再重新整理)
char In_board[ROWS][COLS];//创建原始棋盘;
Init_board(In_board, ROWS, COLS, '0');//初始化原始棋盘;
char Out_board[ROWS][COLS];//创建玩家操作棋盘;
Init_board(Out_board, ROWS, COLS, '?');//初始化玩家操作棋盘;
Set_mine(In_board, ROW, COL);//设置雷;
//Show_board(In_board, ROW, COL);//展示原始棋盘;
Show_board(Out_board, ROW, COL);//展示玩家操作棋盘;
Find_mine(In_board, Out_board, ROW, COL);//排查雷;
2.1初始化原始棋盘和玩家操作棋盘
将原始棋盘初始化所有元素为 '0' ;
将玩家操作棋盘初始化所有元素为 '?' ;
声明;
//初始化棋盘;
void Init_board(char board[ROWS][COLS], int rows, int cols, char set);
函数中第四个函数参数 set 表示要将数组初始化为什么内容;
//初始化棋盘;
void Init_board(char board[ROWS][COLS], int rows, int cols, char set)
{
for (int i = 0; i < rows; i++)
{
for (int j = 0; j < cols; j++)
{
board[i][j] = set;
}
}
}
2.2设置雷
声明;
//设置雷;
void Set_mine(char board[ROWS][COLS], int row, int col);
实现雷的随机设置;将原始棋盘中的元素 '0' 设置为 '*' ;
使用 srand 函数,将计算机时间 time 转化为unsigned int型数据并作为随机数种子;
在main函数中包含以下代码,实现进入程序调用且只调用一次:
srand((unsigned int)time(NULL));//将计算机时间作为随机数种子;
使用 rand 函数,获取随机值;
//设置雷;
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] = '*';
count--;
}
}
}
使用 srand、rand 函数需要包含头文件 #include <stdlib.h>;
使用 time 函数需要包含头文件 #include <time.h>;
2.3展示棋盘
声明;
//展示棋盘;
void Show_board(char board[ROWS][COLS], int row, int col);
展示棋盘;棋盘左侧及上方增加数字显示,代表坐标,便于玩家识别、操作;
//展示棋盘;
void Show_board(char board[ROWS][COLS], int row, int col)
{
printf("-----扫雷-----\n");
for (int j = 0; j <= col; j++)
{
printf(" %d ", j);
}
printf("\n");
for (int i = 1; i <= row; i++)
{
printf(" %d ", i);
for (int j = 1; j <= col; j++)
{
printf(" %c ", board[i][j]);
}
printf("\n");
}
}
根据传输的不同数组名,打印出不同棋盘,结果如下:
原始棋盘,可以看到雷已经设置完毕;实际游戏中不应展示该棋盘,应屏蔽该代码;
玩家操作棋盘,无法看到雷的具体位置;
2.4排查雷
声明;
//排查雷;
void Find_mine(char In_board[ROWS][COLS], char Out_board[ROWS][COLS], int row, int col);
//明确思路:
//输入需要排查的坐标-坐标非法或重复则重新输入;
//坐标为 '*' 则排雷失败,展示雷在棋盘中的设置情况并返回菜单;
//无以上情况则使用 雷数量统计函数Count_mine 遍历坐标周围一格,计算其中 '*' 的数量,并将该数字作为提示打印在排查的坐标上;
//直到将棋盘上不是雷的位置全部排查完毕,游戏胜利,最后展示雷在棋盘中的设置情况;
应注意,结束游戏的条件是,(win < row * col - MINE_COUNT),即被排查的坐标数量,高于总坐标数量减去雷数量;
//排查雷;
void Find_mine(char In_board[ROWS][COLS], char Out_board[ROWS][COLS], int row, int col)
{
int x = 0, y = 0, win = 0;
while (win < row * col - MINE_COUNT)
{
printf("请输入需要排查的坐标\n");
scanf("%d %d", &x, &y);
if (x >= 1 && x <= row && y >= 1 && y <= col)
{
if (Out_board[x][y] == '?')
{
if (In_board[x][y] == '*')
{
printf("该坐标为雷,排雷失败\n");
Show_board(In_board, ROW, COL);
return;
}
else
{
Out_board[x][y] = Count_mine(In_board, x, y) + '0';
Show_board(Out_board, ROW, COL);
win++;
}
}
else
{
printf("重复排查坐标,请重新输入坐标\n");
}
}
else
{
printf("坐标非法,请重新输入\n");
}
}
if (win == row * col - MINE_COUNT)
{
printf("排雷成功,游戏获胜\n");
Show_board(In_board, ROW, COL);
}
}
雷数量统计函数Count_mine
遍历坐标周围,计算并返回其中 '*' 的数量;
//雷数量小计;
int Count_mine(char original[ROWS][COLS], int x, int y)
{
int count = 0;
for (int i = x - 1; i <= x + 1; i++)
{
for (int j = y - 1; j <= y + 1; j++)
{
if (original[i][j] == '*')
{
count++;
}
}
}
return count;
}
三、程序运行
(--end--)