以列表中的第一个状态为例,您需要解释为什么 ooxxxo-xo 应该是 1。如果我按照我认为应该阅读的方式重新编写此内容,则状态显示为:
oox
xxo
-xo
如果我们正确地应用x 作为下一步,我们将得到正确的答案。所以,问题可能出在你的移动生成中。
看看这个,你有一个存储移动的静态数组,但是当你进行递归调用时,你会一遍又一遍地覆盖这个移动。相反,您需要每个递归调用的移动的本地副本。因此,将minChildren 和maxChildren 的定义移动到MinTurn 和MaxTurn 应该至少可以解决代码中的一个问题。 (我还没有验证没有其他问题。)
明确地说,您的调用堆栈如下所示:
MaxTurn call
Set maxChildren to legal moves // <--- A
Call MinTurn recursively
MinTurn call
Set minChildren to legal moves
Call MaxTurn recursively
MaxTurn call
Set maxChildren to legal moves // <--- B
Call MinTurn recursively
当您到达标记为B 的行时,您将覆盖在A 行计算的maxChildren。因此,当程序返回A 时,可用的移动将被覆盖,并且可能与之前预期的不同。
修复后,我相信您的新问题只是您打印内容的方式。如果您查看打印代码,您会记录当前的最大值,而不是孩子返回的值:
int maxValue = Setting.NEGATIVE_INFINITY;
maxChildren = generateMoves(state);
for (State aChildren : maxChildren) {
maxValue = Math.max(maxValue, MinTurn(aChildren)); // <-- A
nodes.add(aChildren.getState() + " " + maxValue); // <--B
}
因此,在标记为 B 的行中,您正在为迄今为止看到的所有孩子打印maxValue。如果你想查看孩子的值,你不应该立即取 A 行中的最大值。而是存储结果并记录它。然后,取最大值。
您在此状态下遇到问题:
oox
xxo
-x-
这是从搜索可能开始的父状态打印出来的:
oox
xxo
---
第一招是把x放在左下角,赢了游戏,给1的值。当第二招应用时,导致x在中间的状态,maxValue仍然是1 从上一步开始。
您的代码应如下所示:
int nextValue = MinTurn(aChildren)
maxValue = Math.max(maxValue, nextValue);
nodes.add(aChildren.getState() + " " + nextValue);