C++ NegaMax没有';I don’我没有按预期工作

C++ NegaMax没有';I don’我没有按预期工作,c++,chess,minmax,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);

我在国际象棋程序中实现一个简单的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;
}
这不可能是对的,如果我从起始位置为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分。如果有任何提示,我将非常感谢。

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

我觉得与其为你钓鱼,不如教你如何钓鱼。我建议花一些时间构建一个例程,以某种方式直观地输出树结构和累积分数。似乎你已经有了这样一件事的基础。一开始这样做可能会很费时,但从长远来看,这将大大有助于调试——相信我,在一个象棋引擎中,在这棵树上拖网将是一个不幸的频繁现实,特别是当你执行更模糊的动作时,如顺道,这些可能会在树内造成各种各样的麻烦(我曾经在那里)

尝试输出如下内容:

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

…其中
---
表示移动


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

非常感谢您的建议。我使用这种方法向我显示最深层的当前电路板情况,以及我的评估函数的一些分数,并认识到有一点缺陷。我不明白为什么它对一个没有负号的玩家有效,但是现在最大化似乎对两个玩家都有效。不用担心,很高兴这有帮助。有时,最微妙的错误可能会导致看似无关的问题,特别是在象棋引擎之类的东西中!
<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>