Xiangism

从一个无知角落里开始,蹒跚学步,一个未知到另一个未知,在跌跌撞撞中越走越快,越走越远,最后宇宙也为之开源。对于探索者来说,最后他们的思想总是变得和自己的足迹一样伟大。
  博客园  :: 首页  :: 联系 :: 管理

自动扫雷——确定情况的分析

Posted on 2012-11-18 19:07  Xiangism  阅读(4757)  评论(2编辑  收藏  举报

前面的博文中介绍了如何从“扫雷”游戏中获取数据、并输出数据,现在就来讲解数据的分析:如何在程序中实现雷块的判定。从前言中可知,“扫雷”游戏的分析,可分为四种模型,这里介绍前面三种模型的分析。

数据要比编程逻辑更容易驾驭。在此,先介绍“自动扫雷”所定义的有关数据结构。

Blog类表示游戏场景中的一个小方块。其类图如下所示:

m_isHide表示其是否隐藏;m_aroundMineCount表示m_isHide为false时(即方块显示出来时),方块上显示的数字;m_mineState表示m_isHide为true时,程序判断出这个块是雷、还是非雷(刚开始扫雷时都为UnKown)。

TwoDimesionArray<Block> m_blocks表示由Block组成的两维游戏场景。

由上面的数据即可对付第一、二种模型。在utility.h中分别提供两个函数calMine(),calHide(),分别用来求某个块周围已经判断出雷的数目,以及某个块周围未显示的块。如果周围有雷的个数等于m_aroundMineCount则其它未判断的块就都不是雷;如果周围未显示的个数等于雷数,则这些就都是雷。

下面介绍第三种模型的分析:

先来简单回顾下——(详细先见前言

如果出现以下的情况:

可以得出下面的数学式子:

a+b=1                 (1)  

d+e=1                 (2)

a+b+c+d+e=2         (3)

在程序中,为了表示这个的式子,本人定义了ProbableMine类,其类图如下:

points表示所以可能出现雷块的坐标,mineCount表示在这个块中雷的总数。上面三个式子得用三个ProbableMine对象表示,其mineCount分别为1,1,2。points分别为a,b;d,e ;a,b,c,d,e的坐标。

SurAnalyse负责第三种模型算法的实现。类图如下:

其中probables为所有的可能情况,m_notMines,m_Mines用来记录分析过程中的结果。

在分析时,两两比较每个ProbableMine对象,如果其中一个points是另一个的子集,则可由它们差集生成另一个ProbableMine对象。如果这个新ProbableMine对象中的mineCount==0,则可以判断其points都不是雷;而如果mineCount==points.size(),则可以判断其points都是雷;如果两种情况都不满足则加入到probables中,参加下一轮的运算。直到数据都不再变化为止。

至此,前三种模型的分析都已结束,可以看出算法并不复杂。最有挑战的还是在第四种模型的分析,本系列的下一篇将会仔细分析(不过最近在研究第四种情况时,发现了这么一个数学题,有兴趣的朋友可以思考下,一个排列组合题)。

现在将C++项目源码公开出来: https://files.cnblogs.com/xiangism/mineTerminator_src.rar ,现在只实现前三种模型,第四种模型的代码还不完善。 (再次强调,为了专注,本人只研究XP系统下的自动扫雷。如果是WIN7系统,则需要拷贝XP下扫雷游戏,下面提供其下载地址)

32位XP系统下的扫雷游戏:winmine_32cn

自动扫雷的EXE下载地址为:https://files.cnblogs.com/xiangism/mineTerminator.rar

 

下面是本人用自动扫雷完成的游戏界面