翻看了下以前大学学习的一些小项目,突然发现有个项目比较有意思,觉得有必要把它分享出来。当然现在看来,里面有很多的不足之处,但因博主现在已经工作,没有时间再去优化。这个项目就是利用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. Selenium2Lib库之操作浏览器相关的关键字实战

    1.1  操作浏览器相关的关键字 Selenium2Lib提供了与浏览器交互的关键词 1.1.1 Open Browser关键字 按F5 查看Open Browser关键字的说明,如下图: Open ...

  2. [CVPR2017] Weakly Supervised Cascaded Convolutional Networks论文笔记

    p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 14.0px "Helvetica Neue"; color: #042eee } p. ...

  3. pycharm linux版快捷方式创建

    ****************************pycharm_linux安装and快捷方式创建******************1.下载好安装包之后解压:    tar -xfz 压缩包名 ...

  4. List数组和集合相互转换

    1.List的toArray()方法用于将集合转换成数组,但实际上改方法是在Collection中定义的,所以所有的集合都具备这个功能, 其有两个方法:Object[] toArray()  和   ...

  5. 网络Socket编程及实例

    1 TCP和UDP介绍 在介绍TCP和UDP之前,有必要先介绍下网络体系结构的各个层次. 1.1  网络体系结构 协议:控制网络中信息的发送和接收.定义了通信实体之间交换报文的格式和次序,以及在报文传 ...

  6. DoxygenToolKit.vim 插件配置

    如何才能既享受 Doxygen 的强大功能,同时又避免大量的重复性的注释内容? 解决思路: 让编辑器来替我们写那些格式和内容固定的部分,我们只负责写真正的有效内容. 所以,答案就是:Vim + Dox ...

  7. map和set的原理

    1)map:经过排序了的二元组的集合,map中的每个元素都是由两个值组成,其中的key(键值,一个map中的键值必须是唯一的) 是在排序或搜索时使用,它的值可以在容器中重新获取:而另一个值是该元素关联 ...

  8. nake_api_protect 请求保护器——防止请求被恶意刷

    github : https://github.com/xjnotxj/wechat_interaction_auth -- nake_api_protect 接口请求保护器,根据 频率 + 次数 的 ...

  9. Python使用Socket写一个简单聊天程序

    b2b模式的聊天工具 服务端: # 链接 while True: print('等待连接...') sock,adr = server_socket.accept() while True: try: ...

  10. 解析PHP程序员需要掌握的必备技能

    转自:http://www.php100.com/html/php/lei/2013/0904/4199.html 作为PHP的爱好者,如果你想加入PHP程序的世界,一定要做好充分的准备.建议大家阅读 ...