Chris Mair

Language selector

A chess engine in Go: part 4 - move generator fixes & logo

News about MOCHI1.

To cite myself, the “(likely) correct” move generator was not so correct.

I’ve tried to run PERFT to depth 8 for the starting position and got 84 998 979 372 positions instead of the correct 84 998 978 956 (I got 416 more…). It turned out the bug was not castling or en passant, as those numbers came out good according to the CPW results2.

After looking through the code I spotted the problem: I missed avoid moving a king to a square next to an enemy king. In fact, my isInCheck() procedure didn’t look for checks by kings (kings cannot give check), so this was missed. In the mean time I’ve refactored the code to just use the more generic isAttacked() function to understand if a square is attacked. This same code now looks for checks and attacked squares when castling, is a bit more efficient and fixes this bug.

I’ve also optimized castling code a bit and spotted (and fixed) another problem. MOCHI would allow castling after a rook had been taken and the other rook moved into its place (you cannot castle with a rook that was moved in any way).

To be on the safe side I’ve computed PERFT for the initial position to depth 9 (that’s an interesting depth because promotions first occur there) and recomputed PERFT to depth 6 for the CPW test positions3.

That’s an awesome 2 547 168 383 761 positions generated and I dare to say the move generator is now very likely correct (insert quote about programmer optimism :).

On a lighter note, MOCHI now has a cute logo:

MOCHI logo
MOCHI logo (C) Emil B. Mair CC BY 4.0

Language selector