In the second diagram that I posted in the starting post of this topic, I forgot the castling rights (KQkq) in FEN string. The same happened to me at first when running Critter 1.4, until I discovered that I forgot KQkq in FEN. So, Critter results are good in that post, but not the FEN of the second diagram.JuLieN wrote:There, bug found and corrected. Now Prédateur agrees with JetChess too.It's quite astonishing to find a bug in the move generation when I thought it was bug free for years!
Maybe I should tell what the bug was, in case someone else has the same problem in his engine?
After going deeper into the tree to see where the node count was starting to diverge, I noticed that when the e pawn was promoted to a rook and that this rook was later captured by the black queen then Prédateur wouldn't consider castling on the king side anymore. So I looked into my MakeMove routine and found a bug there (in pseudocode):
The commented line is where the bug was: I falsely assumed that the captured rook would be the other one on the starting position board (WhiteRook2), while this rook was actually WhitePawn5 turned into a rook, which wrongly triggered the loss of the king-side castling flag.Code: Select all
if (Capture) and (CapturedPiece.type = rook) then begin if (Board[to_square] = WhiteRook1) then WhiteQueenCastle := false else WhiteKingCastle := false; // This is where the bug is!!! end;
The correct pseudo-code is:So the missing 1520 moves out of 94 billions were all the king-side castles moves lost that way.Code: Select all
if (Capture) and (CapturedPiece.type = rook) then begin if (Board[to_square] = WhiteRook1) then WhiteQueenCastle := false else if (Board[to_square] = WhiteRook2) then WhiteKingCastle := false; end;
So this position was very interesting because it was a position where:
1- the game is early so the king still hasn't castled but can still do it on both sides;
2- still, a pawn is ready to get promoted.
As the perft procedure up to a depth 7 in this position takes some time, here is a more handy position (a few plies later in the tree) that still matches those two criteria above:
[d]rnbq1k1r/pp1Pbppp/2p5/8/2B5/8/PPP1NnPP/RNBQK2R w KQ - 1 8
(Here, a perft 3 is sufficient to detect the class of bugs described above)
Is your perft (with hash) having problems with this position too, HG?
Thanks again for this position, Jesús!
Now, trying this position:
[d]rnbq1k1r/pp1Pbppp/2p5/8/2B5/8/PPP1NnPP/RNBQK2R w KQ - 1 8
Code: Select all
i-perft -divide 3 "rnbq1k1r/pp1Pbppp/2p5/8/2B5/8/PPP1NnPP/RNBQK2R w KQ - 1 8"
i-perft 1.0 (c) 2006-2008 AJ Siemelink
+---+---+---+---+---+---+---+---+
8 |*r*|*n*|*b*|*q*| |*k*| |*r*|
+---+---+---+---+---+---+---+---+
7 |*p*|*p*| |(P)|*b*|*p*|*p*|*p*|
+---+---+---+---+---+---+---+---+
6 | | |*p*| | | | | |
+---+---+---+---+---+---+---+---+
5 | | | | | | | | |
+---+---+---+---+---+---+---+---+
4 | | |(B)| | | | | |
+---+---+---+---+---+---+---+---+
3 | | | | | | | | |
+---+---+---+---+---+---+---+---+
2 |(P)|(P)|(P)| |(N)|*n*|(P)|(P)|
+---+---+---+---+---+---+---+---+
1 |(R)|(N)|(B)|(Q)|(K)| | |(R)|
+---+---+---+---+---+---+---+---+
a b c d e f g h
--divide--------------
Ke1g1 1376
d7xc8=Q 1432
d7xc8=N 1573
d7xc8=R 1269
d7xc8=B 1634
a2a3 1344
a2a4 1404
b2b3 1339
b2b4 1369
c2c3 1409
g2g3 1279
g2g4 1308
h2h3 1342
h2h4 1373
Ne2g1 1431
Ne2c3 1564
Ne2g3 1494
Ne2d4 1525
Ne2f4 1526
Nb1d2 1143
Nb1a3 1274
Nb1c3 1436
Bc4b5 1303
Bc4a6 1228
Bc4d5 1345
Bc4e6 1408
Bc4xf7 1301
Bc4d3 1240
Bc4b3 1246
Bc1d2 1337
Bc1e3 1558
Bc1f4 1523
Bc1g5 1395
Bc1h6 1286
Rh1g1 1311
Rh1f1 1364
Qd1d2 1405
Qd1d3 1656
Qd1d4 1722
Qd1d5 1658
Qd1d6 1476
Ke1f1 1445
Ke1xf2 1269
Ke1d2 978
----------------------
total 61298 (0.03 seconds)
Code: Select all
frcperft-win32
frcperft 1.0, (C) 2008-2011 AJ Siemelink
single threaded, no hashing, mode=FAST, extract=BSF32, count=LOOP
+---+---+---+---+---+---+---+---+
8 |*r*|*n*|*b*|*q*|*k*|*b*|*n*|*r*|
+---+---+---+---+---+---+---+---+
7 |*p*|*p*|*p*|*p*|*p*|*p*|*p*|*p*|
+---+---+---+---+---+---+---+---+
6 | | | | | | | | |
+---+---+---+---+---+---+---+---+
5 | | | | | | | | |
+---+---+---+---+---+---+---+---+
4 | | | | | | | | |
+---+---+---+---+---+---+---+---+
3 | | | | | | | | |
+---+---+---+---+---+---+---+---+
2 |(P)|(P)|(P)|(P)|(P)|(P)|(P)|(P)|
+---+---+---+---+---+---+---+---+
1 |(R)|(N)|(B)|(Q)|(K)|(B)|(N)|(R)|
+---+---+---+---+---+---+---+---+
a b c d e f g h
rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1
interactive mode, type 'help'+Enter for help
% fen rnbq1k1r/pp1Pbppp/2p5/8/2B5/8/PPP1NnPP/RNBQK2R w KQ - 1 8
+---+---+---+---+---+---+---+---+
8 |*r*|*n*|*b*|*q*| |*k*| |*r*|
+---+---+---+---+---+---+---+---+
7 |*p*|*p*| |(P)|*b*|*p*|*p*|*p*|
+---+---+---+---+---+---+---+---+
6 | | |*p*| | | | | |
+---+---+---+---+---+---+---+---+
5 | | | | | | | | |
+---+---+---+---+---+---+---+---+
4 | | |(B)| | | | | |
+---+---+---+---+---+---+---+---+
3 | | | | | | | | |
+---+---+---+---+---+---+---+---+
2 |(P)|(P)|(P)| |(N)|*n*|(P)|(P)|
+---+---+---+---+---+---+---+---+
1 |(R)|(N)|(B)|(Q)|(K)| | |(R)|
+---+---+---+---+---+---+---+---+
a b c d e f g h
rnbq1k1r/pp1Pbppp/2p5/8/2B5/8/PPP1NnPP/RNBQK2R w KQ - 1 1
% divide 3
O-O 1376
dxc8=Q 1459
dxc8=N 1607
dxc8=B 1668
dxc8=R 1296
a4 1433
b4 1398
g4 1337
h4 1402
a3 1373
b3 1368
c3 1440
g3 1308
h3 1371
Nd2 1174
Na3 1303
Nbc3 1467
Ng1 1431
Nec3 1595
Ng3 1523
Nd4 1554
Nf4 1555
Bd2 1368
Be3 1587
Bf4 1552
Bg5 1422
Bh6 1312
Bb3 1275
Bd3 1269
Bb5 1332
Bd5 1375
Ba6 1256
Be6 1438
Bxf7 1328
Qd2 1436
Qd3 1685
Qd4 1751
Qd5 1688
Qd6 1500
Rf1 1364
Rg1 1311
Kf1 1445
Kd2 978
Kxf2 1269
-------------------
total 62379
%
Code: Select all
qperft 3 "-2" "rnbq1k1r/pp1Pbppp/2p5/8/2B5/8/PPP1NnPP/RNBQK2R w KQ - 1 8"
- - - - - - - - - - - -
- - - - - - - - - - - -
- - r n b q . k . r - -
- - p p . P b p p p - -
- - . . p . . . . . - -
- - . . . . . . . . - -
- - . . B . . . . . - -
- - . . . . . . . . - -
- - P P P . N n P P - -
- - R N B Q K . . R - -
- - - - - - - - - - - -
- - - - - - - - - - - -
Quick Perft by H.G. Muller
Perft mode: No hashing, bulk counting in horizon nodes
2. e1g1 moves = 1376 ( 0.000 sec)
2. h2h3 moves = 1371 ( 0.000 sec)
2. h2h4 moves = 1402 ( 0.000 sec)
2. g2g3 moves = 1308 ( 0.000 sec)
2. g2g4 moves = 1337 ( 0.000 sec)
2. c2c3 moves = 1440 ( 0.000 sec)
2. b2b3 moves = 1368 ( 0.000 sec)
2. b2b4 moves = 1398 ( 0.000 sec)
2. a2a3 moves = 1373 ( 0.000 sec)
2. a2a4 moves = 1433 ( 0.016 sec)
2. d7c8 moves = 1459 ( 0.000 sec)
2. d7c8 moves = 1296 ( 0.000 sec)
2. d7c8 moves = 1668 ( 0.000 sec)
2. d7c8 moves = 1607 ( 0.000 sec)
2. b1a3 moves = 1303 ( 0.000 sec)
2. b1c3 moves = 1467 ( 0.000 sec)
2. b1d2 moves = 1174 ( 0.000 sec)
2. e2c3 moves = 1595 ( 0.000 sec)
2. e2d4 moves = 1554 ( 0.000 sec)
2. e2f4 moves = 1555 ( 0.000 sec)
2. e2g3 moves = 1523 ( 0.000 sec)
2. e2g1 moves = 1431 ( 0.000 sec)
2. c4b5 moves = 1332 ( 0.000 sec)
2. c4a6 moves = 1256 ( 0.000 sec)
2. c4d3 moves = 1269 ( 0.000 sec)
2. c4d5 moves = 1375 ( 0.000 sec)
2. c4e6 moves = 1438 ( 0.000 sec)
2. c4f7 moves = 1328 ( 0.000 sec)
2. c4b3 moves = 1275 ( 0.000 sec)
2. c1d2 moves = 1368 ( 0.000 sec)
2. c1e3 moves = 1587 ( 0.000 sec)
2. c1f4 moves = 1552 ( 0.000 sec)
2. c1g5 moves = 1422 ( 0.000 sec)
2. c1h6 moves = 1312 ( 0.000 sec)
2. d1d2 moves = 1436 ( 0.000 sec)
2. d1d3 moves = 1685 ( 0.000 sec)
2. d1d4 moves = 1751 ( 0.000 sec)
2. d1d5 moves = 1688 ( 0.000 sec)
2. d1d6 moves = 1500 ( 0.000 sec)
2. h1g1 moves = 1311 ( 0.000 sec)
2. h1f1 moves = 1364 ( 0.000 sec)
2. e1f1 moves = 1445 ( 0.000 sec)
2. e1f2 moves = 1269 ( 0.000 sec)
2. e1d2 moves = 978 ( 0.000 sec)
perft( 3)= 62379 ( 0.016 sec)
Code: Select all
qperft 3 "H20" "-2" "rnbq1k1r/pp1Pbppp/2p5/8/2B5/8/PPP1NnPP/RNBQK2R w KQ - 1 8"
Hash-table size = fffff, Starts at 4f0040,section = 1ffff
- - - - - - - - - - - -
- - - - - - - - - - - -
- - r n b q . k . r - -
- - p p . P b p p p - -
- - . . p . . . . . - -
- - . . . . . . . . - -
- - . . B . . . . . - -
- - . . . . . . . . - -
- - P P P . N n P P - -
- - R N B Q K . . R - -
- - - - - - - - - - - -
- - - - - - - - - - - -
Quick Perft by H.G. Muller
Perft mode: Hash-table size = 16MB, bulk counting in horizon nodes
2. e1g1 moves = 1376 ( 0.015 sec)
2. h2h3 moves = 1371 ( 0.000 sec)
2. h2h4 moves = 1402 ( 0.000 sec)
2. g2g3 moves = 1308 ( 0.000 sec)
2. g2g4 moves = 1337 ( 0.000 sec)
2. c2c3 moves = 1440 ( 0.000 sec)
2. b2b3 moves = 1368 ( 0.000 sec)
2. b2b4 moves = 1398 ( 0.000 sec)
2. a2a3 moves = 1373 ( 0.000 sec)
2. a2a4 moves = 1433 ( 0.000 sec)
2. d7c8 moves = 1459 ( 0.000 sec)
2. d7c8 moves = 1296 ( 0.000 sec)
2. d7c8 moves = 1621 ( 0.000 sec)
2. d7c8 moves = 1621 ( 0.000 sec)
2. b1a3 moves = 1303 ( 0.000 sec)
2. b1c3 moves = 1467 ( 0.000 sec)
2. b1d2 moves = 1174 ( 0.000 sec)
2. e2c3 moves = 1595 ( 0.000 sec)
2. e2d4 moves = 1554 ( 0.000 sec)
2. e2f4 moves = 1555 ( 0.000 sec)
2. e2g3 moves = 1523 ( 0.000 sec)
2. e2g1 moves = 1431 ( 0.000 sec)
2. c4b5 moves = 1332 ( 0.000 sec)
2. c4a6 moves = 1256 ( 0.000 sec)
2. c4d3 moves = 1269 ( 0.000 sec)
2. c4d5 moves = 1375 ( 0.000 sec)
2. c4e6 moves = 1438 ( 0.000 sec)
2. c4f7 moves = 1328 ( 0.000 sec)
2. c4b3 moves = 1275 ( 0.000 sec)
2. c1d2 moves = 1368 ( 0.000 sec)
2. c1e3 moves = 1587 ( 0.000 sec)
2. c1f4 moves = 1552 ( 0.000 sec)
2. c1g5 moves = 1422 ( 0.000 sec)
2. c1h6 moves = 1312 ( 0.000 sec)
2. d1d2 moves = 1436 ( 0.000 sec)
2. d1d3 moves = 1685 ( 0.000 sec)
2. d1d4 moves = 1751 ( 0.000 sec)
2. d1d5 moves = 1688 ( 0.000 sec)
2. d1d6 moves = 1500 ( 0.000 sec)
2. h1g1 moves = 1311 ( 0.000 sec)
2. h1f1 moves = 1364 ( 0.000 sec)
2. e1f1 moves = 1445 ( 0.000 sec)
2. e1f2 moves = 1269 ( 0.000 sec)
2. e1d2 moves = 978 ( 0.000 sec)
perft( 3)= 62346 ( 0.015 sec)
Code: Select all
JetChess 1.0.0.0 (64 MB of hash):
rnbq1k1r/pp1Pbppp/2p5/8/2B5/8/PPP1NnPP/RNBQK2R w KQ - 1 8
1 Qd1-d2 1436
2 Qd1-d3 1685
3 Qd1-d4 1751
4 Qd1-d5 1688
5 Qd1-d6 1500
6 Rh1-g1 1311
7 Rh1-f1 1364
8 Bc1-d2 1368
9 Bc1-e3 1587
10 Bc1-f4 1552
11 Bc1-g5 1422
12 Bc1-h6 1312
13 Bc4-b5 1332
14 Bc4-a6 1256
15 Bc4-d5 1375
16 Bc4-e6 1438
17 Bc4*f7 1328
18 Bc4-d3 1269
19 Bc4-b3 1275
20 Nb1-a3 1303
21 Nb1-c3 1467
22 Nb1-d2 1174
23 Ne2-c3 1595
24 Ne2-d4 1554
25 Ne2-f4 1555
26 Ne2-g3 1523
27 Ne2-g1 1431
28 a2-a3 1373
29 a2-a4 1433
30 b2-b3 1368
31 b2-b4 1398
32 c2-c3 1440
33 g2-g3 1308
34 g2-g4 1337
35 h2-h3 1371
36 h2-h4 1402
37 d7*c8Q 1459
38 d7*c8N 1607
39 d7*c8R 1296
40 d7*c8B 1668
41 0-0 1376
42 Ke1-f1 1445
43 Ke1-d2 978
44 Ke1*f2 1269
Total: 62379
62,379 (move pathes after 3 half moves).
Time: 1 ms (0:00:00.001).
Code: Select all
OliPerft -3 "rnbq1k1r/pp1Pbppp/2p5/8/2B5/8/PPP1NnPP/RNBQK2R w KQ - 1 8"
r n b q . k . r
p p . P b p p p
. . p . . . . .
. . . . . . . .
. . B . . . . .
. . . . . . . .
P P P . N n P P
R N B Q K . . R
Ke1xf2: 1269
Ke1-f1: 1445
Ke1-d2: 978
Pa2-a3: 1373
Pa2-a4: 1433
Pb2-b3: 1368
Pb2-b4: 1398
Pc2-c3: 1440
Pg2-g3: 1308
Pg2-g4: 1337
Ph2-h3: 1371
Ph2-h4: 1402
Pd7xc8q: 1459
Pd7xc8n: 1607
Pd7xc8r: 1296
Pd7xc8b: 1668
Nb1-d2: 1174
Nb1-a3: 1303
Nb1-c3: 1467
Ne2-g1: 1431
Ne2-c3: 1595
Ne2-g3: 1523
Ne2-d4: 1554
Ne2-f4: 1555
Rh1-f1: 1364
Rh1-g1: 1311
Ke1-g1: 1376
Bc1-d2: 1368
Bc1-e3: 1587
Bc1-f4: 1552
Bc1-g5: 1422
Bc1-h6: 1312
Bc4xf7: 1328
Bc4-b3: 1275
Bc4-d3: 1269
Bc4-b5: 1332
Bc4-d5: 1375
Bc4-a6: 1256
Bc4-e6: 1438
Qd1-d2: 1436
Qd1-d3: 1685
Qd1-d4: 1751
Qd1-d5: 1688
Qd1-d6: 1500
Nodes: 62379 cs: 0 knps: 62379
Code: Select all
FireBird 1.1 w32
by Kranium and Sentinel
based on IppoLit
Compiled by KLO
Feb 15 2010 11:59:18
position fen rnbq1k1r/pp1Pbppp/2p5/8/2B5/8/PPP1NnPP/RNBQK2R w KQ - 1 8
perft 3
+---+---+---+---+---+---+---+---+
8 |<R>|<N>|<B>|<Q>| |<K>| |<R>|
+---+---+---+---+---+---+---+---+
7 |<P>|<P>| . | P |<B>|<P>|<P>|<P>|
+---+---+---+---+---+---+---+---+
6 | | . |<P>| . | | . | | . |
+---+---+---+---+---+---+---+---+
5 | . | | . | | . | | . | |
+---+---+---+---+---+---+---+---+
4 | | . | B | . | | . | | . |
+---+---+---+---+---+---+---+---+
3 | . | | . | | . | | . | |
+---+---+---+---+---+---+---+---+
2 | P | P | P | . | N |<N>| P | P |
+---+---+---+---+---+---+---+---+
1 | R | N | B | Q | K | | . | R |
+---+---+---+---+---+---+---+---+
a b c d e f g h
rnbq1k1r/pp1Pbppp/2p5/8/2B5/8/PPP1NnPP/RNBQK2R w KQ - 1 0
c4f7 1328/32
e1f2 1269/28
d7c8q 1459/31
e1g1 1376/34
a2a4 1433/34
a2a3 1373/34
b2b4 1398/33
b2b3 1368/34
c2c3 1440/34
g2g4 1337/34
g2g3 1308/34
h2h4 1402/34
h2h3 1371/34
d1d2 1436/34
d1d3 1685/34
d1d4 1751/34
d1d5 1688/35
d1d6 1500/28
h1f1 1364/34
h1g1 1311/34
c1d2 1368/34
c1e3 1587/34
c1f4 1552/34
c1g5 1422/32
c1h6 1312/31
c4b3 1275/34
c4d3 1269/34
c4b5 1332/34
c4d5 1375/35
c4a6 1256/33
c4e6 1438/35
e1f1 1445/34
e1d2 978/34
b1d2 1174/34
b1a3 1303/34
b1c3 1467/34
e2g1 1431/34
e2c3 1595/34
e2g3 1523/34
e2d4 1554/34
e2f4 1555/34
d7c8n 1607/41
d7c8r 1296/31
d7c8b 1668/41
TOTAL 62379 moves 44 time: 47000 us
Thanks to Julien for providing a position where low plies are enough to see the differences in perft. I suppose that this issue in move generation is not worth a new bugfix version of Prédateur (2.2.2, 2.2.1.1, 2.2.1a...).
When I tested the original position (Perft(7)), I expected that it will be a tricky one due to white castle kingside; I could not expect that the problems will be in black side! Curious...
Just trying to help a little: the order of promotions in qperft is {Q, R, B, N} or {Q, R, N, B} (I suppose the first), but it will be good that Muller could specify it in the output (for example: d7c8q, d7c8r, ...). The only errors are in bishop and knight underpromotions when hash is used in this Perft(3) test.
Congrats to the people that posted here (their results were right, good job!). Also thanks for pointing out the problem: the hash issue.
@Muller: Thank you very much for qperft: it is my second favourite public available dedicated perft programme (after JetChess) due to its speed and the posibility of using hash, which speeds up the run. Good job!
@Julien: I am glad that I have contributed in a modest way to fix your almost perfect move generator. I agree with you: some positions of this topic should be added to any wiki because they will be surely useful for newbie programmers that are starting their move generators. Congratulations and good luck being moderator.
Regards from Spain.
Ajedrecista.