目录
- 1. 扫雷游戏的分析与设计
- 1. 扫雷游戏的功能说明
- 2. 游戏的分析与设计
- 1. 游戏菜单的设计
- 2. 游戏棋盘的设计
- 2. 游戏的扩展
前言
扫雷是一款经典的益智小游戏,规则简单却充满挑战:玩家需要在不踩中地雷的前提下,通过数字提示推理出所有安全格子。本文将以 C 语言为例,从零开始带你一步步实现一个控制台版扫雷游戏。
我们将按照「功能说明 → 分析与设计 → 代码实现 → 扩展思路」的顺序展开。在分析与设计阶段,重点讲解如何用二维数组存储棋盘信息、如何解决数组越界问题、以及如何用两个数组分别管理「雷的分布」和「玩家排查结果」。在代码实现阶段,会给出 game.h、game.c、test.c 三个文件的完整设计思路与关键代码,并附上调试效果图。
无论你是刚学完 C 语言基础、想通过小项目巩固知识的新手,还是想了解如何把一个想法拆解成可落地代码的初学者,这篇文章都适合你。读完本文,你将能独立写出一个可运行的扫雷游戏,并掌握模块化编程的基本思路。
1. 扫雷游戏的分析与设计
1.扫雷游戏的功能说明
·使用控制台实现经典的扫雷游戏 解释:控制台也就是我们常用到的命令提示符
·游戏可以通过菜单来实现继续玩或退出游戏
·扫雷的棋盘是9*9的格子
·默认随机布置10个雷
·可以排查雷,有3种情况:
(1)如果位置不是雷,就显示周围有几颗雷的信息
(2)如果位置是雷,则被炸死游戏结束
(3)如果将除10个雷之外的所有非雷的位置排查出来,则游戏胜利
2.游戏的分析与设计
1.游戏菜单的设计
进入游戏首先我们会先看见游戏的一个主界面,也就是主菜单,让我们去选择继续玩或退出游戏,通过以上描述,在结合我们在猜数字游戏写的菜单就可以写出以下代码了
首先我们先创建game.h、game.c、test.c 3个文件,如下图:
游戏菜单的显示(test.c)
纠错:以上图片中,菜单每句输出都少了换行
显示游戏菜单后,我们要进行选择继续玩或退出游戏(test.c)
根据玩家的选择对应不同的情况(继续玩、退出游戏、输入错误)(test.c)
2.游戏棋盘的设计
扫雷过程中,我们要对布置雷和非雷位置提供周围雷数量的信息进行存储,为了在棋盘上存放信息,我们首先会想到用99的二维数组
对于布置雷的信息,如果这个位置布置雷,我们存放1,不布置雷,存放0
对于非雷位置提供周围雷数量的信息
假设我们排(2,5),访问周围一圈,得到周围雷的数量为1
假设我们排(8,6),访问周围一圈发现最下面的3个坐标发生了越界,为了解决越界的问题,
我们是不是可以扩大以下访问的区域,将棋盘周围扩大1圈,但是雷的信息仍存放在99棋盘中,扩大的1圈不去存放布置雷的信息,所以我们创建了11*11的二维数组去存放信息
我们继续分析,在棋盘上布置雷,雷为1,非雷为0;假如遇到这种情况,排雷时排查到非雷的位置,周围一圈的雷数量为1,要将这个信息记录存放,但是这个信息存放在哪呢?若存放在布置雷的数组内,则会与布置雷的信息发生混淆和打印上的困难。这时候我们可能会想到去改变布置雷的信息,不使用数字,用某种字符就行了,虽然这样能解决冲突,但是这样做棋盘上有雷和非雷的信息,还有排查出的雷的个数信息,就比较混杂,不够方便。
这里我们采取另一种方案:使用2个二维数组,一个数组用来存储布置雷的信息,另一个数组用来存储排查雷的个数的信息。雷存放在mine数组内,在mine数组内排查雷,排查到的数据存放在show数组数组里面,并打印show数组的信息帮助排雷游戏的进行。
首先创建2个数组(test.c)
为了保持神秘,show数组初始化为’‘,为了保持两个数组的类型一致,可以使用同一
套函数处理,mine数组最开始也初始化为字符’0’,布置雷改成’1’。如下如:
2个数组的初始化(test.c)初始化函数的声明(game.h)
初始化函数的定义(game.c),要包含game.h的头文件
我们做的是一个99的棋盘,但是如果我们想要生成别的大小的棋盘,我们要把全部关于棋盘大小的数据去进行修改,操作很繁琐,我们这时会想到用变量去控制棋盘大小,改变变量就可以改变关于棋盘的所有数据
创建改变棋盘大小的变量(game.h)
修改各处代码(均要包含头文件)
game.h
game.c
test.c
在将棋盘初始化后,我们想看一下初始化后棋盘的效果,这时候我们就要去将棋盘打印在屏幕上去观察
创建打印棋盘函数(test.c)
打印棋盘函数的声明(game.h)
打印棋盘函数的定义(game.c)
调试一下,打印的效果如下:
但是对于我们在玩排查雷时,但是使用上面的棋盘,我们定位速度就会显得很慢,我们是否可以去将这个打印函数去改进一下,在打印布置雷的信息和排查雷的信息时,同时可以把行号和列号一起打印出来。
代码改进如下:
调试一下,棋盘显示效果如下:
在我们玩扫雷游戏时,布置雷的信息不会打印出来,只会打印排查雷的信息,所以要把打印布置雷的信息给注释掉
棋盘的初始化和打印完成之后,接下来就是在mine数组内去布置雷了
创建布置雷的函数(test.c)
布置雷函数的声明(game.h)
由于我们想要布置雷的位置是随机的,那我们就要用到之前猜数字游戏的rand函数和srand函数了,这里不做过多的讲解
棋盘大小可以调整,那么布置雷的个数是不是也可以去调整?
定义布置雷的个数(game.h)
布置雷函数的定义(game.c)
我们要使用到rand函数,就必须要用srand函数去改变种子的大小
srand函数的创建及种子的设置(test.c)
以及使用这些函数要包含的头文件(game.h)
因为include <stdio.h>和include "game.h"每个文件都要包含,干脆直接将它整合到game.h
布置好之后,我们是不是开始要排查雷了,排查时,若排查到不是雷的地方,该位置是不是要提供它所在周围一圈的雷的数量信息;若排查到雷时,则游戏结束;若将除了雷的非雷位置全部排查出来,则游戏胜利。
创建排查雷函数(game.c)
(1)玩家输入排查坐标功能和循环排雷条件的选取
纠错:Findmine函数的返回类型为void
(2)判断玩家输入坐标是否合法
纠错:printf后补一个;
(3)有两种情况,第一种情况,排查的坐标是布置雷的位置
第二种情况,排查的坐标是非雷的位置,要显示周围一圈的雷数
统计周围的雷数
法1.
纠错:形式参数x、y的数据类型为int
法2.
接上面的第二种情况,完善代码
最后测试代码
将雷数量改为80
将mine棋盘打印出来,方便看非雷位置,为了测试游戏胜利的情况
运行结果:
2.游戏的扩展
总结
本文从需求分析出发,完整实现了控制台版扫雷游戏,核心要点如下:
- 功能设计:通过菜单控制游戏开始与退出,棋盘为 9×9,默认布置 10 个雷,支持排查雷、显示周围雷数、判断胜负。
- 数据结构:使用两个 11×11 的二维数组——
mine数组存放雷的分布(‘0’ 表示无雷、‘1’ 表示有雷),show数组存放玩家排查结果(初始为 ‘*’)。扩大一圈棋盘是为了避免排查边界坐标时发生数组越界。 - 模块化编程:将代码拆分为 game.h(声明与宏定义)、game.c(函数实现)、test.c(游戏主逻辑)三个文件,职责清晰、便于维护。
- 可扩展性:通过宏定义控制棋盘大小与雷的数量,修改一处即可调整游戏难度,无需改动大量代码。
- 随机布雷:借助
rand与srand函数实现雷的随机分布,保证每次游戏体验不同。
通过本项目,你不仅掌握了一个完整小游戏的开发流程,还练习了二维数组、函数封装、头文件管理、随机数等 C 语言核心知识点。后续可以尝试为游戏增加「标记雷」「展开空白区域」「计时器」「难度选择」等功能,让游戏更加完善。