7

新手30天,C语言实现扫雷(上)

 2 years ago
source link: https://blog.csdn.net/weixin_60742599/article/details/120641448
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

新手30天,C语言实现扫雷(上)

蒋同学783 2021-10-07 21:59:15 2
专栏收录该内容
1 篇文章 0 订阅

因为大学生活的到来,对程序设计这门课程非常感兴趣,便开始超过学校进度开始自学,自学一个月过去了,不断摸索,写了无数bug,分享一个bug游戏,希望大家给给意见,让我也尝一下进步的感觉

软件用的是VS2019

首先建立新的(空项目)工程:

 随后开始思考(构建框架)

扫雷是啥?

 扫雷的功能?

一、有边边框框,方便用户操作

二、呈方形的排布(二维数组)

三、具有游戏开始界面、具有游戏模块

游戏模块包括:

(一)画出雷区

(二)随机生成雷区

        随机在雷区产生指定数目的地雷

(三)玩家扫雷

(四)系统判定

        ①是否合法的操作(有没有在棋盘内操作)

        ②是否已经扫过了

        ③是否炸了

        ④是否赢了

(五)更新游戏最新画面(更新雷区)

我们现在想象,其中的(三)(四)(五)具有重复性,(一)(二)属于游戏生成阶段的产物

现在,我们思路已经清晰了,我们开始写这一代码:

第一步:创立三个文档

以上述的步骤,创建出以下三个文件,注意其中一个是game.h是头文件,源文件处的后缀可以是cpp,也可以是c,由于我正在学c语言,此处使用.c作为后缀。

(一)预处理第一个文档: 在test.c的源文件中,键入代码:

 因为是任务驱动编程,因此test()函数,作为整个程序的起点

#define _CRT_SECURE_NO_WARNINGS

此语句为C语言环境中使用scanf函数时,屏蔽系统得不安全警告

(二)预处理第二个文档:在game.h文件中键入

第一行为创建的时候自带的,先不管

为什么要在头文件中输入三个库函数呢?

这里我们可以想象:

你每天起床都会喝果汁

果汁有:草莓汁,蓝莓汁,香蕉汁等一堆汁

假如你每天起床,都要一杯杯的打果汁,又耗时又费力

就像你在每个不同的文档里面写代码,每个文档都要引用一大堆头文件。

那么,我们可以想到一个好方法:

把一堆水果,都放在同一个果汁机里面,打成一杯,然后一口喝下!

这里我们把可能用到的头文件,都放在了game.h头文件中

接着,我们在源文件(game.c和test.c)中,引用

(三)第三个文件,我们弄好头文件后,就先不管

好,现在开始,我们开始实现最根本的流程

因为任务是,在test()函数中,实现最基本的运行逻辑

我们打开test.c文件编写如下代码

 如图:代码在图下

我们开始解读一下这个代码行

首先,我们想要读取一个用户的输入,所以我们设置一个变量,然后请求用户输入

再者,我们希望,无论如何,请求输入的次数永远是大于零次的(谁也不想还没开始,就被关掉了游戏),因此我们使用do-while函数进行最基础的框架搭建

最后,game()函数作为游戏的最终入口!

menu()函数,是实现用户交互的函数,我们首先要有一个菜单

好,我们跑起来现在最基本流程了

五、开始(或退出)



以下是game函数的写法

 首先,我们先不管第一行的srand()后面再细讲

我们可以看见有两个数组

 这两个数组,分别存储:

(一)mine存储的是随机产生的雷

(二)show是存储用户视角的数据

不懂?没关系

mine数组,对应的是雷的排布:(相当于地下)

而玩家所看见的是show数组(相当于地上)

而创建数组的时候,为了方便后期维护,我们不写具体的数组框定数组的范围

在这里我们使用定义常量

诶?为什么定义的时候是ROW和COL

而在数组的那边是ROWS和COLS?

因为假设雷区是3*3

如果程序要判断坐标(2,2)附近雷的个数,自然去搜索

如果程序要判断坐标(3,2)附近雷的个数,要去搜索

显然,棋盘是不够大的

如果我们人为,在棋盘的周围,多加一个圈

计算机搜索的时候,便不需要刻意去搞特殊!

这样,在棋盘的周围多加了一圈,蓝色就能肆无忌惮的扫描,不用在意壁垒。

因此,在宏定义下,我们在上下左右各加一行,则是

因此ROWS/COLS是扩大后的棋盘横纵


 观察game函数

我们第一件事,就是建立一个地下,和地面

第二步:是将地下的区域,全部都置零(先把杂质全部挖掉,为后面埋雷做准备)

参数的意义是:

mine/show:传入数组

ROWS/COLS:是代表行数和列数

而'0'和'*'则是代表将mine数组或者show数组填满所用的元素

效果(故意打印出来后)大概为:

 (注:上边棋盘的1,是随机产生的地雷,产生地雷的方法后面再说)


在game.c内实现各个函数的内容:

这是将两个数组mine和show初始化的函数


光有内容,可不行,现在还没有能打印出我们游戏界面的功能

而,game()中的Displayboard()

便是展现游戏界面的功能

这个函数实现了:

(一)在棋盘的周围布上数字,让用户更好的定位坐标

(二)在格子之间加上分割线,使格子更好看

(三)根据show和mine的棋盘内容,相应打印出数组内的情况


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK