使用人工智能解决谜题游戏

5
我做了一个益智游戏,玩家需要将方块滑动到目标节点,规则相对简单:
  1. 每次只能移动一个滑块
  2. 目标是将滑块移至目标节点,不需要所有滑块都移动到目标节点
  3. 如果滑块滑在冰上,则会一直向那个方向移动,直到被阻止或移动到其他位置
  4. 如果滑块碰到实体物体(如混凝土、其他方块),则会停下并可以再次移动(显然不能移动到混凝土中)
  5. 如果滑块滑到木材上,则会停在木材上并可继续移动
  6. 如果滑块滑到目标节点上,则无法再次移动
  7. 某些方块可以移动滑块,例如箭头方块可以推动滑块朝特定方向移动
  8. 有开关方块可以打开“门”,可移动到其上以打开和关闭“门”
  9. 按钮方块的操作类似于开关,但必须在其上放置方块才能激活“门”
  10. 当“门”关闭时,它们表现得像实体物体一样。当“门”打开时,它们就像冰一样

以上是规则,以下是游戏截图:

The beginning state of a puzzle

玩家需要移动方块使其相互碰撞以解决谜题。

The puzzle is three moves away from solving

游戏接近解决状态。请注意,方块碰到另一个方块后停了下来。

这里还有一个包含推动方块机制的谜题:

The blocks may be moved around here

如果我们将右上角的方块向下移动,则会发生以下情况:

The block has been propelled leftward, to the wood block

如您所见,当方块碰到箭头方块时,它被向左移动并停在木块上面。

我想编写一种AI解决这些谜题——我认为这将是某种深度优先搜索,但我不知道从哪里开始。任何关于实现这个想法的指导都是很好的!


无论您选择哪种方法,您能否在UI之外清晰地表示游戏状态和移动?这非常重要,以便您可以轻松模拟/可能回溯。 - J Trana
是的,我可以很简单地表示游戏状态和移动,而不需要用户界面 - 这需要一些构建,但并不难。本质上,它是一堆可能移动的节点,受环境影响。 - Sam P
很好。你还有一种好的方法来枚举所有可能的有效移动吗? - J Trana
对于每个玩家节点,找到移动的方向?按照我的设想,这将输出每一步玩家节点的结果位置。 - Sam P
那么,随着我们的进展,我们将制作一个游戏状态堆栈 - 如果我们遇到解决方案(或非解决方案),记录它,然后弹出,继续其他分支等,直到我们完成?我并不特别关心时间限制 - 我只想能够验证谜题是否可解以及解决该谜题所需的最短移动次数。 - Sam P
显示剩余4条评论
1个回答

8
您的问题是一个典型的状态空间搜索问题。根据您特定实例的特征,可以使用不同的算法。
无论您的实例如何,都需要定义四个组件:
1. 初始状态,在您的问题中为初始配置 2. 一个函数,返回空间中任何状态可达的所有可能状态,在您的问题中,可到达的状态是通过移动滑块可获得的所有可能拼图配置。当其可达状态被访问时,状态被称为已扩展。 3. 目标测试,确定给定状态是否为目标状态,在您的问题中,您将检查是否填满了所有目标块, 4. 成本函数,给出从一个状态到另一个状态的成本,使您的算法能够选择要执行的最佳操作。在您的情况下,我认为您可以为每个操作使用一个恒定值1,并搜索执行最少操作以达到其中一个目标状态。
由于您的问题可以用这四个组件来定义,因此可以使用以下算法之一解决您的问题:
  1. 广度优先搜索(BFS):我们首先测试初始状态是否为目标状态(对于非平凡问题显然不是),然后扩展初始状态,测试每个可达状态,如果不是,则扩展这些状态,以此类推进行级别... 可以使用队列实现。
  2. 深度优先搜索(DFS):从初始状态开始,测试目标,然后展开邻居状态,测试目标,然后展开该状态,以此类推,一直到状态空间的最深层。 可以使用栈实现。

要评估哪种算法最合适,我们可以考虑以下因素:

  1. 完整性:算法是否保证在存在解时找到解决方案?
  2. 最优性:算法能否找到最优解?
  3. 时间复杂度:需要多长时间?
  4. 空间复杂度:需要多少内存?
如果我们考虑BFS策略,我们可以看出它是完整的,因为它通过层次系统地探索状态空间,只有在成本函数不会随着状态深度增加而降低时它才是最优的(这是我们的情况,因为所有操作都具有恒定成本)。现在来了一个坏消息:假设每个节点的扩展最多可以给出个状态,并且第一个解在深度处,那么您将需要存储和扩展最多个状态。
在DFS的情况下,我们必须考虑到它可能会在某个路径上搜索很长时间(潜在地无限),而另一种选择可能会导致解决方案附近的位置。因此,当状态空间是无限的时候,该算法既不完整也不优化。如果我们将视为状态空间的最大深度,则最多会得到的空间复杂度,而时间复杂度仍然是指数级的:
因此,我们可以采用迭代加深深度优先搜索的方法来混合这两种策略。在这种搜索中,我们将从0开始限制最大深度,并迭代地运行DFS到最大深度级别。此方法具有两种搜索策略的优点:空间复杂度,其中是第一个最佳解的深度,时间(我们无法做得更好),它是完整的(它将通过层次迭代地探索所有状态来找到解决方案),并且对于相同的原因,它是最优的(假设成本函数随路径长度的增加而不减)BFS是最优的。

参考:人工智能:一种现代方法

注意:显然还存在其他未经过了解的策略,但正如《IDDFS》一书所述,在搜索空间上没有额外信息的未知搜索问题中,IDDFS是一个不错的选择。有关其他类型的搜索策略(例如,有一个目标状态与当前状态之间的距离概念的启发式搜索),请参考该书。

1
非常感谢您提供这个出色的答案!❤ - Jens A. Koch

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