欢迎来到程序员的快乐!
目录
一、游戏规则
二、编程准备和分析
三、game.h
1、头文件的包含
2、#define 的作用是定义的标识符常量
3、函数的声明
四、游戏菜单界面打印
五、游戏逻辑函数
六、游戏相关函数的实现
七、游戏测试
八、game.c和text.c
哈喽,童年的你扫雷时真的了解游戏的规则吗?
在一块网格中,埋有若干颗雷。游戏开始后选择一块区域,若该网格为雷则失败,反之,显示这块区域周围8个网格中埋雷的个数。我们根据这个提示继续排雷直至胜利!
1、准备:
Text.c:测试游戏逻辑。
game.c:游戏相关函数的实现。
game.h:头文的包含、函数的声明、符号声明。
2、分析:
实现一个9*9的简易扫雷游戏,创建两个字符数组,
char mine[][]埋雷:存放布置雷的信息。
雷的个数(固定)我们设定为10,每次游戏开始后随机在棋盘上生成,雷用字符‘1’表示,非雷用字符‘0’表示。
注意:这里的‘1’和‘0’是char类型的!
char show[][]排雷:存放排查雷的信息。
打印出来的棋盘用“*”表示,用坐标选择网格区域,若是雷游戏结束,若不是雷,则显示这个网格周围8个区域相加的雷的个数。想到这里有的小伙伴可能会出现疑问,当我们排到棋盘的边缘时该怎么办呢?我们可以这样解决,创建数组的时候,我们多创建成11*11并初始化,在9*9的范围内布雷,保证雷不会出界,打印的时候只打印出9*9,。
小游戏的所有头文件引用,符号的定义和函数的声明
#pragma once
//头文件的包含
#include
#include
#include
//符号的定义
#define minenum 10
#define ROW 9
#define COL 9
#define ROWS ROW+2
#define COLS COL+2
//函数的声明
//初始化数组
void initboard(char board[ROWS][COLS],int rows,int cols,char set);
//打印棋盘
void printfboard(char board[ROWS][COLS], int row,int col);
//布置雷
void setmine(char board[ROWS][COLS],int row,int col);
//排雷
void findmine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col);
头文件的包含
#include
/* printf, scanf, puts, NULL */ #include /* srand, rand */ #include /* time */ #define 的作用是定义的标识符常量
minenum>代表布雷的个数。
ROW 9*9棋盘的行号。
COL 9*9棋盘的列号。
ROWS 11*11棋盘的行号.
COL S 11*11棋盘的列号.
函数的声明
初始化数组的函数
打印棋盘的函数
布置雷的函数
排雷的函数
1、自己动手写一个menu()函数实现菜单界面的打印。
//打印菜单
void menu()
{
printf("|------------Mine*Clearance --------|\n");
printf("|*********** 1.开始游戏 **********|\n");
printf("|*********** 0.退出游戏 **********|\n");
printf("|-----------------------------------|\n");
}
2、在主函数中使用do...while循环语句和switch多分支,实现选择不同选项出现不同的效果,我们暂时输出一句话来显示不同的效果。input是我们定义的一个变量,并把它当做循环和分支的条件表达式,当input = 1时开始游戏,input = 0 时退出游戏并且退出循环,input= 其它值时打印出一句错误提醒!
int main()
{
int input;
do
{
menu();
printf("请选择选项:>");
scanf("%d",&input);
switch (input)
{
case 0:
printf("退出游戏\n");
break;
case 1:
printf("开始游戏\n");
break;
default:
printf("选项错误,请重新输入:>\n");
}
} while (input);
return 0;
}
效果截图:
当我们在菜单界面选择1时,单单输出一句话肯定是不行的,所以我们要调用一个game()函数,来实现开始游戏后展现出的游戏效果。
//游戏逻辑
void game()
{
//创建字符数组存储数据
char mine[ROWS][COLS] = { 0 };
char show[ROWS][COLS] = { 0 };
//数组初始化
initboard(mine,ROWS,COLS,'0');
initboard(show, ROWS, COLS, '*');
//打印棋盘
printfboard(show, ROW, COL);
//布置雷
setmine(mine, ROW, COL);
printfboard(mine, ROW, COL);
//排雷
findmine(mine,show,ROW,COL);
}
1、创建两个11*11的字符数组,mine数组用来布雷,在游戏的过程中是隐藏的,show数组是我们直接操作的。
2、用来数组初始化的函数,四个参数分别为:数组、行、列、字符。
mine数组初始化成字符‘0’,show数组初始化成'*'。
3、打印棋盘、把初始化后的show数组打印。
4、布雷,在mine中操作,在9*9的范围内随机布雷,这里涉及到一个rand()函数,在下面会有详细介绍。
5、排雷:游戏过程中可能出现的情况:我们输入一个合法坐标后,
排到雷->游戏失败。
不是雷->在棋盘上返回一个信息提示玩家周围有几个雷。
排到只剩下雷,游戏胜利。
1、initboard()函数,形参set的作用是接收传来的‘0’和‘*’,达到两个数组分别初始化的效果!
void initboard(char board[ROWS][COLS], int rows, int cols, char set)
{
int i = 0;
int j = 0;
for (i = 0; i
2、printfboard()函数,虽然我们创建的是11*11的数组,但是我们只打印出9*9的棋盘,棋盘行号和列号的打印是为了玩家方便坐标的输入!
//打印棋盘
void printfboard(char board[ROWS][COLS], int row, int col)
{
int i = 0;
int j = 0;
printf("------------扫雷游戏------------\n");
for (i = 0; i<=row;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");
}
3、setmine()函数,在mine[][]数组中随机布雷
//布置雷
void setmine(char board[ROWS][COLS], int row, int col)
{
int count = minenum;//记录雷的个数
while (count)
{
int x = rand() % row + 1;
int y = rand() % col + 1;
if (board[x][y] == '0')
{
board[x][y] = '1';
count--;
}
}
}
rand()函数: 生成随机数,介于0和 RAND_MAX(32767)之间的随机整数。
我们输入的坐标是要在9*9棋盘的范围内的,所以布置雷的坐标也一定要符合条件,
rand() % row的范围是0到8,所以rand()% row +1这个表达式是满足条件的!
count记录雷的个数,每次布好一颗雷后自减。当count=0时跳出循环。
4、 findmine()函数,排查雷,输入一个坐标判断是否合法,如果合法,判断是不是雷,
是雷:游戏结束!
不是雷:返回一个信息告诉玩家这个区域周围一共有几颗雷,存储信息到show数组
在9*9的网格中排查到只剩下10个网格的时候游戏胜利
//排雷
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-minenum)
{
printf("请输入一个坐标:>");
scanf("%d %d", &x, &y);
//判断坐标是否合法
if (x > 0 && x <=row && y>0 && y <=col)
{
//判断是不是雷
if (mine[x][y] == '1')
{
printf("有炸弹,游戏结束!\n");
//游戏结束,打印结果
printfboard(mine,row,col);
break;
}
else
{
//不是雷,返回一个信息告诉玩家这个区域周围一共有几颗雷,存储信息到show数组
int count = get_mine_count(mine,x,y);
show[x][y] = count + '0';
printfboard(show, row, col);
win++;
}
}
else
{
printf("坐标错误!\n");
}
}
if (win >= row * col - minenum)
{
printf("排雷成功,游戏胜利!\n");
printfboard(mine,row,col);
}
}
int count = get_mine_count(mine,x,y);
show[x][y] = count + '0';
get_mine_count(mine,x,y)函数的作用是计算我们输入做标的周围有几颗雷,返回值返回到show[][]中。但是返回的是一个int 类型,而show是一个字符数组,所以这时我们可以让count + '0'转换成一个字符存到数组中去。
5、 findmine()函数中调用了一个get_mine_count(mine,x,y)函数,在不是雷的情况下给玩家返回一个提示周围有几颗雷的信息。
int get_mine_count(char mine[ROWS][COLS], int x, int y)
{
return mine[x - 1][y - 1] +
mine[x][y - 1] +
mine[x + 1][y - 1] +
mine[x + 1][y] +
mine[x + 1][y + 1] +
mine[x][y + 1] +
mine[x - 1][y] +
mine[x - 1][y + 1] - 8 * '0';
}
游戏失败:
游戏成功,这里为了方便,把布雷的个数改成80,提前打印mine[][]数组查看,测试游戏成功的情况:
game.c
#define _CRT_SECURE_NO_WARNINGS 1
#include "game.h"
//游戏相关函数的实现
//初始化数组
void initboard(char board[ROWS][COLS], int rows, int cols, char set)
{
int i = 0;
int j = 0;
for (i = 0; i");
scanf("%d %d", &x, &y);
//判断坐标是否合法
if (x > 0 && x <=row && y>0 && y <=col)
{
//判断是不是雷
if (mine[x][y] == '1')
{
printf("有炸弹,游戏结束!\n");
//游戏结束,打印结果
printfboard(mine,row,col);
break;
}
else
{
//不是雷,返回一个信息告诉玩家这个区域周围一共有几颗雷,存储信息到show数组
int count = get_mine_count(mine,x,y);
show[x][y] = count + '0';
printfboard(show, row, col);
win++;
}
}
else
{
printf("坐标错误!\n");
}
}
if (win >= row * col - minenum)
{
printf("排雷成功,游戏胜利!\n");
printfboard(mine,row,col);
}
}
text.c
#define _CRT_SECURE_NO_WARNINGS 1
//测试游戏的逻辑
#include "game.h"
//打印菜单
void menu()
{
printf("|------------Mine*Clearance --------|\n");
printf("|*********** 1.开始游戏 **********|\n");
printf("|*********** 0.退出游戏 **********|\n");
printf("|-----------------------------------|\n");
}
//游戏逻辑
void game()
{
//创建字符数组存储数据
char mine[ROWS][COLS] = { 0 };
char show[ROWS][COLS] = { 0 };
//数组初始化
initboard(mine,ROWS,COLS,'0');
initboard(show, ROWS, COLS, '*');
//打印棋盘
printfboard(show, ROW, COL);
//布置雷
setmine(mine, ROW, COL);
/*printfboard(mine, ROW, COL); */
//排雷
findmine(mine,show,ROW,COL);
}
int main()
{
srand((unsigned int)time(NULL));
int input;
do
{
menu();
printf("请选择选项:>");
scanf("%d",&input);
switch (input)
{
case 0:
printf("退出游戏\n");
break;
case 1:
game();
break;
default:
printf("选项错误,请重新输入:>\n");
}
} while (input);
return 0;
}
嘻嘻,今天的你快乐了吗!