初始界面 排雷界面 排雷失败界面
布置好雷的棋盘
越界问题需注意!
排雷的假设界面 多加一圈防止越界
mine数组初始化状态 show数组初始化状态
char mine[11][11];//⽤来存放布置好的雷的信息
char show[11][11];//⽤来存放排查出的雷的个数信息
小江之前学习了多文件的形式对函数的声明和定义,这里我们实践⼀下,我们设计三个文件(其他方法也可以):
1. test.c //⽂件中写游戏的测试逻辑
2. game.c //⽂件中写游戏中函数的实现等
3. game.h //⽂件中写游戏需要的数据类型和函数声明等
首先,玩游戏必不可少的就是菜单和游戏选项;其次,游戏需要多次进行,少不了循环。
排雷游戏设置步骤:开始——>初始化棋盘——>打印棋盘——>布置雷——>排雷——>结束
#include"game.h"
//自定义头文件用“ ”
//game.h中包含#include等一系列头文件,变量,函数定义——>这样只用写一遍,3个文件就都能使用了
void menu()
{
printf("*********************************\n");
printf("********** 1.Play **********\n");
printf("********** 2.Exit **********\n");
printf("*********************************\n");
}
int main()
{
//输入
int input = 0;
//选择是否玩游戏
do
{
menu();
printf("请选择是否进行游戏:");
scanf("%d ", &input);
switch (input)
{
case 1:
game();//如果玩游戏,就进入game函数实现游戏,我们这里先注重逻辑,之后再完善game()
break;
case 0:
printf("结束游戏\n");
break;
default:
printf("输入错误,请重新输入:\n");
break;
}
} while (input);//为了保证多次游戏和可以重来的机会,需要循环
return 0;
}
初步编写初始化棋盘函数和打印棋盘函数函数
void game()
{
//创建数组存放
char mine[ROWS][COLS];//存放布置好的雷和非雷 ROWS代表行数 COLS代表列数
char show[ROWS][COLS];//存放排查出的雷的信息
//初始化棋盘
//1.mine数组初始化为‘0’
//2.show数组初始化为‘*’
InitBoard(mine, ROWS, COLS, '0');
InitBoard(show, ROWS, COLS, '*');
//打印棋盘
DisplayBoard(mine, ROW, COL);//在这里我们可以先打印出来看看效果,但mine对应端棋盘应当隐藏起来,保证游戏“神秘化”
DisplayBoard(show, ROW, COL);
//布置雷
//排查雷
}
自定义行列数和初始化棋盘函数和打印棋盘函数
#define _CRT_SECURE_NO_WARNINGS 1//保证scanf()可以正常运行,否则vs2022报错或警告
//游戏的函数的实现
#include
//用字符代替数字,方便以后更改,如果行列用数字表示,以后更改很麻烦,需要多处更改
//ROW———>9行
//COL———>9列
#define ROW 9
#define COL 9
//ROWS———>11行
//COLS———>11列
#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);
//布置雷
//排查雷
1.总共11*11,但是其中只有9*9需要打印出来,最外圈隐藏起来防止越界
2.打印出行数列数(0-9)更方便输入坐标
//游戏的实现
#include"game.h"
void InitBoard(char board[ROWS][COLS], int rows, int cols, char set)
{
int i = 0;
for (i = 0; i
打印初始化棋盘的效果
别忘记隐藏DisplayBoard(mine, ROW, COL);
隐藏后的初始化棋盘的效果
1.雷的个数
雷的个数要确定,用字符表示方便以后更改
2.雷的位置
雷每次游戏时需要重新随机布置——>需要随机数——>随机数函数
随机函数不了解的宝子,链接放这里了:http://t.csdn.cn/0ETFB
布置雷的范围在9*9之中,只需传参ROW(9)和 COL(9)即可,排雷同样
//void game()中
//布置雷
SetMine(mine, ROW, COL);//将雷布置在mine中即可
DisplayBoard(mine, ROW, COL);//打印一下看一下结果,正式游戏时需要隐藏
//int main()中
//输入
int input = 0;
srand((unsigned int)time(NULL));//放在main()中,只需调用一次
//选择是否玩游戏
#include
#include
#define EASY_COUNT 10
//布置雷
void SetMine(char mine[ROWS][COLS], int row, int col);
涉及生成随机数的范围的知识点,上面的链接中有哦。
void SetMine(char mine[ROWS][COLS], int row, int col)
{
//布置雷需要每次都随机布置---->生成随机数
int count = EASY_COUNT;
//设置随机数,范围在1-9行,1-9列,每次游戏都需要重新设置
while (count)
{
int x = 1 + rand() % row ;//任何数除以9余数都在0-8之中,余数+1得到范围1-9;
int y = 1 + rand() % col ;
//考虑到只有没有布置过雷的地方才能布置---->if()条件限制
if (mine[x][y] == '0')
{
mine[x][y] = '1';
count--;//共10个雷每次布置完一个次数-1直至为0,结束循环
}
}
}
布置好雷的棋盘的效果
//排查雷
FindMine(mine ,show , ROW, COL);//FindMine函数涉及到2个数组:从mine数组中排查,将排查出的信息放到show数组中
//排查雷
void FindMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col);
1.排雷有次数限制(总次数 = 行 * 列 — 雷个数)
如果被炸死,则结束游戏;如果直到排完都没被炸死则成功。
2.雷的分布显示
没被炸死时,给出坐标周围的雷个数,如下图所示:
3.周围的雷的个数统计——int count=GetMineCount(mine, x, y)
将统计的周围的雷的个数统计完后并相加得到总个数,(x,y)即为排查的坐标
x:行数
y:列数
x-1,y-1 | x-1,y | x-1,y+1 |
x,y-1 | x,y | x,y+1 |
x+1,y-1 | x+1,y | x+1,y+1 |
但是,字符‘0’和‘1’怎么相加减呢?
根据ASCLL码表可知,48——>'0' 49——>'1'
所以,‘1’ - ‘0’ =49 -48 =1 1 + ‘0’ =1 + 48 =‘1’
数字字符 - ‘0’ =对应数字
int GetMineCount(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 + 1][y - 1] +
mine[x + 1][y + 1] +
mine[x + 1][y] +
mine[x][y + 1] - 8 * '0');
}
void FindMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col)
{
int x = 0;
int y = 0;
int win = 0;
while (win < row * col - EASY_COUNT)//排雷次数限制
{
printf("请输入要排查的坐标:");//需循环多次输入---->while()循环
scanf("%d %d", &x, &y);
if (x >= 1 && x <= row && y >= 1 && y <= col)
{
if (mine[x][y] == '1')
{
printf("很遗憾,你被炸死了\n");
DisplayBoard(mine, ROW, COL);//显示mine对应的棋盘,看看雷的分布
break;
}
else
{
int count = GetMineCount(mine, x, y);//统计输入坐标周围雷的个数
show[x][y] = count + '0';//将统计到的输入坐标周围雷的个数存放到show对应的棋盘中
DisplayBoard(show, ROW, COL);
win++;//每排一次雷次数+1,直到排查完没有雷的地方
}
}
else //坐标不满足范围
{
printf("输入非法坐标,请重新输入\n");
}
}
if (win == row * col - EASY_COUNT)
{
printf("恭喜你,排雷成功\n");
DisplayBoard(mine, ROW, COL);//显示mine对应的棋盘,看看雷的分布
}
}
排雷的实现
#define _CRT_SECURE_NO_WARNINGS 1//保证scanf()可以正常运行,否则vs2022报错或警告
#include "game.h"//包含自定义的头文件用“ ”
//游戏的逻辑实现
void menu()
{
printf("*********************************\n");
printf("********** 1.Play **********\n");
printf("********** 2.Exit **********\n");
printf("*********************************\n");
}
void game()
{
//创建数组存放
char mine[ROWS][COLS];//存放布置好的雷和非雷
char show[ROWS][COLS];//存放排查出的雷的信息
//初始化棋盘
//1.mine数组初始化为‘0’
//2.show数组初始化为‘*’
InitBoard(mine, ROWS, COLS, '0');
InitBoard(show, ROWS, COLS, '*');
//打印棋盘
//DisplayBoard(mine, ROW, COL);//mine对应端棋盘应当隐藏起来
DisplayBoard(show, ROW, COL);
//布置雷
SetMine(mine, ROW, COL);//将雷布置在mine中即可
//DisplayBoard(mine, ROW, COL);//打印一下看一下结果
//排查雷
FindMine(mine ,show , ROW, COL);//FindMine函数涉及到2个数组:从mine数组中排查,将排查出的信息放到show数组中
}
int main()
{
//输入
int input = 0;
srand((unsigned int)time(NULL));//放在main()中,只需调用一次
//选择是否玩游戏
do
{
menu();
printf("请选择是否进行游戏:");
scanf("%d ", &input);
switch (input)
{
case 1:
game();
break;
case 0:
printf("结束游戏\n");
break;
default:
printf("输入错误,请重新输入:\n");
break;
}
} while (input);//为了保证多次游戏和可以重来的机会,需要循环
return 0;
}
#define _CRT_SECURE_NO_WARNINGS 1//保证scanf()可以正常运行,否则vs2022报错或警告
//游戏的函数的实现
#include
#include
#include
#define ROW 9
#define COL 9
#define ROWS ROW+2
#define COLS COL+2
#define EASY_COUNT 10
//函数的声明
//初始化棋盘
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);
//游戏的实现
#include"game.h"
void InitBoard(char board[ROWS][COLS], int rows, int cols, char set)
{
int i = 0;
for (i = 0; i 生成随机数
int count = EASY_COUNT;
//设置随机数,范围在1-9行,1-9列,每次游戏都需要重新设置
while (count)
{
int x = 1 + rand() % row ;//任何数除以9余数都在0-8之中,余数+1得到范围1-9;
int y = 1 + rand() % col ;
//考虑到只有没有布置过雷的地方才能布置---->if()条件限制
if (mine[x][y] == '0')
{
mine[x][y] = '1';
count--;//共10个雷每次布置完一个次数-1直至为0,结束循环
}
}
}
int GetMineCount(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 + 1][y - 1] +
mine[x + 1][y + 1] +
mine[x + 1][y] +
mine[x][y + 1] - 8 * '0');
}
void FindMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col)
{
int x = 0;
int y = 0;
int win = 0;
while (win < row * col - EASY_COUNT)//排雷次数限制
{
printf("请输入要排查的坐标:");//需循环多次输入---->while()循环
scanf("%d %d", &x, &y);
if (x >= 1 && x <= row && y >= 1 && y <= col)
{
if (mine[x][y] == '1')
{
printf("很遗憾,你被炸死了\n");
DisplayBoard(mine, ROW, COL);//显示mine对应的棋盘,看看雷的分布
break;
}
else
{
int count = GetMineCount(mine, x, y);//统计输入坐标周围雷的个数,先初步定义
show[x][y] = count + '0';//将统计到的输入坐标周围雷的个数存放到show对应的棋盘中
DisplayBoard(show, ROW, COL);
win++;//每排一次雷次数+1,直到排查完没有雷的地方
}
}
else //坐标不满足范围
{
printf("输入非法坐标,请重新输入\n");
}
}
if (win == row * col - EASY_COUNT)
{
printf("恭喜你,排雷成功\n");
DisplayBoard(mine, ROW, COL);//显示mine对应的棋盘,看看雷的分布
}
}