一点背景知识:作为在 C++ 中学习多节点树的一种方法,我决定生成所有可能的井字棋棋盘并将它们存储在树中,这样从一个节点开始的分支都是可以从该节点跟随的所有棋盘,并且一个节点是一次跟随的棋盘。在那之后,我认为用那棵树作为决策树来编写一个 AI 来玩井字游戏会很有趣。
TTT 是一个可以解决的问题,完美的玩家永远不会输,所以在我第一次尝试 AI 时,它似乎是一个简单的 AI 编码。
现在,当我第一次实现 AI 时,我返回并在生成时为每个节点添加了两个字段:X 将获胜的次数和 O 将在该节点下的所有子节点中获胜的次数。我认为最好的解决方案是让我的 AI 在每一步中选择并沿着获胜次数最多的子树向下走。然后我发现虽然它在大多数情况下都表现完美,但我找到了可以击败它的方法。这不是我的代码有问题,只是我让 AI 选择路径的方式有问题。
然后我决定让它选择计算机获得最大胜利或人类损失最大的树,以较大者为准。这使它表现更好,但仍然不完美。我仍然可以击败它。
所以我有两个想法,我希望输入哪个更好:
1)我可以分配值 1 表示胜利,0 表示平局,-1 表示失败,而不是最大化胜利或失败。然后选择具有最高值的树将是最好的移动,因为下一个节点不能是导致损失的移动。这是板生成中的一个简单更改,但它保留了相同的搜索空间和内存使用。或者...
2) 在棋盘生成过程中,如果有一个棋盘使得 X 或 O 在下一步中获胜,则只会生成阻止该获胜的子棋子。不会考虑其他子节点,然后生成将照常进行。它缩小了树的大小,但是我必须实现一个算法来确定是否有单步获胜,我认为这只能在线性时间内完成(我认为让棋盘生成速度慢很多?)
哪个更好,或者有更好的解决方案?