====== Chess - Programming - Perft ======
**Perft**, standing for Performance Test, does a raw node count, up to some specified depth, by doing a full tree search.
* By recording the amount of time taken to complete a Perft Test, it is possible to check the performance.
Draws by threefold repetition are ignored.
----
===== Perft Function =====
A simple perft function might look as follows:
typedef unsigned long long u64;
u64 Perft(int depth)
{
MOVE move_list[256];
int n_moves, i;
u64 nodes = 0;
if (depth == 0) return 1;
n_moves = GenerateMoves(move_list);
for (i = 0; i < n_moves; i++) {
MakeMove(move_list[i]);
nodes += Perft(depth - 1);
UndoMove(move_list[i]);
}
return nodes;
}
----
===== Perft Values =====
==== Start Positition ====
Perft against normal opening position:
FEN-string: rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1
^Depth^Nodes^Captures^E.p.^Castles^Promotions^Checks^Checkmates^Total Nodes^
|1|20|0|0|0|0|0|0|20|
|2|400|0|0|0|0|0|0|420|
|3|8902|34|0|0|0|12|0|9322|
|4|197281|1576|0|0|0|469|8|206603|
|5|4865609|82719|258|0|0|27351|347|5072212|
|6|119060324|2812008|5248|0|0|798271|10828|124132536|
|7|3195901860|3320034396| | | |32668081|435767| |
|8|84998978956| | | | |959129557|9852036| |
|9|2439530234167| | | | |35695709940|400191963| |
|10|69352859712417| | | | |1078854669486|8790619155| |
|11|2097651003696806| | | | |39147687661803|1078854669486| |
|12|62,854,969,236,701,747| | | | |1224448528652016|8361091858959| |
|13|1,981,066,775,000,396,239| | | | | | | |
----
=== Checks ===
^Depth^Direct Check Only^Single Discovered Check Only^Direct and Discovered Checks^Double Discovered Checks^Total^
|1|0|0|0|0|0|
|2|0|0|0|0|0|
|3|12|0|0|0|12|
|4|461|0|0|0|461|
|5|26998|6|0|0|27004|
|6|797896|329|46|0|798271|
|7|32648427|18026|1628|0|32668081|
|8|958135303|847039|147215|0|959129557|
|9|35653060996|37101713|5547221|10|35695709940|
|10|1077020493859|1531274015|302900733|879|1078854669486|
|11|39068470901662|67494850305|11721852393|57443|39147687661803|
|12| | | | |1224448528652016|
**NOTE:** Definitions are:
* **Direct Check**: When a piece which moved gives check.
* A check given by one piece when another friendly piece moves out of the way.
* This excludes cases where the check happens because an enemy pawn gets captured En Passant.
* **Discovered Check**: When a piece which didn't move gives check.
* **Double Check**: When two pieces give check. Split into two categories: "direct and discovered check" and "double discovered check".
* A double check is a discovered check where the moving piece also gives check.
* This definition excludes cases where a king is under two discovered attacks.
* Also in general the expression "the moving piece" sounds awkward, because two pieces move during castling.
----
=== Check Mates ===
^Depth^Direct Checkmate Only^Single Discovered Checkmate Only^Direct and Discovered Checkmate^Double Discovered Checkmate^Total^
|1|0|0|0|0|0|
|2|0|0|0|0|0|
|3|0|0|0|0|0|
|4|8|0|0|0|8|
|5|347|0|0|0|347|
|6|10828|0|0|0|10828|
|7|435767|0|0|0|435767|
|8|9852032|4|0|0|9852036|
|9|399421379|1869|768715|0|400191963|
|10|8771693969|598058|18327128|0|8790619155|
|11|360675926605|60344676|1553739626|0|362290010907|
|12| | | | |8361091858959|
----
==== Perft Estimates ====
^Depth^Nodes^
|13|1.9810e+18|
|14|6.187e+19|
|15|2.015e+21|
|16|6.507e+22|
|17|2.175e+24|
|18|7.214e+25|
|19|2.462e+27|
|20|8.350e+28|
**NOTE:** These estimates are done by randomly pruning the game tree.
----
==== Good Test Position ====
The startposition is not a very good test position as it does not uncover flaws that might still be hidden regarding promotion or castling.
* Therefore the following position should be a better test.
FEN-string: r3k2r/p1ppqpb1/bn2pnp1/3PN3/1p2P3/2N2Q1p/PPPBBPPP/R3K2R w KQkq - 0 1
^Depth^Nodes^Captures^E.p.^Castles^Promotions^Checks^Checkmates^Total Nodes^
|1|48|8|0|2|0|0|0|48|
|2|2039|351|1|91|0|3|0|2087|
|3|97862|17102|45|3162|0|993|1|99949|
|4|4085603|757163|1929|128013|15172|25523|43|4185552|
|5|193690690|35043416|73365|4993637|8392|3309887|30171|197876242|
|6|8031647685| | | | | | |8229523927|
----
==== Discover promotion bugs ====
The following position does not look very realistic but nevertheless helps to uncover promotion bugs.
FEN-string: n1n5/PPPk4/8/8/8/8/4Kppp/5N1N b - - 0 1
^Depth^Nodes^Total Nodes^
|1|24|24|
|2|496|520|
|3|9483|10003|
|4|182838|192841|
|5|3605103|3797944|
|6|71179139|74977083|
----
==== Position 1 ====
This position is very good because it catches many possible bugs:
Position r3k2r/p1ppqpb1/bn2pnp1/3PN3/1p2P3/2N2Q1p/PPPBBPPP/R3K2R w KQkq -
^Depth^Perft Value^
|1|48|
|2|2039|
|3|97862|
|4|4085603|
|5|193690690|
|6|8031647685|
----
==== Position 2 ====
FEN-string: 8/2p5/3p4/KP5r/1R3p1k/8/4P1P1/8 w - -
^Depth^Nodes^Captures^E.p.^Castles^Promotions^Checks^Checkmates^Total Nodes^
|1|14|1|0|0|0|2|0|
|2|191|14|0|0|0|10|0|
|3|2812|209|2|0|0|267|0|
|4|43238|3348|123|0|0|1680|17|
|5|674624|52051|1165|0|0|52950|0|
|6|11030083|940350|33325|0|7552|452473|2733|
|7|178633661|14519036|294874|0|140024|12797406|87|
----
==== Position 3 ====
FEN-string: r3k2r/Pppp1ppp/1b3nbN/nP6/BBP1P3/q4N2/Pp1P2PP/R2Q1RK1 w kq - 0 1
Or mirrored (with the same perft results):
FEN-string: r2q1rk1/pP1p2pp/Q4n2/bbp1p3/Np6/1B3NBn/pPPP1PPP/R3K2R b KQ - 0 1
^Depth^Nodes^Captures^E.p.^Castles^Promotions^Checks^Checkmates^Total Nodes^
|1|6|0|0|0|0|0| |
|2|264|87|0|6|48|10| |
|3|9467|1021|4|0|120|38| |
|4|422333|131393|0|7795|60032|15492| |
|5|15833292|2046173|6512|0|329464|200568| |
|6|706045033|210369132|212|10882006|81102984|26973664| |
----
===== A very interesting FEN =====
18 queens with only 6 captures:
k1qrq3/rq4Qq/3q1Q2/Q6q/3Q4/1Q4Q1/R1q1Q2Q/KQR2q1q/
----
===== Other FENs useful for finding bugs =====
Position 8/3K4/2p5/p2b2r1/5k2/8/8/1q6 b - 1 67
Perft(1) = 50
Perft(2) = 279
Position 8/7p/p5pb/4k3/P1pPn3/8/P5PP/1rB2RK1 b - d3 0 28
Perft(6) = 38633283
Position rnbqkb1r/ppppp1pp/7n/4Pp2/8/8/PPPP1PPP/RNBQKBNR w KQkq f6 0 3
Perft(5) = 11139762
Position 8/2p5/3p4/KP5r/1R3p1k/8/4P1P1/8 w - -
Perft(6) = 11030083
Perft(7) = 178633661
----
==== References ====
http://web.archive.org/web/20120420061542/http://www.rocechess.ch/perft.html