扫雷解决算法

时间:2009-11-15 17:14:07

标签: algorithm minesweeper

我很确定大多数人都知道扫雷游戏。我想编码(在C#中)我自己的扫雷游戏,并且正在寻找一些关于该游戏的优秀算法的输入。我一直在浏览网页很长一段时间,但找不到一个好的解决方案。任何人都可以帮我吗?

8 个答案:

答案 0 :(得分:50)

生成网格很简单。执行玩家移动时需要几个简单的算法,以确定要打开的方块以及它们是否已丢失或赢了。

生成网格

最简单的算法是随机放置所有地雷。 (确保你没有重叠!)

问题: 玩家的第一次点击可能是我的。

改进:延迟生成网格直到用户点击第一个方格,并且不在该方格中放置任何地雷。

问题: 玩家的第一次点击可能会显示非零数字,他们将被迫随意点击,直到某些内容打开。

改进:不要在第一次点击周围的(最多)八个方格中生成任何地雷。

问题: 玩家可能会被迫在某个时候猜测,这使得这成为逻辑谜题的一个可悲的借口。

改进:Run the solver与生成器并排,确保puzzle具有唯一解决方案。这需要一些聪明,并且在大多数变体中都没有。

解决歧义的另一种不太常见的方法是检测玩家何时知道他们在同等可能的可能性之间进行选择并“将波形折叠”到他们决定的位置。我从来没有见过这个,但它会很有趣。

玩游戏

除了标记标记外,玩家还可以进行两种移动以尝试揭开正方形:

  • 单猜:玩家点击状态未知且没有旗帜的广场。显示广场,看看玩家是否死亡,并在其中放入一个数字。如果正方形包含0,则对所有周围的正方形递归重复。这应该在一个专用函数中,将它与GUI的事件处理程序分开,以使递归变得容易,并且因为它在多个集合中被重用。

  • Multiguess:玩家点击一个未被发现且已知安全的广场。如果周围的旗帜数量等于此方格中的数字,我们将使用与上述相同的程序打开未标记的方块。

赢得比赛

如果被掩盖的方格数与地雷数相同,那么即使玩家没有在每个方格上放置旗帜,玩家也会获胜。

当玩家输掉时,习惯上会标记他们所做的任何不正确的猜测,剩下的地雷以及他们踩到的地雷。

答案 1 :(得分:5)

如果您尝试编写解算器,我只想添加以下内容 - Minesweeper is NP complete (Archive Link)。这意味着,直到有人证明P = NP,你可以做更好的事情,然后在某些情况下进行强力搜索(但也许游戏对于小场来说不是NP完成)。

答案 2 :(得分:3)

这是我的扫雷解算器:

  • 对于每个数字方块:
    • 如果未开封的数量==平方数:所有这些都是地雷
    • 如果方数 - 标记的数量== 0:所有未开封的都不是地雷
  • 使用子规则

这是一个实际的实现,请注意它使用了子集规则,这很难解释 https://github.com/SHiNKiROU/Minesweeper/blob/master/src/org/shinkirou/minesweeper/MinesweeperSolver.java#L27

当然,我的算法有时会失败。我打算实施Prolog风格的回溯解算器

答案 3 :(得分:2)

评论是你不需要算法来构建游戏。我相信你的意思是一种解决意义上的算法,每个人也可能都是这样理解的。

然而,问题的任何解决方案都可以被视为算法。

与大多数数学问题一样,您可以将整个算法分解为更小,更简单的算法,直到您达到足以解决的小问题。这将为您提供第一个正确的解决方案。稍后您可以在整个算法的上下文中优化较小的算法。

游戏板可以被认为是二维阵列。您将拥有与每个操作相关联的算法。第一个操作可能是随机生成的一组矿井位置,其中x,y坐标具有地雷数量和板块尺寸的参数。您将获得另一个与显示正方形相关联的算法,该算法接收板和位置并确定与其相邻的多少个地雷。最后的算法将采用棋盘并检查是否有任何没有地雷的方格显示出来。

现在你可以采用这些算法中的每一种,并尝试优化它们中的每一种以获得更好的性能,并说“使用x,y坐标给出二维数组时,使用与当前正方形相邻的地雷计算正方形的最佳方法是什么

答案 4 :(得分:2)

我绝对不是一个扫雷专家,但这是我尝试解决它时使用的算法:

遍历所有显示区域边界的方块。对于这些方块中的每一个,计算您旁边显示的地雷数量。减去写在方格中的数字(它周围的真实地雷数)。那是在这个广场周围留下的未发现的地雷数量。除以当前正方形周围未显示的正方形数量。这是包含矿井的每个相邻广场的概率。如果任何方格的概率为1,则将其标记为地雷。如果任何方格的概率为0,则将其标记为安全。然后你更新相关的数字。

如果没有方格的概率为0或1,你会怎么做?最优算法将考虑来自多个正方形的约束。但正如我在开头写的那样,我不是扫雷专家,所以我从其他方格中随机选择概率最接近0或1的方格。

答案 5 :(得分:2)

请检查:http://quantum-p.livejournal.com/19616.html

棋盘上的任何位置都无法通过猴子推理直观地解决,这个矩阵可以解决一些个体(或整个位置)方格,这可以带来更好的解决率。简单的随机猜测没有产生好的结果。 我通过添加线性方程组求解器将这种方法实现到我在C ++中的求解算法中。我正在通过算法运行数万场游戏并进行统计来研究扫雷的难度。

我的算法解决了高达85%的(9,9,10)易级扫雷舰。我尚未对其他困难程度进行完整的测试,但较小的测试表明中等水平(16,16,40)的解决率为55-60%,硬度(30,16,99)低至5 -10%。我将添加一些可以使其最佳的新内容。

答案 6 :(得分:2)

正如亨利所提到的,解决扫雷的正确方法是用数学,特别是确定性部分的线性代数矩阵数学。我在这里有一个完整的帖子:

  • 解释了该方法的工作原理
  • 具有可以在任何平台上编译和运行的工作代码
  • 包含制作游戏的代码和解算器

您可以在此处看到所有内容:https://massaioli.wordpress.com/2013/01/12/solving-minesweeper-with-matricies/

我建议您仔细阅读,然后仔细考虑一下。 Minsweeper的概率部分也可以使用统计数据来解决,但我还没有一个好的计划。但是,其他人也对此进行了研究。

答案 7 :(得分:1)

你见过this C# implementation of the game吗?源代码是可下载的,并解释了对象模型。