2012-02-28 224 views
0

我在我的国际象棋程序中实现一个简单的NegaMax时遇到问题。NegaMax无法正常工作

据一些网站negamax应该在我的代码如下:

int Position::negaMax(int curr_depth, int depth) { 
    cd = curr_depth-1; 
    if (curr_depth==depth) return evaluate(); 

    int max = -500000; 

    calc_moves(true); 
    doBackup(cd); 
    for (int i=0;i<mvSize[cd];i++) { 
     move_figure(mvD[cd][i][0],mvD[cd][i][1],mvD[cd][i][2],mvI[cd][i][0],mvI[cd][i][1]);  
     int score = -negaMax(curr_depth+1,depth); 
     cd--; undoMove(cd); 

     if (curr_depth==1) 
      cout << "Move: " << getMoveString(i) << ", Score: " << score << endl;   

     if (score>max) 
      max=score; 
    } 
    return max; 
} 

但有了这个代码,我得到这样的输出:

Move: a2a3, Score: 0 
Move: a2a4, Score: 0 
Move: b2b3, Score: 0 
Move: b2b4, Score: 0 
Move: c2c3, Score: 0 
Move: c2c4, Score: 0 
Move: d2d3, Score: 0 
Move: d2d4, Score: 0 
Move: e2e3, Score: 0 
Move: e2e4, Score: 0 
Move: f2f3, Score: 0 
Move: f2f4, Score: 0 
Move: g2g3, Score: 0 
Move: g2g4, Score: 0 
Move: h2h3, Score: 0 
Move: h2h4, Score: 0 
Move: b1a3, Score: 0 
Move: b1c3, Score: 0 
Move: g1h3, Score: 0 
Move: g1f3, Score: 0 
score: 0 

这不可能是正确的,如果我negaMax从ply3起始位置。

如果我在递归函数调用前删除减号,我会得到更好的结果。但在我看来,这是不对的,因为如果没有上述代码中的减号,我只会最大限度地提高一名球员的得分,但对两者都不会。

Move: a2a3, Score: 0 
Move: a2a4, Score: 30 
Move: b2b3, Score: 0 
Move: b2b4, Score: 30 
Move: c2c3, Score: 0 
Move: c2c4, Score: 30 
Move: d2d3, Score: 295 
Move: d2d4, Score: 295 
Move: e2e3, Score: 295 
Move: e2e4, Score: 295 
Move: f2f3, Score: 0 
Move: f2f4, Score: 30 
Move: g2g3, Score: 0 
Move: g2g4, Score: 30 
Move: h2h3, Score: 0 
Move: h2h4, Score: 30 
Move: b1a3, Score: 30 
Move: b1c3, Score: 30 
Move: g1h3, Score: 30 
Move: g1f3, Score: 30 
score: 295 

我试着实现不同版本的MinMax,NegaMax和AlphaBeta。但我总是得到0.我会非常感谢任何提示。

回答

0

negamax的实际框架似乎正确实施。 (但是,我更习惯于看到传递给递归函数的单个深度变量,每个层都会减去 - 并在等于0时返回评估分数)。但由于对其他代码的依赖性很大,因此很难将您的问题诊断为局外人。

与其为您钓鱼,我觉得教您如何钓鱼会更好。我建议花一些时间来构建一个例程,以某种方式在视觉上输出树结构和累积分数。看起来好像你已经拥有这样的构件。最初这样做可能会花费很长时间,但从长远来看,这对调试有很大帮助 - 并且相信我,通过使用国际象棋引擎,通过这棵树进行拖网将是一个不幸的事情,尤其是当您执行更加模糊的动作时,比如en - 通行证 - 这些可能会导致树内的各种麻烦(我去过那里)。

尝试输出是这样的:

<move-white ----> 
    <move-black ----><eval score> 
    <move-black ----><eval score> 
    <move-black ----><eval score> 
    <best black score> 
<move-white ----> 
    <move-black ----><eval score> 
    <move-black ----><eval score> 
    <move-black ----><eval score> 
    <move-black ----><eval score> 
    <move-black ----><eval score> 
    <move-black ----><eval score> 
    <best black score> 
<move-white ----> 
    <move-black ----><eval score> 
    <move-black ----><eval score> 
    <best black score> 
<best white score> 

...其中表示举动。

很明显,这将会变得更大更深,但至少你可以看到发生了什么,以更人性化的方式。希望从长远来看,它也能帮助你解决其他问题。使用国际象棋引擎建立一个良好的调试系统是非常重要的,你可能会发现。

+0

非常感谢您的建议。我用这种方法向我展示了最深层板的当前板面情况,并带有一些评估函数的分数,并认识到存在一个小错误。无法弄清楚为什么它对一名没有减号的球员有效,但现在最大化似乎对两名球员都有效。 – Peter 2012-02-28 15:29:31

+0

不用担心,很高兴这有帮助。有时候最微妙的错误可能会导致看似无关的问题,特别是像国际象棋引擎这样的问题! – 2012-03-01 06:36:30