To me it looks like you do not restore the hash key correctly whenever old_enpassant != 0. The enPassant property of the board "changes" from old_enpassant to 0 so you need to XOR with the corresponding BoardHash.EnpassantHashKeys[...] values of both old_enpassant and 0 when making and unmaking the null move. Doing this only if old_enpassant != 0 may or may not be faster (but I would prefer to avoid the additional "if"). There are certainly tricks to do this as fast as possible but I guess this would not affect overall performance at all.pedrojdm2021 wrote: ↑Sun Jun 06, 2021 7:09 pm any ideas? this is my whole negamax function, thank you
Code: Select all
byte old_enpassant = board.current_state.enPassant; board.current_state.sideToMove ^= 1; board.current_state.hash ^= BoardHash.sideHash; board.current_state.enPassant = 0; board.current_state.hash ^= BoardHash.EnpassantHashKeys[0]; //... // restore side & state board.current_state.sideToMove ^= 1; board.current_state.enPassant = old_enpassant; board.current_state.hash ^= BoardHash.sideHash; board.current_state.hash ^= BoardHash.EnpassantHashKeys[old_enpassant];
Since your test position has potential to create a lot of positions with the ep target square set within the first four plies (after a4 by White or c5 by Black), this might result in severe damage to your hash key and could explain any undesired behaviour.
To debug possible hash key problems, it may be a good idea to add an assertion after each UnmakeMove() that the hash key is now the same as before the corresponding MakeMove().
Also I noticed that you do not increment "ply" when making a null move (maybe you do this by intent but I do not understand why).