游戏可以通过菜单实现继续玩或者退出游戏
• 扫雷的棋盘是9*9的格⼦
• 默认随机布置10个雷
• 可以排查雷
◦ 如果位置不是雷,就显⽰周围有⼏个雷
◦ 如果位置是雷,就炸死游戏结束
◦ 把除10个雷之外的所有雷都找出来,排雷成功,游戏结束
笔者新建了一个头文件:gane.h,两个源文件:game.c ; test.c
game.h里面用来定义变量和声明函数
game.c里存放具体函数
test.c里运行游戏,是正文
首先在test.c源文件中写出基本游戏运行框架
无非就一个循环
#include
#include"game.h"
int main()
{
int choice = 0;//用来读取用户的选择
do
{
menu();//打印菜单
scanf("%d",&choice);
switch (choice)
{
case 1:
{ printf("开始游戏\n");
game();//这里是还未创建的函数
break;
}
case 0:
printf("退出游戏\n");
break;
default :
printf("输入错误,重新输入\n");
break;
}
} while (choice);
return 0;
}
可以直接在源文件中创建menu函数,因为它的可引用范围比较小
添加菜单:
#define _CRT_SECURE_NO_WARNINGS 1
#include
#include"game.h"
void menu()
{
printf(
"****************\n"
"***请选择:>*****\n"
"****1.play******\n"
"****0.exit******\n"
"****************\n"
);
}
int main()
{
int choice = 0;//用来读取用户的选择
do
{
menu();//打印菜单
scanf("%d",&choice);
switch (choice)
{
case 1:
{ printf("开始游戏\n");
game();//这里是还未创建的函数
break;
}
case 0:
printf("退出游戏\n");
break;
default :
printf("输入错误,重新输入\n");
break;
}
} while (choice);
return 0;
}
从游戏逻辑来看
game函数中包括:初始化棋盘,打印棋盘,随机布置雷,显示周围雷的个数
这是一个布满雷的棋盘
问题是:如果排雷时访问到边缘,会越界,破环数组
所以这时候我们给行和列各自在9的基础上+2
多加一圈防止越界,这一圈我们可以不打印,不设雷
这里需要两个数组,一组是初始化后设雷用的,不显示,一组是给用户排雷用的,显示周围雷数
为了方便,这里直接在game.h里定义声明变量
然后要在test.c中包含:
#include“game.h"
下一步,把invisible全部元素初始化成字符类型的0
把visible全部元素初始化成字符类型的*
写函数:Initial_Board()
注意:这里传给函数的行和列分别是 ROW,COL
因为要打印9*9就够了,自己给加的两行不打印
基本模型:
运行结果:
现在,给每一行每一列加上标号,便于判断坐标
void Printf_Board(char board[ROW][COL], int row, int col)
{
int i = 0;
int j = 0;
for (i = 1;i <= 9;i++)
{
printf(" %d", i);//给每一列打印标号(纵坐标)
}
printf("\n");//打印完纵坐标后换行打印棋盘
for (i = 1; i <= row; i++)
{
printf("%d", i);//打印横坐标
for (j = 1; j <= col; j++)
{
printf("%c ", board[i][j]);
}
printf("\n");
}
}
看运行结果:
把invisible打印棋盘注释掉,成功隐藏(这步放哪都行)
随机布置,仍然沿用上次猜数字游戏中的格式
//布置雷
void Set_Mine(char board[ROWS][COLS], int row, int col)
{
int x = rand() % row + 1;
int y = rand() % col + 1;
int count = EASY_COUNT;
while (count)
{
if (board[x][y] == '0')
{
board[x][y] = '1';
}
count--;
}
}
game.c中的函数
在test.c里加入srand,这个语句调用一次就可以了,不需要循环调用
注意:记得在game.h里包含头文件
还有,声明函数和变量
思路:
1.多次排雷,用while循环,那循环条件呢?初始化一个变量win,如果win小于棋盘元素总数减去设雷数,那么正常进入循环
2.输入坐标排雷,所以要循环的scanf()
3.第一个选择:输入在棋盘元素范围内:
a.排到雷–炸死–循环结束
b.未排到雷–输出周围雷的个数–继续循环输入
输入不在范围内:
打印“非法,重输”
//排雷
void Find_Mine(char invisible[ROWS][COLS],char visible[ROWS][COLS], int row, int col)
{
int x = 0;
int y = 0;
int win = 1;
while (win < row * col - EASY_COUNT)
{
printf("请输入要排查的坐标:>\n");
scanf("%d %d", &x, &y);
if (x >= 1 && x <= row && y >= 1 && y <= col)
{
if (invisible[x][y] == '1')
{
printf("很遗憾,你被炸死了\n");
Printf_Board(invisible, ROW, COL);
break;
}
else
{
int num=Count_Mine(invisible, x, y);
visible[x][y] = num+'0';
Printf_Board(visible, ROW, COL);
win++;
}
}
else
printf("非法输入,重新输入\n");
}
if (win == row * col - EASY_COUNT)
printf("太棒啦,扫雷成功\n");
}
注意事项:1.在创建函数时,一定要两个函数都读取
2.在test.c中给函数传参时,一定要传ROWS,COLS(1111的),接受的时候,数组[ ]里也要是ROWS,COLS(1111的),因为排雷操作不能越界,而且自己加的两行不会打印,没有影响,但一定会影响行号列号,也就是影响坐标
上面在排雷函数中嵌套了一个叫Count_Mine()的函数
计算invisible棋盘上某元素周围雷的个数的
巧妙运用了ASCII码值
‘0’–48
‘1’–49
‘2’–50
‘3’–51
所以,计算方法可以是周围一圈字符代表的ASCII值相加减去8个‘0’的ASCII值
int Count_Mine(char invisible[ROW][COL], int x, int y)
{
return( invisible[x][y - 1] + invisible[x][y + 1] + invisible[x - 1][y - 1] + invisible[x - 1][y + 1] + invisible[x - 1][y]
+ invisible[x + 1][y - 1] + invisible[x + 1][y] + invisible[x - 1][y + 1] - 8 * '0');
}
好,完工
#define _CRT_SECURE_NO_WARNINGS 1
#define ROW 9
#define COL 9
#define ROWS ROW+2
#define COLS COL+2
#define EASY_COUNT 10
#include
#include
void Initial_Board(char board[ROWS][COLS], int rows, int cols, char set);
void Printf_Board(char board[ROWS][COLS], int row, int col);
void Set_Mine(char board[ROWS][COLS], int row, int col);
int Count_Mine(char invisible[ROW][COL], int x, int y);
#define _CRT_SECURE_NO_WARNINGS 1
#include"game.h"
#include
//初始化棋盘
void Initial_Board(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 Printf_Board(char board[ROWS][COLS], int row, int col)
{
int i = 0;
int j = 0;
printf("-----------扫雷开始-----------\n");
for (i = 1;i <= 9;i++)
{
printf(" %d", i);
}
printf("\n");
for (i = 1; i <= row; i++)
{
printf("%d", i);
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 x = rand() % row + 1;
int y = rand() % col + 1;
int count = EASY_COUNT;
while (count)
{
if (board[x][y] == '0')
{
board[x][y] = '1';
}
count--;
}
}
//排雷
void Find_Mine(char invisible[ROWS][COLS],char visible[ROWS][COLS], int row, int col)
{
int x = 0;
int y = 0;
int win = 1;
while (win < row * col - EASY_COUNT)
{
printf("请输入要排查的坐标:>\n");
scanf("%d %d", &x, &y);
if (x >= 1 && x <= row && y >= 1 && y <= col)
{
if (invisible[x][y] == '1')
{
printf("很遗憾,你被炸死了\n");
Printf_Board(invisible, ROW, COL);
break;
}
else
{
int num=Count_Mine(invisible, x, y);
visible[x][y] = num+'0';
Printf_Board(visible, ROW, COL);
win++;
}
}
else
printf("非法输入,重新输入\n");
}
if (win == row * col - EASY_COUNT)
printf("太棒啦,扫雷成功\n");
}
int Count_Mine(char invisible[ROW][COL], int x, int y)
{
return( invisible[x][y - 1] + invisible[x][y + 1] + invisible[x - 1][y - 1] + invisible[x - 1][y + 1] + invisible[x - 1][y]
+ invisible[x + 1][y - 1] + invisible[x + 1][y] + invisible[x - 1][y + 1] - 8 * '0');
}
#define _CRT_SECURE_NO_WARNINGS 1
#include
#include"game.h"
void menu()
{
printf(
"****************\n"
"***请选择:>*****\n"
"****1.play******\n"
"****0.exit******\n"
"****************\n"
);
}
void game()
{
char invisible[ROWS][COLS];
char visible[ROWS][COLS];
//初始化棋盘
Initial_Board(invisible,ROWS,COLS,'0');
Initial_Board(visible, ROWS, COLS, '*');
//打印棋盘
Printf_Board(visible, ROW, COL);
//Printf_Board(invisible, ROW, COL);
//布置雷
Set_Mine(invisible, ROW, COL);
//排雷
Find_Mine(invisible, visible, ROWS, COLS);
}
int main()
{
int choice = 0;//用来读取用户的选择
do
{
menu();//打印菜单
srand((unsigned int)time(NULL));
scanf("%d",&choice);
switch (choice)
{
case 1:
{ printf("开始游戏\n");
game();
break;
}
case 0:
printf("退出游戏\n");
break;
default :
printf("输入错误,重新输入\n");
break;
}
} while (choice);
return 0;
}