Mediocre ran through most perft tests without trouble, but one caused trouble, the start position.
At depth 5 the number started to differ. 36 moves were not found correctly.
So I did a divide-search like I mentioned in my previous post and I noticed moves were missing from the branches starting with pawn to 'a4', 'a3', 'b4', 'g4', 'h3' and 'h4'.
I started tracking the 'h4' move and ran into the following position:
Black has just played g7g4 and my perft method reported finding 21 moves. The correct number is of course 22 moves, 21 ordinary moves and one en passant. It does not take a rocket scientist to understand where the problem was. :)
So I went and looked in the Board-class and looked up the en-passant generation routine. There I found this line:
if((index-17 & 0x88) == 0 && (index-15 & 0x88) == 0It is supposed to check if the pawn we are generating moves for can reach the en-passant square on the board.
&& (((index - 17) == enPassant)
|| ((index - 15) == enPassant)))
But the logic is obviously flawed. In words it says "if both the square diagonally to the right and diagonally to the left are on the board, and one of them is the en-passant square, add the en-passant move".
I have no idea what I was thinking when I wrote this, but you might remember another bug I had with this. The en-passant square is -1 if no en passant is available and if we have a black pawn on 'a2' it would think an en passant was available outside the board.
Obviously I messed up the bugfix back then. :) So now I simply changed it to:
if(enPassant != -1 &&Since the board should never produce an en passant outside the board, we never have to check for the en passant being on the board. As long as it is not -1.
(index+17 == enPassant || index+15 == enPassant))
I have to pick my default values more careful in the future.
All better now
After this fix all perft scores are working like a charm. I have not found a single error in any of the tests I have run. So hopefully the move generation is bugfree for now.