0

I'm trying to figure out how a traditional chess engine (no AI) works, and now I'm trying to collect pv (principal variation) moves using triangular table. So I'm using a NxN table and a very simple implementation

private Integer alphaBeta(final int depth, int alpha, int beta) {
    ...
    pvLength[ply] = ply;
    ...
    while (move != null) {
        ...
        if (value > alpha) {  // (1)
            dPvTable[ply][ply] = move;
            nextPly = ply + 1;
            for (int p = nextPly; p < pvLength[nextPly]; ++p) {
                pvTable[ply][p] = pvTable[nextPly][p];
            }
            pvLength[ply] = pvLength[nextPly];
            ...
        }
        ...
    }
    ...
}

I am comparing the extracted pv with the pv resulting from the transposition table.

It works well if the pv doesn't end with checkmate. If it does end with a checkmate, the triangular table returns only the first (correct) move.

I have tried many changes but without success. The only thing that works (at the expense of search speed) is to change the condition (1) to

if (value >= alpha) {

But clearly this is not an acceptable change, because this way the search explores the tree up to the last move, and does not end at the first checkmate found.

I just wanted to know, if anyone had the same problem: is this behavior due to a flaw in my implementation? Or this method just can't return all PV moves when there are checkmates?

dakat
  • 51
  • 6

1 Answers1

0

I am answering my question after further verification.

Premise: in my engine, checkmate is evaluated with alpha (-30000). I'm using iterative deepening, so (i guess) i don't need to determine the "distance" of checkmate by adding ply, as is often done to pick the "closest".

So, i do not think that with this method it is possible to read the pv line during or at the end of the search, when the pv ends with a checkmate: the pv line is updated only if (value > alpha) and, when a checkmate is detected, at the next iteration this condition is no longer satisfied, because value == alpha. I tried to modify the condition (value > alpha) in order to register the pv line, but in this way the whole search is distorted.

However you always get the correct best move.

On the other hand, when the checkmate is not alpha, but alpha + ply, this method returns all the moves of the pv line. But this extends and slows the search.

Even using the "PV-List on the Stack" method, described in the Chess Programming Wiki, i notice the same behavior because the pv line is updated under the same condition.

This is an example, I hope it is clear enough.

The real pv line got from TT is:
    [h2-h3      , Kg4-f4     , Rd6-f6     , Nh5xf6(R)  , g2-g3      ]

In the search, we have:

            4 ->    move=g2-g3    value= 30000    alpha=306    beta=30000
            4 // g2-g3 is a pv move (gives checkmate at ply=4), and is
            4 // registered in pvTable because value > alpha
            4 old pv=[]
            4 new pv=[g2-g3      , b4xc3(P)   ]

         3 ->    move=Nh5xf6    value=-30000    alpha=-30000    beta=-306
         3 // Nh5xf6 is a pv move, but is not registered in pvTable because
         3 // value == alpha

      2 ->    move=Rd6-f6    value= 30000    alpha=306    beta=30000
      2 // Rd6-f6 is a pv move and is registered, but in a line that is not
      2 // linked to Nh5xf6
      2 old pv=[Ng5-f7     , g6-g5      , Bh6xg5(P)  , Kf4-e4     ]
      2 new pv=[Rd6-f6     , Bb6xd8(R)  , g2-g3      , b4xc3(P)   ]

   1 ->    move=Kg4-f4    value=-30000    alpha=-30000    beta=30000
   1 // Kg4-f4 is a pv move, but is not registered in pvTable because
   1 // value == alpha

0 ->    move=h2-h3    value=30000    alpha=-30000    beta=30000
0 // so the pv remains incorrect
0 old pv=[h2-h3      , Kg4-f4     , Ng5-f7     , Kf4-e4     , Rd6xg6(P)  ]
0 new pv=[h2-h3      , Kg4-f4     , Ng5-f7     , Kf4-e4     , Rd6xg6(P)  ]
dakat
  • 51
  • 6