翻看了下以前大学学习的一些小项目,突然发现有个项目比较有意思,觉得有必要把它分享出来。当然现在看来,里面有很多的不足之处,但因博主现在已经工作,没有时间再去优化。这个项目就是利用C#编写一个Windows系统下的扫雷小游戏。

首先讲下扫雷小游戏的玩法:

(1)扫雷就是要把所有非地雷的格子揭开即胜利;踩到地雷格子就算失败。

(2)当点开的格子不是地雷区域的时候,该格子会显示一个数字,该数字表示的含义就是该格子周边有多少个地雷。

(3)同时点开的如果非地雷的格子,周边连贯的非地雷区域都会自动被扫描打开,直到遇到旁边有雷区的时候停止。

(4)当你判断出格子是地雷的时候,你可以使用鼠标右键将该块方格标记为雷区。当不确定的时候,你可标记个问号以待确定。

下面来说下我大学时候实现这个扫雷小游戏的思路:

(1)因为雷区是一个个格子联合组成的,那我们可以使用winform程序自带的系统按钮控件Button来实现雷区方格。

(2)代表雷区方格的Button按钮需要实现下面几个事件:鼠标左键点击扫雷事件,鼠标右键点击标记雷区事件,鼠标右键点击标记问号区域事件。

(3)为了更好的实现游戏的可玩性,增加一个自由设置地雷数量的小功能,可自行设置雷区包含的地雷数量,设置完成后,自动刷新界面,重新部署地雷。

(4)我们将雷区的方格存储在一个全局的二维数组中,Form窗体在初始化的时候,自动生成面板区域的Button按钮列表。

(5)为了实现每次玩游戏的时候,地雷分布不一致,我们在Button列表生成后。随机抽取出某些Button按钮作为地雷分布点,并记录该Button的雷区属性为含有地雷。

(6)算法中的关键:递归算法计算雷区。当点击某个方格的时候,如果该方格是雷区,则直接Game Over,如果不是的话,则我们需要一个算法去计算旁边区域的地雷数量,以及旁边区域没有地雷的区域,当没有地雷的区域连成一片的时候,我们需要使用递归算法,去查找二维数组,找到对应的连片非雷区,将之打开。

(7)如何设置方格的状态:当鼠标左键点击的方块区域非雷区的时候,我们将Button按钮的属性设置为Disabled即可呈现打开的状态。当鼠标左键打开的方格是雷区时候,此时我们可以将所有地雷区域块的Button的背景图设置为地雷图片,并播放相应的爆炸音效,弹出游戏终止界面即可。当鼠标右键标记雷区或者待确定区域的时候,只需要更改Button的背景图即可。当然上述所有点击操作,都得判断Button方格区域当前的状态值:初始化状态、已标记为待确定状态、已标记为雷区。

游戏的最终效果图如下:

我们下面来剖析下几个关键点,因为代码量比较多,我就不全部详细剖析了。

首先我们定义一个LeiButton类,这个类继承于系统控件Button,增加x,y,youlei三个字段,x表示二维数组的第一个索引,y表示二维数组的第二个索引值,youlei用于标记Button方块区域按钮的状态(0表示无雷,1表示有雷)。同时我们使用Button按钮类自带的一个Tag属性标记该方块区域是否被翻开。具体定义如下:

然后我们在窗体对象Form类中定义一些常用的变量之类,如下图,都有相应注释

下面我们来看下生成Button的二维数组,即生成雷区的Button列表。我们需要在Form中添加GroupBox组件,然后将动态生成的Button列表添加到这个groupbox组件中。生成Button的二维数组方法体如下:

生成完Button列表后,我们就开始部署地雷了,地雷随机部署到Button列表中,部署地雷的方法如下:

到了这一步,我们就应该将雷区的界面渲染出来了,这时候我们可以将上面两个方法放入窗体的Form_Load事件中即可渲染出游戏界面。如下所示

我们继续,下面写扫雷的算法,当鼠标左键点开某个方格的时候,如果该方格不是雷区,那我们需要计算该方格周边的地雷数量,计算方法如下:

下面是个递归计算的核心算法,非常关键。当我们点开的方格非雷区的时候,周边连片的非雷区的方格块会被打开。这一块的核心算法参考下列代码,row表示行,col表示列

下面我们来添加鼠标的点击事件,我这边采用的是bt_MouseUp事件来处理。点击后,我们首先判断游戏是否结束,如果没结束,则进行下列操作,获取到被点击的按钮的x,y值以及点击事件按下的键值(判断按下的是鼠标左键还是右键)。x,y值获取到了,我们就可以到Button二维数组中找到对应元素。

假如点击的是鼠标左键,则我们进行扫雷操作,具体的代码如下:

如果按下的是鼠标右键,则是标记方块是雷区或者待确定区域,具体代码如下:

最后再给出一个判断是否扫雷完毕的方法。

扫雷游戏的设计大概到此结束,中间还有很多可以优化的地方,比如将扫雷的逻辑代码抽离Form类独立出来等,这些都靠读者自行去优化了。

附上博主源码下载的百度云链接,需要代码学习的可自行下载研究:https://pan.baidu.com/s/1T4zVndyypzY9i9HsLiVtGg 提取码: b2im 

最后,附上博主的IT技术学习群,欢迎各位同行入群指导交流。技术群:872894940

更多文章可以关注博主个人站点:IT技术小屋

C#编写扫雷游戏的更多相关文章

  1. C# -- HttpWebRequest 和 HttpWebResponse 的使用 C#编写扫雷游戏 使用IIS调试ASP.NET网站程序 WCF入门教程 ASP.Net Core开发(踩坑)指南 ASP.Net Core Razor+AdminLTE 小试牛刀 webservice创建、部署和调用 .net接收post请求并把数据转为字典格式

    C# -- HttpWebRequest 和 HttpWebResponse 的使用 C# -- HttpWebRequest 和 HttpWebResponse 的使用 结合使用HttpWebReq ...

  2. 我用Bash编写了一个扫雷游戏

    我在编程教学方面不是专家,但当我想更好掌握某一样东西时,会试着找出让自己乐在其中的方法.比方说,当我想在 shell 编程方面更进一步时,我决定用 Bash 编写一个扫雷游戏来加以练习. 我在编程教学 ...

  3. Java练习(模拟扫雷游戏)

    要为扫雷游戏布置地雷,扫雷游戏的扫雷面板可以用二维int数组表示.如某位置为地雷,则该位置用数字-1表示, 如该位置不是地雷,则暂时用数字0表示. 编写程序完成在该二维数组中随机布雷的操作,程序读入3 ...

  4. JAVA_扫雷游戏(布置地雷)

    1.要为扫雷游戏布置地雷,扫雷游戏的扫雷面板可以用二维int数组表示.如某位置为地雷,则该位置用数字-1表示, 如该位置不是地雷,则暂时用数字0表示. 编写程序完成在该二维数组中随机布雷的操作,程序读 ...

  5. 洛谷 P2670 扫雷游戏==Codevs 5129 扫雷游戏

    题目描述 扫雷游戏是一款十分经典的单机小游戏.在n行m列的雷区中有一些格子含有地雷(称之为地雷格),其他格子不含地雷(称之为非地雷格).玩家翻开一个非地雷格时,该格将会出现一个数字——提示周围格子中有 ...

  6. 原生javascript扫雷游戏

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  7. [LeetCode] Minesweeper 扫雷游戏

    Let's play the minesweeper game (Wikipedia, online game)! You are given a 2D char matrix representin ...

  8. C语言二维数组实现扫雷游戏

    #include<stdio.h> //使用二维数组实现 扫雷 int main() { char ui[8][8]={ '+','+','+','+','+','+','+','+', ...

  9. 【Android】自己动手做个扫雷游戏

    1. 游戏规则 扫雷是玩法极其简单的小游戏,点击玩家认为不存在雷的区域,标记出全部地雷所在的区域,即可获得胜利.当点击不包含雷的块的时候,可能它底下存在一个数,也可能是一个空白块.当点击中有数字的块时 ...

随机推荐

  1. Spring MVC 的 XML 配置方式

    索引: 开源Spring解决方案--lm.solution 参看代码 GitHub: solution/pom.xml solution/webapi/pom.xml solution/mapper/ ...

  2. 一个基于原生JavaScript开发的、轻量的验证码生成插件

    Vcode.js 一个基于原生JavaScript开发的.轻量的验证码生成插件 V: 1.0.0 DEMO:https://jofunliang.github.io/Vcode.js/example. ...

  3. namespace------------https://www.cnblogs.com/linhaifeng/p/6657119.html

    PHP支持两种抽象的访问当前命名空间内部元素的方法,__NAMESPACE__ 魔术常量和namespace关键字. 常量__NAMESPACE__的值是包含当前命名空间名称的字符串.在全局的,不包括 ...

  4. JAVA Set 交集,差集,并集

    /** * Created by yuhui on 2017/7/11 0011. */ import java.util.HashSet; import java.util.Set; public ...

  5. Spring加载xml配置文件的方式 ApplicationContext

    大家都知道Java读普通文件是通过Basic I/O 中的InputStream.OutStream.Reader.Writer 等实现的.在spring 框架中,它是怎样识别xml这个配置文件的呢? ...

  6. JFrame图形界面 ----绝对布局和按钮

    开始 绝对布局应该是最简单的一种布局方式了,只需要确定好大小和位置就可以固定不变 代码 ` package window; import java.awt.Color; import java.awt ...

  7. 应用服务器性能优化 之 消息队列(MQ:Message Queue)

    一,消息队列基本概念 借用百科的一句话:消息队列就是在消息的传输过程中,保存消息的容器. 从图-1和图-2对比,可以很清晰的明白,消息队列服务器,是位于应用服务器和数据库服务器之间的一个服务器.消息队 ...

  8. 一起来读Netty In Action(一)

    Netty是一款异步事件驱动的网络应用程序框架,支持快速的开发可维护的高性能的面向协议的服务器和客户端.在网络编程中,阻塞.非阻塞.同步.异步经常被提到.同步(synchronous) IO和异步(a ...

  9. 深入理解SpringCloud之分布式配置

    Spring Cloud Config Server能够统一管理配置,我们绝大多数情况都是基于git或者svn作为其配置仓库,其实SpringCloud还可以把数据库作为配置仓库,今天我们就来了解一下 ...

  10. 如何把word中的图片怎么导出来呢?

    在办公使用word的过程中你可能经常会遇到这个问题:插入到word中的图片找不到导出来的方法,是不是很郁闷呢,别急,今天咱们研究一下把word中的图片导出来的方法(把"我的"变成你 ...