2013-12-08 190 views
0

我正在做一个4x4井字游戏的小项目。我正在使用Alpha Beta Search来寻找下一个最佳举措。在α+β搜索,我使用的是被称为在下面的算法函数不返回负值

Alpha Beta Search

我成功地实施一切的“效用”功能的截止评价功能,但问题是效用函数不返回一个负值,我真的不知道为什么!以下是功能

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设置为true,当它从MINVALUE函数调用

isMin为O的移动和AI的举动是X.如果o赢得效用应该返回-50。 但它只返回0。我调试了程序,它实际上将-50调到nodeValuenodeValue调试器中的更改为-50),但是当我在Min或Max函数中接收时,它是零。

注:在整个项目中使用的所有int是signed int。没有unsigned关键字时,如果你正在考虑的功能,来电显示是无符号

Alpha-Beta搜索的完整代码是在这里:http://pastie.org/8538015

请朋友们帮忙尽快。

+0

我看不到''Utility'的调用,'isMin'在伪代码中设置为'true' ... – MiMo

+0

在我的代码中,它确实将区别MinValue和MaxValue的调用来自X的O) –

回答

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函数时,它不可能神奇地消失。我有一种感觉发生了腥意,代码并没有真正执行你期望的路径。

+0

我知道我可以直接返回它,但是在调试器中,它直接返回时不存储该值,所以我使用了一个值,以便我可以介入并查看它是否完成。另外,我也可以在调用者函数中做同样的事情。我也发布了minmax功能。请 –

+0

好吧,足够公平:)一旦其他代码启动,我会再次检查。 –

+0

我发布了它 - 它在http://pastie.org/8538015 –