NegaMax没有按预期工作

时间:2012-02-28 08:35:45

标签: c++ chess minmax

我在国际象棋程序中实现一个简单的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

这不可能是正确的,如果我从起始位置开始为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分。我会非常感谢任何提示。

1 个答案:

答案 0 :(得分:0)

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

我觉得最好教你如何钓鱼。我建议花一些时间来构建一个以某种方式在视觉上输出树形结构和累积分数的例行程序。好像你已经拥有了这样的东西的构建块。最初这样做可能会耗费时间,但从长远来看,这将有助于调试 - 并且相信我,使用国际象棋引擎,拖网浏览这棵树将是一个不幸的频繁现实,特别是当您实施更加模糊的动作,如en - passant - 这些可能会导致树内的各种麻烦(我去过那里)。

尝试输出如下内容:

<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>

...其中----表示移动。

显然,这将会更大更深,但至少你可以以更人性化的方式看到正在发生的事情。希望从长远来看,它也可以帮助您解决其他问题。建立一个带有国际象棋引擎的良好调试系统至关重要,正如您可能会发现的那样。