扫雷棋盘的“开局”

4

我正在设计一个扫雷游戏,但是我找不到如何让“开局”时板块打开的算法。如果你玩过扫雷游戏,第一次点击或者几次点击会显示很多方块。这背后的算法是什么呢?


这只是循环调用,当用户点击方块 (x, y) 时,便会调用 show(x, y) 函数。在函数内部,它会展示该方块,同时如果该方块为空,则调用 show(x-1, y)show(x+1, y)show(x, y-1)show(x, y+1) 等函数(或许还有对角线函数,我现在记不清了)。 - j_random_hacker
小心使用无限循环。 - ChronoTrigger
2个回答

4
您可以使用泛洪算法(Flood-fill)来处理没有任何相邻炸弹的单元格(显示“0”或无值),以及它们周围的单元格。
以下是一些伪代码:
floodFill(cell)
  if not cell.isOpen
    cell.open()
    if not cell.hasNeighbouringBombs
      for each neighbour n of cell
        floodFill(n)

请注意,这与“正常”的泛洪算法不同:

floodFill(cell)
  if not cell.hasNeighbouringBombs and not cell.isOpen
    cell.open()
    for each neighbour n of cell
      floodFill(n)

这种差异的原因可以通过以下示例看出:
1 1 2
2 0 3
1 2 3

正常的泛洪填充算法只能填充0,但是我们希望填充以上所有单元格,因此我们应该在打开当前单元格后再检查hasNeighbouringBombs
请注意,如果您从一个具有非零值的单元格开始点击,通常情况下不会打开其他单元格(至少在大多数版本的游戏中),这将通过上述算法得到解决。

如果你开始点击地雷,地雷会被移动到另一个位置,这样你就不会在第一次点击时死亡。 - Teepeemm
根据游戏的不同,有些游戏允许你点击一个地雷来开始游戏。但是基于第一次点击生成游戏似乎是更好的想法(但显然更加复杂)。 - Bernhard Barker
@Dukeling,我不太明白!open是什么意思。你能否详细说明一下在你的伪代码中open的不同用法? - LazySloth13
@Lewis,我希望cell.opencell.isOpen更有意义。已经修改了。 - Bernhard Barker
如果有太多关闭的相邻单元需要访问,这种实现可能会导致 StackOverflowException。 - Bruno Negrão Zica
排队可以使用。 - Sairam

1

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接