GeoffW wrote:My makemove code uses the 0x88 delta trick you mentioned to figure out if in check, but I am currently doing this right at the end of makemove().
This is less than optimum as it would be best to do it at the start of makemove(), to save the move make and move undo code. That is much trickier to code however, so i am just contemplating that one now.
Where do you test for sideToMove in check ? At start or end of makemove() ?
Quick Perft (which is actually the basis of Joker) does the self-check test after MakeMove, but only for King moves, e.p. captures. This to prevent the King from trying to hide behind himself, end because e.p. pins are not trivially detected (e.g. if both involved Pawns are n the pin line).
Castlings are King moves, but in the MakeMove part that moves the Rook it is checked if the Rook ends up in-check. (So illegal castlings are treated as self-checks.)
Other moves can never cause self-check, and thus do not have to be tested at all. This because the move generator does not generate illegal moves with pinned pieces. This is much more efficient: There are only 5 enemy sliders that could pin something, and most of those fail the 0x88 test for alignment with your King. If occasionally one is aligned, that piece is excluded from normal move generation, disabling many moves at once. This saves a lot of time compared to testing each move separately for the pin condition. If a pinned piece has moves along the pin line, they are generated in the code section that handles the pins, as it is already aware what the pin line is, and has already determined upto where the moves can go (from own King upto and including pinner).
As a fringe benifit, testing for the pins automatically tell you if you are in distant check yourself. Alternatively, if you test moves for delivering check to the opponent after they are made, you can at the same time without much extra work detect new pins as well, and differentially maintain a list of pinned pieces.
When you are in check before the move, your primary concern is not if your move puts you in check, but to get out of it. It helps if your 0x88 test already tells you if the move is a distant check or a contact check. In the latter case you can limit yourself to King moves and capture of the checker. (With non-pinned pieces. Note that a move of a pinned piece on the pin line can never capture the checker or block the check.) The distant case is a pain, and I could not devise any quicker way than simply generating all moves, and then doing the 0x88 test compared to own King to see if they fal on the check line, and if they do, test if they indeed block it. (Perhaps the latter could be still sped up by also having a 0x88 distance table, but checks are not sufficiently common to care very much how you handle them.)
How exactly you handle the castlings and e.p. captures is also completely irrelevant fr speed.