Score of New vs Old: 22 - 106 - 15 [0.206] 143
ELO difference: -234.07 +/- 65.97
SPRT: llr -2.95, lbound -2.94, ubound 2.94 - H0 was accepted
Finished match
Can anyone spot any problems that I'm not immediately noticing?
Other possible issues (maybe they are minor, just double check them):
- PopCount(...) > 2 seems to include pawns but you should better test the non-pawn material only, otherwise you might get zugzwang problems in pawn endings.
- I would also reset the fifty-moves counter to 0 after making a null move, since in my opinion the null move is irreversible. (There are certainly different opinions about that.)
Volker Annuss wrote:Your nullmove does not change hash key. It must be different because the side to move has changed.
Hash probe code regenerates the key before probing. It's not much of an overhead to scan the board to generate a key from scratch.
Sven Schüle wrote:Other possible issues (maybe they are minor, just double check them):
- PopCount(...) > 2 seems to include pawns but you should better test the non-pawn material only, otherwise you might get zugzwang problems in pawn endings.
Okay, thank you!
- I would also reset the fifty-moves counter to 0 after making a null move, since in my opinion the null move is irreversible. (There are certainly different opinions about that.)
I may have forgotten to include that when transcribing the code Yes, I do zero the fifty-move counter. That's why the fifty-move counter is backed up.
I'm going to run a test in which I copy the board before making the nullmove. Just in case I'm messing something up.
Volker Annuss wrote:Your nullmove does not change hash key. It must be different because the side to move has changed.
Hash probe code regenerates the key before probing. It's not much of an overhead to scan the board to generate a key from scratch.
Sven Schüle wrote:Other possible issues (maybe they are minor, just double check them):
- PopCount(...) > 2 seems to include pawns but you should better test the non-pawn material only, otherwise you might get zugzwang problems in pawn endings.
Okay, thank you!
- I would also reset the fifty-moves counter to 0 after making a null move, since in my opinion the null move is irreversible. (There are certainly different opinions about that.)
I may have forgotten to include that when transcribing the code Yes, I do zero the fifty-move counter. That's why the fifty-move counter is backed up.
I'm going to run a test in which I copy the board before making the nullmove. Just in case I'm messing something up.
Actually it is a LOT of overhead since you do this once for every node you search...
Is there anything indexed by ply that you failed to copy? (generally one copies castling status and such in MakeMove().)
2: aren't you trying calling null move pruning when it's not necessary? for example when static_eval << beta
3: where is the code that prevent your search to do null move pruning recursively??
Volker Annuss wrote:Your nullmove does not change hash key. It must be different because the side to move has changed.
Hash probe code regenerates the key before probing. It's not much of an overhead to scan the board to generate a key from scratch.
But what if you need the updated hash key already before probing? Actually I see where that is the case: in IsTrivialDraw() you need the hash key for repetition check, and you call it prior to hash probing ... That might lead to a couple of wrong decisions regarding a repetition draw, which could of course lead to weaker play. Not sure, though, whether the effect would be so drastical to see null move delivering almost zero improvement.
You certainly mean "allowNullMove" instead of "allowPV". I don't think it is absolutely necessary to avoid making two null moves in a row. Years ago I had the same opinion like you (and many others) but today I think it is possible, I have already tried it. The point is that you do not search the position after two consecutive null moves with the same conditions as you did before, you do it with a depth reduction of 2*R (or twice the reduction you apply per null move). And if you take care not to handle the position after two consecutive null moves as a repetition then I see no problem in it.
with the actual code when he search with depth = 9, he do the null move and search with depth = 5, do the search another time with depth = 1 -> so it replace the search at depth 9 with a search at depth 1 since it doesn't filter out position with staticeval << beta
I may be wrong