public int Perft(int depth)
{
var moves = ListLegalMoves(this);
if (depth == 1) return moves.Count;
int count = 0;
foreach (mv in moves)
{
var capture = mv.GetCapture(this);
mv.Apply(this);
count += Perft(depth - 1);
mv.TakeBack(this, capture);
}
return count;
}
JetChess is not a chess engine but a perft counter.
I guess that times are somewhat misleading because different computers will bring different times for the same engine.
Anyway, here I go with some runs by JetChess in an Intel Pentium D930 (3 GHz) of year 2006. JetChess is single core, 32-bit and hash will vary. One run per ply:
Well, the code Henk shows actually is a bulk-counting perft. So I guess dedicated perft counters are allowed. Qperft is basically Joker's move generator.
Reposting a qperft run from the time when Skipper still got the wrong count:
What a huge difference with 18 seconds. Perhaps my KingInCheck routine is much too slow. Also it calls my normal move generator which sorts the moves etcetera which makes no sense.
Well, qperft does not do fully legal move generation. It doesn't generate illegal moves with pinned pieces (which saves it some time), so the only moves that would have to be tested to see if it puts itself in check are King moves and e.p. capture. So it makes those at the 1-ply level. And it then tests for check using the 0x88 attack test for all non-Pawns in the piece list, and testing the two board squares from which it could be checked by a Pawn.
Henk wrote:Also it calls my normal move generator which sorts the moves...
In a chess (not perft) context, have you tried sorting on demand in the main loop - getNextBestMove() kinda thing - that way you haven't done all that sorting for nothing in nodes that return >= beta early.
I sort all non captures. I remember extracting the move with maximum value instead of sorting was not a performance gain. Maybe for captures for there are less but I did not test that.