说到扫雷,我想大家应该都不陌生,今天实现基本的扫雷游戏
扫雷游戏:
1.需要存放布置好的雷的信息,存放排查出雷的信息,所以我们需要两个二维数组。
2.排查坐标的时候为了防止坐标越界,我们给数组增加两行,增加两列。
我们需要三个文件来实现代码:
1.test.c //测试的逻辑
2.game.h //用来声明函数
3.game.c //用来实现函数
步骤:
1.初始化数组 //布置雷的数组全部初始化为’0’ // 排查出雷的数组全部初始化为’*'.
2.打印数组 //比如11*11的数组,我们只需要打印9行9列的内容,因为多出来的是为了方便排查雷,不让数组越界
3.布置雷
4.排查雷
程序至少运行一次,所以我们用do while循环
void menu()
{
printf("**********************************\n");
printf("******** 1.Play ********\n");
printf("******** 0.Exit ********\n");
printf("**********************************\n");
}
void test()
{
int input = 0;
do
{
menu();//打印菜单
scanf("%d", &input);,不是1也不是0进入default语句重新输入
switch (input)
{
case 1://如果是1进入case1语句
game();
break;
case 0://是0退出程序
printf("Byebye\n");
break;
default://不是1也不是0进入default语句重新输入
printf("Try again!\n");
break;
}
} while (input);//只有是0的时候才跳出循环
}
int main()
{
test();
return 0;
}
在创建数组之前,我们需要知道数组有几行几列的元素,上面我们说了,需要在9*9的基础上多加两行
我们在game.h头文件中定义行和列
#include
#include
#include
#define ROW 9//定义9行
#define COL 9//定义9列
#define ROWS ROW+2//排查雷为了防止坐标越界,我们多加2行
#define COLS COL+2
#define Easy_count 10//雷的个数
//初始化数组
void init(char board[ROWS][COLS], int rows, int cols, char set);
//打印数组
void print(char board[ROWS][COLS], int row, int col);
//布置雷
void set_mine(char mine[ROWS][COLS], int row, int col);
//排查雷
void cheak_mine(char mine[ROWS][COLS], ch
game()函数内部代码:
void game()
{
srand((unsigned int)time(NULL));
char mine[ROWS][COLS] = { 0 };//创建布雷数组
char show[ROWS][COLS] = { 0 };//创建展示出来的数组
//初始化数组
init(mine, ROWS, COLS, '0');//把要布置雷的数组全部初始化为'0',所以把'0'传过去,等下用set接收
init(show, ROWS, COLS, '*');//把要展示出来的数组,初始化为'*'
//打印数组
//print(mine, ROW, COL);
print(show, ROW, COL);//ROW和COL是我们需要打印的行和列
//布置雷
set_mine(mine, ROW, COL);
//print(mine, ROW, COL);
//排查雷
//布置雷的数组和展示出来的数组都需要传过去,以便排雷和方便展示
cheak_mine(mine, show, ROW, COL);//
}
//初始化数组
void init(char board[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++)
{
board[i][j] = set;//set是我们实参传过来的'0',或者是'*'
}
}
}
//打印数组
void print(char board[ROWS][COLS], int row, int col)
{
int i = 0;
int j = 0;
printf(" 扫雷 \n");
for (j = 0; j <= col; j++)
{
printf("%d ", j);//打印列序
}
printf("\n");
for (i = 1; i <= row; i++)//打印每行的元素
{
printf("%d ", i);//打印行序
for (j = 1; j <= col; j++)//打印每列的元素
{
printf("%c ", board[i][j]);//以%c的形式打印每一个字符元素
}
printf("\n");
}
}
在布置雷之前,我们需要定义雷的个数在game.h头文件中
用rand和srand函数来生成随机布雷的值
因为是布雷,所以我们只需要在布置雷的数组里进行操作
//布置雷
void set_mine(char mine[ROWS][COLS], int row, int col)
{
int count = Easy_count;//把雷的个数放到count变量
while (count)//当雷布置完便不再进入循环
{ //假设row是9,取模9得到0-8之间的随机值,+1得到0-9之间的随机值
int x = rand() % row + 1;//得到行1-9之间的随机值
int y = rand() % col + 1;//得到列1-9直接的随机值
if (mine[x][y] == '0')
{//数组里的元素是'0'的话,我们把'1'放进去
mine[x][y] = '1';
count--;
}
}
}
排雷的话,我们需要把布雷的数组和展示出来的数组都传过去,方便排雷和展示
1.输入的行和列的值肯定是1-9之间,反之则是坐标输入错误
2.坐标输入正确的话,我们还需要判断:坐标是否被占用,坐标是不是雷
3.排除以上情况,我们就成功排一次雷
计算坐标周围位置是否有雷,有几颗雷,就在坐标位置显示周围雷的个数
//排查雷
int get_mine_count(char mine[ROWS][COLS], int x, int y)
{//把坐标周围的8个坐标的位置全部加在一起减8乘以字符0,得到的就是周围雷的个数
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 cheak_mine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col)
{
int x = 0;
int y = 0;
int win = 0;
while ((ROW*COL-Easy_count) > win)//每次进来如果排雷成功,win就+1,直到不再小于81-10的不是雷的坐标
{
printf("请输入:");
scanf("%d %d", &x, &y);//输入行和列
//如果行是1-9,列是1-9
if ((x >= 1 && x <= row) && (y >= 1 && y <= col))
{
//如果坐标不是'*',说明已被占用
if (show[x][y] != '*')
{
printf("坐标已被占用,重新输入\n");
continue;//直接省略下面代码,重新输入坐标
}
if (mine[x][y] == '1')
{//坐标是1说明坐标处是雷
printf("被炸死\n");
//打印出来,让玩家死个明白
set_mine(mine, ROW, COL);
break;//被炸死直接跳出循环
}
else
{//get_mine_count函数是计算坐标周围有几个雷,有几个雷就返回几给n
int n = get_mine_count(mine, x, y);
//n是整形,所以+上'0'
//如果返回来的是2,'0'的ascii码值是48,48+2=50,50在ascii码中对应的就是2
show[x][y] = n + '0';
print(show, ROW, COL);//排完一次雷打印出来
win++;//排雷成功win++
}
}
else//输入坐标不正确
{
printf("坐标错误,重新输入\n");
}
}
//如果每次都排雷成功,win一直在++,直到win等于坐标总个数减雷的个数
if (ROW * COL - Easy_count == win)
{
printf("Success!\n");
print(mine, ROW, COL);
}
}
#include "game.h"
void menu()
{
printf("**********************************\n");
printf("******** 1.Play ********\n");
printf("******** 0.Exit ********\n");
printf("**********************************\n");
}
void game()
{
srand((unsigned int)time(NULL));
char mine[ROWS][COLS] = { 0 };
char show[ROWS][COLS] = { 0 };
//初始化数组
init(mine, ROWS, COLS, '0');
init(show, ROWS, COLS, '*');
//打印数组
//print(mine, ROW, COL);
print(show, ROW, COL);
//布置雷
set_mine(mine, ROW, COL);
//print(mine, ROW, COL);
//排查雷
cheak_mine(mine, show, ROW, COL);
}
void test()
{
int input = 0;
do
{
menu();
scanf("%d", &input);
switch (input)
{
case 1:
game();
break;
case 0:
printf("Byebye\n");
break;
default:
printf("Try again!\n");
break;
}
} while (input);
}
int main()
{
test();
return 0;
}
#include "game.h"
//初始化数组
void init(char board[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++)
{
board[i][j] = set;
}
}
}
//打印数组
void print(char board[ROWS][COLS], int row, int col)
{
int i = 0;
int j = 0;
printf(" 扫雷 \n");
//打印列序
for (j = 0; j <= col; j++)
{
printf("%d ", j);
}
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 set_mine(char mine[ROWS][COLS], int row, int col)
{
int count = Easy_count;
while (count)
{
int x = rand() % row + 1;
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 - 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 cheak_mine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col)
{
int x = 0;
int y = 0;
int win = 0;
while ((ROW*COL-Easy_count) > win)
{
printf("请输入:");
scanf("%d %d", &x, &y);
if ((x >= 1 && x <= row) && (y >= 1 && y <= col))
{
if (show[x][y] != '*')
{
printf("坐标已被占用,重新输入\n");
continue;
}
if (mine[x][y] == '1')
{
printf("被炸死\n");
set_mine(mine, ROW, COL);
break;
}
else
{
int n = get_mine_count(mine, x, y);
show[x][y] = n + '0';
print(show, ROW, COL);
win++;
}
}
else
{
printf("坐标错误,重新输入\n");
}
}
if (ROW * COL - Easy_count == win)
{
printf("Success!\n");
print(mine, ROW, COL);
}
}
#include
#include
#include
#define ROW 9
#define COL 9
#define ROWS ROW+2
#define COLS COL+2
#define Easy_count 10
//初始化数组
void init(char board[ROWS][COLS], int rows, int cols, char set);
//打印数组
void print(char board[ROWS][COLS], int row, int col);
//布置雷
void set_mine(char mine[ROWS][COLS], int row, int col);
//排查雷
void cheak_mine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col);