Question

I have a problem with implementing a simple NegaMax in my chess programm.

According to several websites negamax should look as follows in my code:

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

But with this code I get this output:

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

That can't be right, if I negaMax for ply3 from the starting position.

If I remove the minus sign in front of the recursive function call, I get a more better result. But in my opinion that can't be right, because without the minus sign in the above code, I only maximize the score for one player, but not for the both.

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

I've tried to implement different versions of MinMax, NegaMax and AlphaBeta. But I always get a score of 0. I would be very thankful for any hints.

Was it helpful?

Solution

The actual skeleton of negamax appears to be implemented correctly. (However, I'm more used to seeing a single depth variable passed to the recursive function that is subtracted each ply - and returns the evaluated score when it equals 0). But it is hard to diagnose your problem as an outsider due to the large dependency on other code.

Rather than fishing for you, I feel it would be better to teach you how to fish. I would suggest spending some time to build a routine that outputs the tree structure and cumulative score visually somehow. It seems as though you already have the building blocks of such a thing, too. It might be time consuming to do this initially, but in the long run will help greatly with debugging - and believe me, with a chess engine, trawling through this tree will be an unfortunately frequent reality, especially when you implement more obscure moves like en-passant - these can cause all sorts of troubles within the tree (I've been there).

Try to output something like this:

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

...where ---- denotes the move.

Obviously this is going to be much larger and deeper, but at least you can see what is happening in a more human friendly way. Hopefully it will help you with other issues in the long run, too. Setting up a good debugging system with a chess engine is vital, as you will probably find.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top