之前利用三子棋程序,介绍探讨了 c语言简单游戏编写主要模块及使用方法。
今天,我们就利用这个经典扫雷游戏,来加强对于程序思路的编写及思路。
目录
前引
首先,再次介绍 c 语言编写程序的三个主要程序
测试模块(主要由引用函数构成)
存放游戏菜单,设置游戏的开始、游戏方式逻辑、判断胜利、结束等整套流程的主要模块。
游戏模块(游戏运行函数主题)
存放测试模块中引用的具体游戏函数表达式
游戏调用模块(游戏头文件)
类型为头文件,通过它将游戏模块与测试模块联系起来,在其中申明函数,设置全局可控变量,调用库函数等全局操作。
游戏规则介绍
扫雷游戏的玩法是在一个自定义行列大小的方块矩阵中,随机布置一定量的地雷。
由玩家逐个翻开方块,以找出所有地雷为最终游戏目标,如果玩家翻开的方块有地雷,则游戏结束。
游戏的重点为,每一个方块被翻开时会自动显示出周围八格中含有雷的数量,以帮助玩家胜利。
一、基本游戏思路(游戏实现方法)
1.玩法构思
玩家通过给出的信息,将除去雷块的所有安全坐标找出。
2.游戏菜单打印输出
与玩家人机交互,进入或退出游戏。
3.地图初始化及变量设置
地图设置两个变量大小一致,一个为埋雷地图(mine map),一个为显示给玩家的展示地图(show map)。
4.布置地雷
利用rand函数随机输出坐标,将其中的值改变视为雷。
5.玩家排雷
玩家输入坐标,翻开并判断胜利条件,随后反馈翻开后的地图。
6.显示方块周围雷的数量
分别统计周围八格的地图含雷数,并在显示区中的坐标展示。
7.判断胜利条件
玩家选择到地雷,或所有空白地区全部被玩家翻开。
二、各步骤实例代码分析
1.菜单打印及回馈
这里的菜单与之前的三子棋程序基本一致(观看过的可跳过)
void menu()//菜单表制作
{ printf(" 欢迎来到扫雷游戏 \n");
printf("*********》请选择《***********\n");
printf("****** 1. 开始游戏 *******\n");
printf("****** 0. 退出游戏 *******\n");
printf("******************************\n");
}
int input = 0;//存放玩家输入数据
srand((unsigned int)time(NULL));
do
{
menu();
printf("请选择:>");
scanf_s("%d", &input);
switch (input)
{
case 1:
game();//扫雷游戏主程序
break;
case 0:
printf("退出游戏\n");
break;
default:
printf("选择错误,重新选择\n");
break;
}
} while (input);
注意
//这里使用do while, 保证菜单的第一次循环执行
2.地图变量设计技巧
由于我们程序的主要执行方式为数出周围雷数,所以当玩家翻动最外圈时,可能出现地图报错。
因此,我们在这可以将地图向外扩展一圈(打印地图时不打印)。
#define ROWS ROW+2
#define COLS COL+2
//地图变量行列定义
3.地图打印及列号标识
地图的打印是游戏实现人机交互的重要步骤,为了方便玩家输入坐标。所以,我们要在打印出地图的同时将行列号也打印出来。
int i = 0;
int j = 0;
//打印列号
for (i = 0; i <= col; 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");
}
4.利用rand函数设置雷
int count = MINE;//运用mine全局变量控制雷的数量
while (count)
{
//产生随机的下标
int x = rand()%row+1;
int y = rand()%col+1;
if (mine[x][y] == '0')
{
mine[x][y] = '1';
count--;
}
}
注意
坐标从一开始(符合玩家使用习惯),将普通方块设为‘0’ 雷设置为‘1’(方便日后统计雷数)
5.玩家排雷
int x = 0;
int y = 0;
int win = 0;
while (win<row*col- MINE)
{
printf("请输入要排查的坐标:>");
scanf_s("%d%d", &x, &y);//x--(1,9) y--(1,9)
//判断坐标的合法性
if (x >= 1 && x <= row && y >= 1 && y <= col)
{
if (mine[x][y] == '1')
{
printf("很遗憾,你被炸死了\n");
DisplayBoard(mine map, row, col);
break;
}
else
{
//不是雷情况下,统计坐标周围有几个雷
int count = get_mine_count(mine, x, y);
show[x][y] = count+'0'; //显示排查出的信息
DisplayBoard(show map, row, col);//打印show map地图
win++;//记录成功翻雷的次数。
}
}
else
{
printf("坐标不合法,请重新输入\n");
}
}
6. 统计排查雷数
static int get_mine_count(char mine[ROWS][COLS], int x, int y)
{
return mine[x - 1][y] +
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 + 1] - 8 * '0';//通过,此式算出结果后减去‘0’,就为数字。
}
注意
//static int 强制类型转换为数字
7.判断胜利条件
if (win == row * col - MINE)//通过win的数量判断游戏胜利条件
{
printf("恭喜你,排雷成功\n");
DisplayBoard(mine map, row, col);
}
当win的值为(所有各数-雷数=空白格数目)时,判断为游戏胜利。
三、游戏主体流程
游戏game函数的主体(即主体流程)
void game()
{
char mine map[ROWS][COLS] = {0};//存放布置好的雷的信息
char show map[ROWS][COLS] = {0};//存放排查出的雷的信息
//初始化地图
InitBoard(mine, ROWS, COLS, '0');// 初始化转化为'0'
InitBoard(show, ROWS, COLS, '*');// 初始化转化为'*'
//打印一下地图
DisplayBoard(show, ROW, COL);
//布置雷
SetMine(mine, ROW, COL);
//排查雷
FindMine(mine, show, ROW, COL);
}
四、总结
通过这个游戏程序的编写,大家应该对程序编写思路有了更深刻的理解。
至于扫雷游戏扩展的功能,包括连锁翻动,数据统计,排名分数,计时,选择游戏难度等附加功能。小编能力有限,还尚未开发。如果大家有想法可以优化游戏代码,欢迎大家共同与小编分享。
以上就是超详细分解c 语言——实现扫雷游戏的全部过程,在visual studio 2019环境下实现