0

我正在做一个关于 4x4 井字游戏的小项目。我正在使用 Alpha Beta Search 来寻找下一个最佳动作。在 alpha beta 搜索中,我使用了在以下算法的“实用程序”函数中调用的截止评估函数

Alpha Beta 搜索

我成功地实现了一切,但问题是效用函数没有返回负值,我真的不知道为什么!以下是函数

private static int utility(GameTreeNode gtn, bool isMin = false)
{
    int nodeValue = 0;
    switch (gtn.NodeBoard.getBoardStatus())
    {
        case Status.Success:
            nodeValue = 50;
            if (isMin) nodeValue = -50;    /// here
            break;
        case Status.Incomplete:
            if (isMin)
                nodeValue = gtn.evaluate(State.X);
            else
                nodeValue = gtn.evaluate(State.O);
            break;
    }
    // case Status.Draw:
    return nodeValue;
}

isMin从 MinValue 函数调用时设置为 true

isMin是 O 的移动,而 AI 的移动是 X。如果 O 获胜,实用程序应该返回 -50。但它只返回 0。我调试了程序,它实际上将 -50 分配给nodeValuenodeValue调试器中的更改为 -50),但是当我在 Min 或 Max 函数中收到时,它为零。

注意:整个项目中使用的所有 int 都是signed int. unsigned如果您认为函数调用者是无符号的,则不使用关键字

alpha-beta 搜索的完整代码在这里: http: //pastie.org/8538015

请朋友们尽快帮忙。

4

1 回答 1

1

由于您在方法签名中使用了可选参数,因此我提醒您在输入函数时注意代码实际运行的内容。你说你调试了它并分配了值,但我没有足够的上下文来知道它是否只发生在许多情况之一。无论如何,请小心那些!

我会像这样重写你的函数:

private static int utility(GameTreeNode gtn, bool isMin)
{
    switch (gtn.NodeBoard.getBoardStatus())
    {
        case Status.Success:
            return isMin 
                ? -50 
                : 50;
        case Status.Incomplete:
            return isMin 
                ? gtn.evaluate(State.X)
                : gtn.evaluate(State.O);
        default:
            throw new NotImplementedException("The status is not implemented.");
    }
}

我看到这种方法的一些改进:

  • 您不需要存储一个值并在最后返回它。在您的情况下,当您采用 Status.Success 路径时,您总是将 50 存储到 nodeValue 中,然后有时将 -50 分配给它。除非你坚持在你的函数中有一个返回,否则我认为这种方法更清楚。可能只是我的意见。
  • switch 语句中有一个默认值,因此在您的状态未实现的情况下,您将显式抛出异常。
  • 您的函数没有可选参数。我看不到让这个参数可选的好处。在我看来,它看起来只是增加了空间,使事情更难调试。

编辑:

基于以下代码: http: //pastie.org/8538015#33,43

看起来您唯一可以让实用程序返回负值的时间if (gtn.Nodes.Count == 0) return utility(gtn, true);是在函数中被击中时private static int MinValue(GameTreeNode gtn, int alpha, int beta)。否则,除非有更多您没有发布的代码,否则对实用程序函数的其他调用不会达到您所追求的逻辑路径。您在进入那里时提到过,您可以看到 nodeValue 的值已正确分配。

我建议你改变:

// if Terminal-test(state) then return utitly(state)
if (gtn.Nodes.Count == 0) return utility(gtn, true);
gtn.Value = Globals.MAXINT;

// if Terminal-test(state) then return utitly(state)
if (gtn.Nodes.Count == 0)
{
    int retVal = utility(gtn, true);
    return retVal;
}

gtn.Value = Globals.MAXINT;

至少暂时,然后在return retVal. 如果您的实用程序函数实际上像您所说的那样设置了您期望的值,那么当它将它返回给 MinValue 函数时,它不可能神奇地消失。我感觉发生了一些可疑的事情,并且代码实际上并没有按照您期望的路径执行。

于 2013-12-08T19:44:08.850 回答