我决定写一个解决井字游戏的小程序,以尝试一些剪枝技术在一个小游戏上的效果。使用 minimax 解决它的完整博弈树最终只有 549,946 个可能的博弈。通过 alpha-beta 剪枝,需要评估的状态数量减少到 18,297 个。然后我应用了一个转置表,将数字降低到 2,592。现在我想看看这个数字能走多低。
我要应用的下一个增强功能是战略性缩减。其基本思想是结合具有同等战略价值的国家。例如,在第一步中,如果 X 先下,那么选择一个角而不是另一个角在策略上没有什么不同(假设你的对手打得最好)。在同样的情况下,板壁的中心也是如此,中心也很重要。通过仅减少重要状态,您最终只会在第一步中评估 3 个状态而不是 9 个。这种技术应该非常有用,因为它会修剪靠近博弈树顶部的状态。这个想法来自 CMU 的一个小组创建的 GameShrink 方法,只是我试图避免编写通用形式,而只是做将技术应用于井字游戏所需的操作。
为了实现这一点,我修改了我的哈希函数(用于转置表)以枚举所有战略上等效的位置(使用旋转和翻转函数),并且只返回每个板的最低值。不幸的是,现在我的程序认为 X 在先走时可以从空棋盘中强制在 5 步内获胜。经过长时间的调试会话后,我发现程序总是返回具有最低战略意义的移动(我将最后一个移动存储在换位表中作为我的状态的一部分)。有没有更好的方法可以添加此功能,或者有一种简单的方法来确定适用于当前情况的正确移动方式以及我已经完成的操作?