Understanding AlphaBetaMinMax

Discussion of chess software programming and technical issues.

Moderator: Ras

msarchet
Posts: 13
Joined: Tue Sep 21, 2021 4:07 am
Full name: Michael Sarchet

Understanding AlphaBetaMinMax

Post by msarchet »

I'm trying to implement AlphaBetaMinMax (negascout) following the algorithm that is posted on the CPW.

https://github.com/msarchet/panzer/blob ... search.cpp you can see my code here.

Ignore the bits for the transposition table as they are not used, and currently not implemented correctly.

What happens is I end up with these kind of scores when searching from the startpos for white

go depth 3
info depth 1 score 1662 g1f3
info depth 2 score 1837 g1f3
info depth 3 score 32767 g1f3 <--- This is INT16_MAX
bestmove g1f3

I'm doing a full window search right now.

This worked for me fine when I was using separate Min and Max function so I'm not sure what I implemented incorrectly.

My code works by calling an iterative deepening function to check all of the depths, and to help with bestmove ordering. In my iterative search I call

Code: Select all

makeMove(move)
if (!InCheck)
{
    score = -AlphaBetaMinMax(board, -beta, -alpha, depth);
}
unmakeMove(move)
if (score > alpha) { 
    score = alpha;
    bestMove = move;
 }
In AlphaBetaMinMax I do the following

Code: Select all

if (depth == 0)
{
    auto eval = QSearch(board, alpha, beta);
    return eval;
}

for (moves)
{
     makemove(move);
     if (!inCheck)
     {
          score = -AlphaBetaMinMax(board, -beta, -alpha, depth - 1);
          if (score > alpha)
          {
             if (score >= beta)
             {
                 unmakeMove(move);
                 return beta;
             }
             
             alpha = score;
         }
     }
}

return alpha;
In QSearch I return early if the stand pat is >= beta, and after each recursive search I return if the result of the recursive call is > beta, otherwise I return the bestScore at the end.

Clearly I am not understanding something correctly, and would appreciate some guidance, as I feel like I'm floundering around trying to understand what I am doing incorrectly.
Panzer (still very in progress) - C++ bitboard engine https://github.com/msarchet/panzer
odomobo
Posts: 96
Joined: Fri Jul 06, 2018 1:09 am
Location: Chicago, IL
Full name: Josh Odom

Re: Understanding AlphaBetaMinMax

Post by odomobo »

The issue might be due to negating min int. I think negating min int can return itself.
R. Tomasi
Posts: 307
Joined: Wed Sep 01, 2021 4:08 pm
Location: Germany
Full name: Roland Tomasi

Re: Understanding AlphaBetaMinMax

Post by R. Tomasi »

odomobo wrote: Thu Oct 07, 2021 10:36 pm The issue might be due to negating min int. I think negating min int can return itself.
Indeed. It results in undefined behaviour, so not only could it return itself, but it could return anything really. Just use -INT_MAX as negative infinity score and you're quarding against that. (In C/C++ that is - not sure how other standards handle the fact that there is always a non-zero number that maps to itself).

The reason for this, is that the cardinality of all ints is a power of two, thus an even number. But there already is one element that maps to itself - zero. So one additional odd element without a counterpart will always be present.
msarchet
Posts: 13
Joined: Tue Sep 21, 2021 4:07 am
Full name: Michael Sarchet

Re: Understanding AlphaBetaMinMax

Post by msarchet »

Thanks. I will try this out and see if that improves things.
Panzer (still very in progress) - C++ bitboard engine https://github.com/msarchet/panzer
User avatar
Bo Persson
Posts: 261
Joined: Sat Mar 11, 2006 8:31 am
Location: Malmö, Sweden
Full name: Bo Persson

Re: Understanding AlphaBetaMinMax

Post by Bo Persson »

Another option is to NOT use a 16-bit value for the score.

Using a short value can save space (if you store a huge number of them), but it doesn't save execution time as they will be promoted to an int in all arithmetic operations anyway. The code could just as well use an int.
R. Tomasi
Posts: 307
Joined: Wed Sep 01, 2021 4:08 pm
Location: Germany
Full name: Roland Tomasi

Re: Understanding AlphaBetaMinMax

Post by R. Tomasi »

Bo Persson wrote: Thu Oct 07, 2021 11:29 pm Another option is to NOT use a 16-bit value for the score.

Using a short value can save space (if you store a huge number of them), but it doesn't save execution time as they will be promoted to an int in all arithmetic operations anyway. The code could just as well use an int.
That doesn't resolve the problem with -INT_MIN being ill-defined. It's independend from the number of bits representing the signed integer.
msarchet
Posts: 13
Joined: Tue Sep 21, 2021 4:07 am
Full name: Michael Sarchet

Re: Understanding AlphaBetaMinMax

Post by msarchet »

Switching from INT16_MAX/MIN to using a defined INF as 10000 appears to have resolved the issue.

Now to work out my other issues. :D
Bo Persson wrote: Thu Oct 07, 2021 11:29 pm Another option is to NOT use a 16-bit value for the score.

Using a short value can save space (if you store a huge number of them), but it doesn't save execution time as they will be promoted to an int in all arithmetic operations anyway. The code could just as well use an int.
Aren't int16_t and short the same number of bytes?
Panzer (still very in progress) - C++ bitboard engine https://github.com/msarchet/panzer
User avatar
Ras
Posts: 2703
Joined: Tue Aug 30, 2016 8:19 pm
Full name: Rasmus Althoff

Re: Understanding AlphaBetaMinMax

Post by Ras »

msarchet wrote: Fri Oct 08, 2021 1:23 amSwitching from INT16_MAX/MIN to using a defined INF as 10000 appears to have resolved the issue.
I'd go for a bit more such as maybe 16000 because there are some pathological positions where 10000 can lead to an overlap between mate scores and material difference.
Aren't int16_t and short the same number of bytes?
No. int16_t is 16 bits while short is at least 16 bits, but can be more, depending on the compiler and platform.
Rasmus Althoff
https://www.ct800.net
R. Tomasi
Posts: 307
Joined: Wed Sep 01, 2021 4:08 pm
Location: Germany
Full name: Roland Tomasi

Re: Understanding AlphaBetaMinMax

Post by R. Tomasi »

Ras wrote: Fri Oct 08, 2021 2:03 am
msarchet wrote: Fri Oct 08, 2021 1:23 amSwitching from INT16_MAX/MIN to using a defined INF as 10000 appears to have resolved the issue.
I'd go for a bit more such as maybe 16000 because there are some pathological positions where 10000 can lead to an overlap between mate scores and material difference.
For +/- INF I'd actually go for the maximum/minimum safe value (i.e. +INT16_MAX for positive infinity and -INT16_MAX for negative infinity), since those are supposed to be larger/smaller than any mating score.
msarchet
Posts: 13
Joined: Tue Sep 21, 2021 4:07 am
Full name: Michael Sarchet

Re: Understanding AlphaBetaMinMax

Post by msarchet »

R. Tomasi wrote: Fri Oct 08, 2021 2:20 am
Ras wrote: Fri Oct 08, 2021 2:03 am
msarchet wrote: Fri Oct 08, 2021 1:23 amSwitching from INT16_MAX/MIN to using a defined INF as 10000 appears to have resolved the issue.
I'd go for a bit more such as maybe 16000 because there are some pathological positions where 10000 can lead to an overlap between mate scores and material difference.
For +/- INF I'd actually go for the maximum/minimum safe value (i.e. +INT16_MAX for positive infinity and -INT16_MAX for negative infinity), since those are supposed to be larger/smaller than any mating score.
Doesn't this run me into the same problem with -(-INF) being -INT16_MIN?
Panzer (still very in progress) - C++ bitboard engine https://github.com/msarchet/panzer