Table of Contents

Chess - Programming - Perft

Perft, standing for Performance Test, does a raw node count, up to some specified depth, by doing a full tree search.

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
DepthNodesCapturesE.p.CastlesPromotionsChecksCheckmatesTotal Nodes
12000000020
2400000000420
38902340001209322
419728115760004698206603
548656098271925800273513475072212
6119060324281200852480079827110828124132536
731959018603320034396 32668081435767
884998978956 9591295579852036
92439530234167 35695709940400191963
1069352859712417 10788546694868790619155
112097651003696806 391476876618031078854669486
1262,854,969,236,701,747 12244485286520168361091858959
131,981,066,775,000,396,239

Checks

DepthDirect Check OnlySingle Discovered Check OnlyDirect and Discovered ChecksDouble Discovered ChecksTotal
100000
200000
31200012
4461000461
52699860027004
6797896329460798271
732648427180261628032668081
89581353038470391472150959129557
9356530609963710171355472211035695709940
10107702049385915312740153029007338791078854669486
113906847090166267494850305117218523935744339147687661803
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

DepthDirect Checkmate OnlySingle Discovered Checkmate OnlyDirect and Discovered CheckmateDouble Discovered CheckmateTotal
100000
200000
300000
480008
5347000347
61082800010828
7435767000435767
898520324009852036
939942137918697687150400191963
1087716939695980581832712808790619155
113606759266056034467615537396260362290010907
12 8361091858959

Perft Estimates

DepthNodes
131.9810e+18
146.187e+19
152.015e+21
166.507e+22
172.175e+24
187.214e+25
192.462e+27
208.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.

FEN-string: r3k2r/p1ppqpb1/bn2pnp1/3PN3/1p2P3/2N2Q1p/PPPBBPPP/R3K2R w KQkq - 0 1 
DepthNodesCapturesE.p.CastlesPromotionsChecksCheckmatesTotal Nodes
14880200048
220393511910302087
397862171024531620993199949
4408560375716319291280131517225523434185552
5193690690350434167336549936378392330988730171197876242
68031647685 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 
DepthNodesTotal Nodes
12424
2496520
3948310003
4182838192841
536051033797944
67117913974977083

Position 1

This position is very good because it catches many possible bugs:

Position r3k2r/p1ppqpb1/bn2pnp1/3PN3/1p2P3/2N2Q1p/PPPBBPPP/R3K2R w KQkq -
DepthPerft Value
148
22039
397862
44085603
5193690690
68031647685

</code>


Position 2

FEN-string: 8/2p5/3p4/KP5r/1R3p1k/8/4P1P1/8 w - -
DepthNodesCapturesE.p.CastlesPromotionsChecksCheckmatesTotal Nodes
114100020
219114000100
328122092002670
443238334812300168017
567462452051116500529500
61103008394035033325075524524732733
71786336611451903629487401400241279740687

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
DepthNodesCapturesE.p.CastlesPromotionsChecksCheckmatesTotal Nodes
1600000
226487064810
3946710214012038
4422333131393077956003215492
515833292204617365120329464200568
6706045033210369132212108820068110298426973664

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