目录
设计并实现一个扫雷游戏,使用C语言编程语言完成。游戏应具备基本的游戏功能,包括游戏界面、雷区生成、雷的布局、玩家操作、游戏状态判断等。
总体设计
- 使⽤控制台实现经典的扫雷游戏
- 游戏可以通过菜单实现继续玩或者退出游戏
- 扫雷的棋盘是9*9的格⼦
- 默认随机布置10个雷
- 可以排查雷 :
- 如果位置不是雷,就显⽰周围有⼏个雷
- 如果位置是雷,就炸死游戏结束
- 把除10个雷之外的所有⾮雷都找出来,排雷成功,游戏结束
游戏的界⾯:
- 菜单设计:
- menu() 函数用于显示游戏菜单,提供两个选项:退出游戏和开始游戏。
- 游戏逻辑设计:
- game() 函数实现了扫雷游戏的主要逻辑。
- 定义了两个二维字符数组 mine 和 show,分别用于存储雷的信息和展示信息。
- 通过调用 InitBoard 函数初始化棋盘,将所有元素置为 '0' 或 '*'。
- 使用 SetMine 函数在棋盘上随机布置雷,布置的雷数量为预设的值。
- 调用 DisplayBoard 函数分别显示布置好的雷信息和初始展示信息。
- 最后,通过调用 FindMine 函数让玩家逐步排查雷,更新展示信息。
- 游戏循环设计:
- test() 函数包含游戏循环,通过用户输入选择进行游戏或退出。
- 使用 srand 函数以当前时间作为种子,确保每次游戏的雷的位置是随机的。
- 主函数:
- main() 函数调用 test() 函数启动游戏。
总体来说,该扫雷游戏的设计采用了简单的控制台界面,玩家通过菜单选择是否开始游戏。游戏内部通过二维数组表示棋盘,使用随机数布置雷,然后玩家通过排查雷的过程逐步揭示雷的位置。
游戏的详细设计
扫雷的过程中,布置的雷和排查出的雷的信息都需要存储,所以我们需要⼀定的数据结构来存储这些信息。因为我们需要在9*9的棋盘上布置雷的信息和排查雷,我们⾸先想到的就是创建⼀个9*9的数组来存放信息。
- 那如果这个位置布置雷,我们就存放1,没有布置雷就存放0
假设我们排查(2,5)这个坐标时,我们访问周围的⼀圈8个⻩⾊位置,统计周围雷的个数是1 假设我们排查(8,6)这个坐标时,我们访问周围的⼀圈8个⻩⾊位置,统计周围雷的个数时,最下⾯的三 个坐标就会越界,为了防⽌越界,我们在设计的时候,给数组扩⼤⼀圈,雷还是布置在中间的9*9的坐 标上,周围⼀圈不去布置雷就⾏,这样就解决了越界的问题。所以我们将存放数据的数组创建成11*11 是⽐较合适。
再继续分析,我们在棋盘上布置了雷,棋盘上雷的信息(1)和⾮雷的信息(0),假设我们排查了某⼀个位置后,这个坐标处不是雷,这个坐标的周围有1个雷,那我们需要将排查出的雷的数量信息记录存储,并打印出来,作为排雷的重要参考信息的。如果存放在布置雷的数组中,这样雷的信息和雷的个数信息就可能或产⽣混淆和打印上的困难。这⾥我们采⽤另外⼀种⽅案,我们专⻔给⼀个棋盘(对应⼀个数组mine)存放布置好的雷的信息,再 给另外⼀个棋盘(对应另外⼀个数组show)存放排查出的雷的信息。这样就互不⼲扰了,把雷布置到 mine数组,在mine数组中排查雷,排查出的数据存放在show数组,并且打印show数组的信息给后期排查参考。 同时为了保持神秘,show数组开始时初始化为字符 '*',为了保持两个数组的类型⼀致,可以使⽤同⼀套函数处理,mine数组最开始也初始化为字符'0',布置雷改成'1'。如下图:
对应的数组应该是:
char mine[11][11] = {0};//⽤来存放布置好的雷的信息
char show[11][11] = {0};//⽤来存放排查出的雷的个数信息
对函数的声明和定义,我们设计三个⽂件:
1 test.c //⽂件中写游戏的测试逻辑
2 game.c //⽂件中写游戏中函数的实现等
3 game.h //⽂件中写游戏需要的数据类型和函数声明等
3.3 相关函数功能设计
根据总体设计内容,游戏主要通过使用二维数组和函数操作数据。
根据上面设计内容,主要功能如下:
用于初始化棋盘数组,是扫雷游戏中准备游戏开始的一个基础操作。
设计思路:
- 使用嵌套的 for 循环,分别遍历数组的行和列。
- 对于每个数组元素,使用 arr[i][j] = set; 将其初始化为指定的字符 set。
函数设计:
- 参数设计: 函数接受三个参数,分别是二维数组 arr,数组的行数 rows,数组的列数 cols,以及初始化的字符 set。
- 通用性: 通过将行数和列数作为参数传入,函数具有一定的通用性,可以用于不同大小的数组。
用于在控制台中展示扫雷游戏的当前状态,包括棋盘布局和已经排查的雷的信息。
设计思路:
- 使用嵌套的 for 循环,分别遍历数组的行和列。
- 打印列号,然后逐行打印行号和数组元素。
- 使用 %2d 控制列号和行号的格式,使得输出对齐整齐。
函数设计:
- 参数设计: 函数接受三个参数,分别是二维数组 arr,数组的行数 row,数组的列数 col。
- 通用性: 通过将行数和列数作为参数传入,函数具有一定的通用性,可以用于不同大小的数组。
- 格式控制: 使用 %2d 和 %2c 控制输出的格式,使得棋盘的行号、列号和元素对齐整齐。
用于在游戏开始时在棋盘上随机布置地雷。
设计思路:
- 使用 while 循环,确保地雷的数量达到指定的数量。
- 在每次循环中,生成随机坐标 (x, y),并检查该坐标是否已经布置了地雷。
- 如果坐标合法且未布置地雷,则在该坐标处布置地雷,并将地雷数量减一。
函数设计:
- 参数设计:函数接受三个参数,分别是二维数组 arr,数组的行数 row,数组的列数 col。
- 地雷数量:地雷的数量由常量 EAST_COUNT 控制,可在程序中灵活调整。
- 随机性: 使用 rand() 函数生成随机坐标,增加了地雷的随机性。
该函数的设计实现了扫雷游戏中的核心排雷逻辑,包括输入处理、判定踩雷、更新显示棋盘以及游戏结束的条件判断。
函数功能:
- 允许用户通过输入坐标 (x, y) 进行排雷。
- 判断输入的坐标的合法性,确保在有效范围内。
- 如果坐标合法,判断该坐标是否已经排查过,防止重复排查。
- 如果踩到雷,游戏结束,显示所有雷的位置。
- 如果没有踩到雷,统计该坐标周围的雷的数量,并更新显示棋盘。
- 循环继续,直到排查出所有非雷的格子,游戏胜利。
设计思路:
- 使用 while 循环,确保游戏在踩到雷或者排查完所有非雷格子后结束。
- 用户输入坐标,首先检查坐标的合法性,确保在有效范围内。
- 判断该坐标是否已经排查过,即 show[x][y] 是否为 '*',防止重复排查。
- 如果踩到雷,游戏结束,打印出全部雷的位置。
- 如果没有踩到雷,统计该坐标周围的雷的数量,并更新显示棋盘。
- 每次成功排查非雷格子后,判断是否达到胜利条件,即是否排查完所有非雷格子。
函数设计:
- 用户输入: 使用 scanf 获取用户输入的坐标,体验简单直观。
- 条件判断: 使用多重条件判断,包括坐标合法性、是否已经排查过、是否踩到雷等,确保游戏逻辑正确执行。
- 游戏结束条件: 游戏结束的条件是踩到雷或者排查完所有非雷格子。
总结
这个扫雷程序实现了一个简单的控制台扫雷游戏。程序主要分为三个文件:test.c 包含主函数和用户界面,game.h 包含函数声明和宏定义,以及 game.c 包含了扫雷游戏的核心逻辑。在游戏开始时,通过 InitBoard 函数初始化棋盘,并通过 SetMine 函数在棋盘上随机布置地雷。玩家通过 FindMine 函数进行排雷,输入坐标并根据周围雷的数量进行排查,直到游戏结束。游戏结果通过控制台输出,显示玩家是否成功排雷或者踩中雷。
整体设计简洁,通过函数模块化实现了代码的可读性和可维护性。使用了随机性增加游戏的趣味性,而简单的控制台界面则使得游戏易于上手。通过这个简单的扫雷程序,玩家能够体验到扫雷游戏的基本玩法和乐趣。