【问题标题】:Chess programming: minimax, detecting repeats, transposition tables国际象棋编程:极小极大、检测重复、转置表
【发布时间】:2021-11-21 03:34:07
【问题描述】:

我正在建立一个国际象棋评估数据库(本质上是从国际象棋位置到评估的地图),我想用它来为给定的位置提出一个好的举动。这个想法是做一种“静态”极小极大值,即:对于每个位置,如果子节点(下一层之后的位置)的评估不可用,则使用存储的评估,否则使用 max(白色移动)/min(黑色移动)子节点的评估(以相同的方式确定)。

问题当然是图中的循环,即重复位置。我无法理解如何处理这个问题而不会使它的效率无限降低。

到目前为止我探索的想法是:

  • 假设在游戏中以少于当前评估的步数即可到达的任何位置的评估为 0。这是一个无效的假设,因为 - 例如 - 如果白方下 A,黑方可能不希望跟随 x,但如果白方下 B,则 y -> A -> x -> -B -> - y 可能是最好的线,导致与 A -> x 相同的位置,没有任何重复(-m 表示反向移动到 m 这里,小写:黑色移动,大写:白色移动)。
  • 为到达位置的每种可能方式设置一个实例可解决循环问题,但这会在某些位置产生大量实例,因此不实用
  • 从一个位置回到那个位置有一个循环这一事实并不意味着它是重复平局,因为播放重复线可能不是最佳选择
  • 我已经尝试了几次循环迭代,看看整体评估是否会变得稳定。它没有,因为在某些情况下,假设重复是最好的线意味着它不再是 - 然后它回到平局作为后线等。

我知道国际象棋引擎使用转置表来检测之前已经到达的位置,但我相信这并不能解决我的问题,我实际上想知道它们是否存在问题:一个位置可能通过两个搜索树中的路径 - 其中一条路径之前经过相同的位置,因此它是重复的,而另一条路径没有这样做。那么路径 1 的评估必须是 0,但路径 2 的评估不一定​​是(路径 1 可能不是最好的线),所以换位表持有的评估可能是错误的,对吧?

我确信这个问题必须有一个“标准/最佳实践”的解决方案,但谷歌让我失望了。非常欢迎任何指针/想法!

【问题讨论】:

  • 一个完整的棋盘配置可以用 32 个字节编码。是不是太过分了?
  • @YvesDaoust 编码的大小不是问题 - 如果需要,我可以接受 TB。如果您指的是我列出的“每种可能的方式都有一个实例” - 这个问题是算法需要枚举所有可能的方式,并且在性能方面会变得昂贵。例如,要到达每一方都将每个棋子向前移动两个区域的位置(移动之间没有中间),有 8!*8!,大约 16 亿个可能的移动命令。
  • 最简单的解决方案:只存储位置,并将历史单独处理(作为哈希堆栈)
  • 好吧,毕竟你真的需要关心循环吗?导致循环的移动比例是多少?我的猜测是这个分数是微不足道的。它们会导致差评吗? (即使程序自己玩,你也可以通过存储真正玩过的位置来避免拍序列。)

标签: algorithm graph-algorithm chess minimax


【解决方案1】:

我不明白问题出在哪里。除非我们为其添加随机性,否则极小极大评估对于任何给定的棋盘位置将具有完全相同的结果结合轮到谁和其他关键信息。如果我们有可用空间来存储常见的board_position+who's_turn+castling+en passant+draw_related 元组(或其散列),请继续。在任何其他评估中到达该元组时,只需返回存储的值或依靠其更详细的记录进行更复杂的评估(如果产生该记录的搜索并不详尽,我们可以在任何一次评估中对它有不同的解释)。如果程序还下棋时有时间限制,memoisation 中可能还需要一个额外的时间维度(可能是几个大块)。

(我假设您已经阅读了有关 transposition tables 的常见公共信息。)

【讨论】:

  • 如果您考虑重复绘制,我认为您的陈述是不正确的,因为节点的评估取决于您如何到达那里。这意味着如果您以一种方式到达那里,而不是采取另一种方式,相同的位置(包括轮到谁)可能会有不同的评估。 (感谢您的链接 - 是的,我确实知道并已阅读)。示例:1.Nf3 之后的位置可能有评估,例如 +0.3。但是如果我通过 1.Nf3 Nf6 2.Ng1 Ng8 3.Nf3 Nf6 4.Ng1 Ng8 5.Nf3 去那里,那么这是一个三重重复,所以平局,并且应该有评估 0。
  • @LyingDog 这就是为什么它需要存储在当前搜索状态元组的哈希中,正如我在答案中指出的那样(draw_related)。
  • 我看到您现在已将其添加到您的答案中 - 但 draw_related 实际上是什么?为了最终解决这个问题,它需要对自上次不可逆移动以来的完整历史记录进行编码,不是吗?
  • @LyingDog 如果目标是在游戏中的任何时候检测三重重复,那么它似乎就是这样。但我对三重重复的理解是,实际上它通常发生在一个非常小的移动序列中。
  • @LyingDog 那么你已经比我知道的更多了。对于转置表中的键,我们只需要计算到目前为止该位置重复了多少次。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-10-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多