Page 1 of 1

Null move

Posted: Fri Apr 24, 2020 10:09 pm
by Robert Pope
So, I've always struggled to get a null move search that gives me positive results. I decided to look at the rules that Stockfish uses and see the following:

Code: Select all


    // Step 9. Null move search with verification search (~40 Elo)
1    if (   !PvNode
2        && (ss-1)->currentMove != MOVE_NULL
3        && (ss-1)->statScore < 23397
4        &&  eval >= beta
5        &&  eval >= ss->staticEval
6        &&  ss->staticEval >= beta - 32 * depth - 30 * improving + 120 * ttPv + 292
7        && !excludedMove
8        &&  pos.non_pawn_material(us)
9        && (ss->ply >= thisThread->nmpMinPly || us != thisThread->nmpColor))

Can anyone help explain the conditions in lines 3-6? I can almost read them, but in particular, I'm confused about the difference between statScore, eval, and staticEval. Those sound like almost the same thing, but must obviously be different.

Re: Null move

Posted: Fri Apr 24, 2020 11:07 pm
by Dann Corbit
eval can be a hash lookup, which might be a 40 ply search. It is therefore a much better estimate than static eval.
static eval is the result of calling the evaluation function. Even if we can't find it in the hash, we can get an estimate of the position this way.
statScore is an eval that is stored at each ply of the search and which may be modified by history. This is useful for things like "Am I improving?"

Re: Null move

Posted: Sat Apr 25, 2020 3:19 pm
by Robert Pope
Thanks for the explanation. I don't think I ever had eval as one of the criteria, and that appears to add 30 elo in my initial tests.

Re: Null move

Posted: Sat Apr 25, 2020 9:33 pm
by Dann Corbit
As far as I know, I invented this technique. I called it smooth scaling null move at the time.
Of course it is possible that someone preceded me with the idea. And the concept is simple enough.
If a move looks terrible, we reduce it more. If a move looks good we reduce it less.

Re: Null move

Posted: Sun Apr 26, 2020 3:59 am
by mjlef
Robert Pope wrote: Fri Apr 24, 2020 10:09 pm So, I've always struggled to get a null move search that gives me positive results. I decided to look at the rules that Stockfish uses and see the following:

Code: Select all


    // Step 9. Null move search with verification search (~40 Elo)
1    if (   !PvNode
2        && (ss-1)->currentMove != MOVE_NULL
3        && (ss-1)->statScore < 23397
4        &&  eval >= beta
5        &&  eval >= ss->staticEval
6        &&  ss->staticEval >= beta - 32 * depth - 30 * improving + 120 * ttPv + 292
7        && !excludedMove
8        &&  pos.non_pawn_material(us)
9        && (ss->ply >= thisThread->nmpMinPly || us != thisThread->nmpColor))

Can anyone help explain the conditions in lines 3-6? I can almost read them, but in particular, I'm confused about the difference between statScore, eval, and staticEval. Those sound like almost the same thing, but must obviously be different.
Sure. this line:
&& (ss-1)->statScore < 23397
means if the history scores for the move that the opponent just made was very good, do not bother trying nullmove since we are likely to fail low here. This saves time on searches that are unlikel to pass.

this line:
&& eval >= beta

eval is the hash-adjusted eval. This means it took the static eval of the current positions, and if there was a hash entry with better informaion, it gets adjusted. So sometimes eval will just be the static eval, and other times higher or lower than that. This helps in two ways, if the hash adjusted eval is higher than beta, we should probably try a nullmove even if the static eval is under beta, and if the hash adjusted eval is lower than the static eval, then it is unlikely to fail high. The verification search would see it looses if it has to search. I suggested uses of a hash modified eval a very log time ago on rec.games.chess or maybe talkchess. I used it in NOW.

this line:
&& ss->staticEval >= beta - 32 * depth - 30 * improving + 120 * ttPv + 292
gradually allows worse and worse static evals to still have a nullmove run on them. Larry actually came up with this idea in an earlier Komodo. I remember because I was dealing with ailing parents and he actually modified and compiled the code while I was away. The 30 * improving just owers this depth based margin if the position's eval has aimproved from 2 or 4 plies ago. the 120*ttPv raises the margin if the hash move came from a PV node.

Mark

Re: Null move

Posted: Sun Apr 26, 2020 4:10 am
by mjlef
Dann Corbit wrote: Sat Apr 25, 2020 9:33 pm As far as I know, I invented this technique. I called it smooth scaling null move at the time.
Of course it is possible that someone preceded me with the idea. And the concept is simple enough.
If a move looks terrible, we reduce it more. If a move looks good we reduce it less.
Actually with nullmove, the higher the hash adjusted score is above beta, the more many programs reduce. So in this case, the better a position (or search result was), the more it gets reduced. I suppose you could say after the nullmove, an if an eval/search was done for the opponent, then the nullmoe could be considered a worse move, but artifically.

LMR works like you suggest if it uses history reductions. A move with a low history gets reduced more, and the better its history the less it gets reduced.

Mark