使用 Clingo 优化关卡生成器的难度

Optimizing difficulty with a level generator using Clingo

我正在使用 Clingo 制作拼图关卡生成器(推箱子),但在尝试创建具有特定移动限制的关卡时遇到了困难。这个想法是使用移动限制来控制一个级别的难度。这就是我创建生成器的方式:

  1. 指定有效外观水平的规则(所有可行走的瓷砖都连接,正确的可推动桶和目标平台等)
  2. 指定移动和推动桶的规则。
  3. 指定获胜条件。

我的第一个迭代是通过要求在 0..N 步中满足获胜条件来简单地要求一个级别可以在 N 步中解决。这导致了有效的关卡,但无法控制难度。

我的第二次迭代是尽量减少满足获胜条件所需的移动。这导致了一步完成的水平。

我的第三次迭代是声明一个级别不能在少于 M 步的时间内完成。这导致逻辑做不必要的动作只是为了达到最小值,仍然没有对难度进行有意义的控制。

我的第四次迭代是为了防止相同的游戏状态再次出现,以避免不必要的“填充”动作,但这仍然导致解决关卡的逻辑非常不理想,只是为了达到最低要求。

现在我真的不知道该怎么办了。我想我想做的是最大化所需的最小移动量(达到极限),但我不确定这是否有意义。我希望能够说明完成此级别的最小移动量应该是 M.

应该如何解决这个问题?

所以换句话说:您正在寻找一个可以在 N 步中解决的谜题,但在 N-1 步中解决它会 return 无法满足。这两个部分陈述了互补的问题(“至少找到一个”与“找到 none/all”)并且很难放在一个程序中,并且组合会增加问题的复杂性(参见 polynomial hierarchy)。这里有三个建议通过枚举来解决它:

  1. 枚举与区别:对于NN-1枚举所有答案。当出现 N 而不是 N-1 时,一个谜题可以精确地 N 步解决。这需要某种 post 处理,例如脚本或整洁的文本编辑。

  2. 枚举和不可满足:在脚本中为当前N一一枚举所有答案集。对于当前的谜题,尝试解决 N-1 个问题:如果它有 return 个 0 个答案,那么您就有了自己的谜题。这需要某种形式的 data-handling,我建议使用 python.

  3. 枚举避免双打:在脚本中,为N-1生成所有答案集。将每个答案集转换为约束并将其添加到程序中。示例:图块 m(1..4,l). m(1..4,r) 大致定义了您的拼图,您当前的答案集是 m(1,l). m(2,l). m(3,r).,添加以下约束以避免再次生成此拼图。然后求解 N.

    的更新程序

    :- m(1,l), m(2,l), m(3,r), not m(1,r), not m(2,r), not m(3,l), not m(4,l), not m(4,r).

如您所见,这三种方法都可以解决您的问题,但需要 clingo 之外的额外努力。