Place to find correct perft result from a fen position

Discussion of chess software programming and technical issues.

Moderators: hgm, Rebel, chrisw

Terje
Posts: 347
Joined: Tue Nov 19, 2019 4:34 am
Location: https://github.com/TerjeKir/weiss
Full name: Terje Kirstihagen

Re: Place to find correct perft result from a fen position

Post by Terje »

https://github.com/TerjeKir/EngineTests

You can use the python script here to test your engine's perft, runs on 127 positions with correct counts. It prints any fen you fail, and you can modify it to use any file you like (the 6000+ positions from elcabesa for example), choose depth etc.
Ferdy
Posts: 4833
Joined: Sun Aug 10, 2008 3:15 pm
Location: Philippines

Re: Place to find correct perft result from a fen position

Post by Ferdy »

eligolf wrote: Fri Nov 20, 2020 3:44 pm Thank you H.G.

I am wondering because I get the correct results from all cases on https://www.chessprogramming.org/Perft_Results. But when I try to run some other cases that I found from random people online, e.g. the first answer here http://talkchess.com/forum3/viewtopic.php?t=59046, I get lots of bad results. So I am wondering if these might be wrong, or if my code is wrong? It is especially the promotion and checkmate/stalemate cases that I get some strange results from.

I also wonder what the rules are for stalemate. Is it stalemate immediately when material is wrong with promotion, or do black have to move out of check or something? I mean, I get the wrong result for even an easy position as below. I try it human vs human with takebacks and all looks fine, until I try with perft. [d]K1k5/8/P7/8/8/8/8/8 w - - 0 1
Which claims to be 2217 nodes at depth 6, but I get 2015 (for both black and white to move first). Is my code wrong, or are these random FENs I found online wrong? :)
stalemate is when the stm (side to move) has no legal move and the king of stm is not under attack.

Tried to add promotions other than queen and add fen reader. I got this perft 6.

Code: Select all

affinity_chess

FF  FF  FF  FF  FF  FF  FF  FF  FF  FF
FF  FF  FF  FF  FF  FF  FF  FF  FF  FF
FF  wK  --  bK  --  --  --  --  --  FF
FF  --  --  --  --  --  --  --  --  FF
FF  wp  --  --  --  --  --  --  --  FF
FF  --  --  --  --  --  --  --  --  FF
FF  --  --  --  --  --  --  --  --  FF
FF  --  --  --  --  --  --  --  --  FF
FF  --  --  --  --  --  --  --  --  FF
FF  --  --  --  --  --  --  --  --  FF
FF  FF  FF  FF  FF  FF  FF  FF  FF  FF
FF  FF  FF  FF  FF  FF  FF  FF  FF  FF

K1k5/8/P7/8/8/8/8/8 w - - 0 1

a8a7 : 1380
a6a7 : 837
depth: 6, nodes: 2217
Tried to run the perft from elcabesa perft.txt, it failed on 27 out of 6752 positions on depth 1 and 2 only.
Some positions where it failed.

Code: Select all

line: r3kb1r/p1p2ppp/2n4n/1p3bq1/P2pp1PP/1PN2P2/2PPP3/R1BQKBNR w KQkq -,26,1166,30119,1307169,34774744,1484852572, status: fail, depth: 2, nodes: 1141, data: 1166
line: r2n3r/1bNk2pp/6P1/pP3p2/3pPqnP/1P1P1p1R/2P3B1/Q1B1bKN1 b - e3,50,1630,76411,2468318,113665410,3693285671, status: fail, depth: 2, nodes: 1632, data: 1630
line: r3kbnr/p3p3/bqnp1p2/1pp4p/1P3p1P/P1PP1N2/3KPPP1/RNQ2B1R w kq -,25,789,20061,630780,16454035,524512877, status: fail, depth: 2, nodes: 765, data: 789
line: rB2kbnr/pb6/1p3q2/5p1P/PpPp4/1Q5N/3PPP1P/RN2KB1R w KQkq -,35,1385,48116,1913479,66836437,2659333292, status: fail, depth: 2, nodes: 1381, data: 1385
line: r3kbnr/p1p2p1p/b3p1p1/1p1pq3/4P1PP/N2B4/P1QPKP2/R1B3R1 w kq -,32,1284,40641,1562977,50184262,1881050419, status: fail, depth: 2, nodes: 1256, data: 1284
line: r3kbnr/2qn2p1/8/pppBpp1P/3P1Pb1/P1P1P3/1P2Q2P/RNB1K1NR w KQkq -,43,1674,67202,2613497,100202988,3920538052, status: fail, depth: 2, nodes: 1635, data: 1674
Try these sample perft routines.

Code: Select all

def print_board(board):
    for i, (k, v) in enumerate(board.items()):
        if (i + 1) % 10 == 0:
            print(f'{v}')
        else:
            print(f'{v}  ', end='')


def sample_perft_divide(gamestate, depth):
    total, cnt = 0, 0

    if depth < 1:
        return 1

    valid_moves = gamestate.get_valid_moves()

    for move in valid_moves:
        fr, to, prom = move[0], move[1], move[2]
        gamestate.make_move(fr, to, prom)

        cnt = sample_perft(gamestate, depth-1)
        total += cnt
        gamestate.unmake_move()

        print(f'from: {fr}, to: {to}, promote: {prom}, nodes: {cnt}')

    return total


def sample_perft(gamestate, depth):
    nodes = 0

    if depth < 1:
        return 1

    valid_moves = gamestate.get_valid_moves()

    for move in valid_moves:
        fr, to, prom = move[0], move[1], move[2]
        gamestate.make_move(fr, to, prom)
        nodes += perft(gamestate, depth - 1)
        gamestate.unmake_move()

    return nodes


def run_perft():
    gamestate = b.GameState()
    depth = 1

    print_board(gamestate.board)
    print()

    # Perft count
    print('Perft count')
    nodes = sample_perft(gamestate, depth)
    print(f'nodes: {nodes}')
    print()

    # Perft divide
    print('Perft divide')
    nodes = sample_perft_divide(gamestate, depth)
    print(f'nodes: {nodes}')
Sample result run from above code.

Code: Select all

FF  FF  FF  FF  FF  FF  FF  FF  FF  FF
FF  FF  FF  FF  FF  FF  FF  FF  FF  FF
FF  bR  bN  bB  bQ  bK  bB  bN  bR  FF
FF  bp  bp  bp  bp  bp  bp  bp  bp  FF
FF  --  --  --  --  --  --  --  --  FF
FF  --  --  --  --  --  --  --  --  FF
FF  --  --  --  --  --  --  --  --  FF
FF  --  --  --  --  --  --  --  --  FF
FF  wp  wp  wp  wp  wp  wp  wp  wp  FF
FF  wR  wN  wB  wQ  wK  wB  wN  wR  FF
FF  FF  FF  FF  FF  FF  FF  FF  FF  FF
FF  FF  FF  FF  FF  FF  FF  FF  FF  FF

Perft count
nodes: 20

Perft divide
from: 81, to: 71, promote: None, nodes: 1
from: 81, to: 61, promote: None, nodes: 1
from: 82, to: 72, promote: None, nodes: 1
from: 82, to: 62, promote: None, nodes: 1
from: 83, to: 73, promote: None, nodes: 1
from: 83, to: 63, promote: None, nodes: 1
from: 84, to: 74, promote: None, nodes: 1
from: 84, to: 64, promote: None, nodes: 1
from: 85, to: 75, promote: None, nodes: 1
from: 85, to: 65, promote: None, nodes: 1
from: 86, to: 76, promote: None, nodes: 1
from: 86, to: 66, promote: None, nodes: 1
from: 87, to: 77, promote: None, nodes: 1
from: 87, to: 67, promote: None, nodes: 1
from: 88, to: 78, promote: None, nodes: 1
from: 88, to: 68, promote: None, nodes: 1
from: 92, to: 71, promote: None, nodes: 1
from: 92, to: 73, promote: None, nodes: 1
from: 97, to: 76, promote: None, nodes: 1
from: 97, to: 78, promote: None, nodes: 1
nodes: 20

User avatar
Ajedrecista
Posts: 1968
Joined: Wed Jul 13, 2011 9:04 pm
Location: Madrid, Spain.

Re: Place to find correct perft result from a FEN position.

Post by Ajedrecista »

Hello Ferdinand:
Ferdy wrote: Sun Nov 22, 2020 3:59 am[...]

Tried to run the perft from elcabesa perft.txt, it failed on 27 out of 6752 positions on depth 1 and 2 only.
Some positions where it failed.

Code: Select all

line: r3kb1r/p1p2ppp/2n4n/1p3bq1/P2pp1PP/1PN2P2/2PPP3/R1BQKBNR w KQkq -,26,1166,30119,1307169,34774744,1484852572, status: fail, depth: 2, nodes: 1141, data: 1166
line: r2n3r/1bNk2pp/6P1/pP3p2/3pPqnP/1P1P1p1R/2P3B1/Q1B1bKN1 b - e3,50,1630,76411,2468318,113665410,3693285671, status: fail, depth: 2, nodes: 1632, data: 1630
line: r3kbnr/p3p3/bqnp1p2/1pp4p/1P3p1P/P1PP1N2/3KPPP1/RNQ2B1R w kq -,25,789,20061,630780,16454035,524512877, status: fail, depth: 2, nodes: 765, data: 789
line: rB2kbnr/pb6/1p3q2/5p1P/PpPp4/1Q5N/3PPP1P/RN2KB1R w KQkq -,35,1385,48116,1913479,66836437,2659333292, status: fail, depth: 2, nodes: 1381, data: 1385
line: r3kbnr/p1p2p1p/b3p1p1/1p1pq3/4P1PP/N2B4/P1QPKP2/R1B3R1 w kq -,32,1284,40641,1562977,50184262,1881050419, status: fail, depth: 2, nodes: 1256, data: 1284
line: r3kbnr/2qn2p1/8/pppBpp1P/3P1Pb1/P1P1P3/1P2Q2P/RNB1K1NR w KQkq -,43,1674,67202,2613497,100202988,3920538052, status: fail, depth: 2, nodes: 1635, data: 1674
[...]
I confirm your results up to perft(6) with the help of JetChess. I also computed perft(7) values:

Code: Select all

r3kb1r/p1p2ppp/2n4n/1p3bq1/P2pp1PP/1PN2P2/2PPP3/R1BQKBNR w KQkq -
perft(7) = 40,667,640,384

r2n3r/1bNk2pp/6P1/pP3p2/3pPqnP/1P1P1p1R/2P3B1/Q1B1bKN1 b - e3
perft(7) = 167,545,699,632

r3kbnr/p3p3/bqnp1p2/1pp4p/1P3p1P/P1PP1N2/3KPPP1/RNQ2B1R w kq -
perft(7) = 14,114,307,381

rB2kbnr/pb6/1p3q2/5p1P/PpPp4/1Q5N/3PPP1P/RN2KB1R w KQkq -
perft(7) = 94,037,467,389

r3kbnr/p1p2p1p/b3p1p1/1p1pq3/4P1PP/N2B4/P1QPKP2/R1B3R1 w kq -
perft(7) = 61,441,578,159

r3kbnr/2qn2p1/8/pppBpp1P/3P1Pb1/P1P1P3/1P2Q2P/RNB1K1NR w KQkq -
perft(7) = 146,035,314,968
Regards from Spain.

Ajedrecista.
elcabesa
Posts: 855
Joined: Sun May 23, 2010 1:32 pm

Re: Place to find correct perft result from a fen position

Post by elcabesa »

Ferdy wrote: Sun Nov 22, 2020 3:59 am Tried to run the perft from elcabesa perft.txt, it failed on 27 out of 6752 positions on depth 1 and 2 only.
Some positions where it failed.

Code: Select all

line: r3kb1r/p1p2ppp/2n4n/1p3bq1/P2pp1PP/1PN2P2/2PPP3/R1BQKBNR w KQkq -,26,1166,30119,1307169,34774744,1484852572, status: fail, depth: 2, nodes: 1141, data: 1166
line: r2n3r/1bNk2pp/6P1/pP3p2/3pPqnP/1P1P1p1R/2P3B1/Q1B1bKN1 b - e3,50,1630,76411,2468318,113665410,3693285671, status: fail, depth: 2, nodes: 1632, data: 1630
line: r3kbnr/p3p3/bqnp1p2/1pp4p/1P3p1P/P1PP1N2/3KPPP1/RNQ2B1R w kq -,25,789,20061,630780,16454035,524512877, status: fail, depth: 2, nodes: 765, data: 789
line: rB2kbnr/pb6/1p3q2/5p1P/PpPp4/1Q5N/3PPP1P/RN2KB1R w KQkq -,35,1385,48116,1913479,66836437,2659333292, status: fail, depth: 2, nodes: 1381, data: 1385
line: r3kbnr/p1p2p1p/b3p1p1/1p1pq3/4P1PP/N2B4/P1QPKP2/R1B3R1 w kq -,32,1284,40641,1562977,50184262,1881050419, status: fail, depth: 2, nodes: 1256, data: 1284
line: r3kbnr/2qn2p1/8/pppBpp1P/3P1Pb1/P1P1P3/1P2Q2P/RNB1K1NR w KQkq -,43,1674,67202,2613497,100202988,3920538052, status: fail, depth: 2, nodes: 1635, data: 1674
I have not understood your sentence, are you saying the number in perft.txt are wrong or that the program XXX is not able to calculate the perft number?
Ferdy
Posts: 4833
Joined: Sun Aug 10, 2008 3:15 pm
Location: Philippines

Re: Place to find correct perft result from a fen position

Post by Ferdy »

elcabesa wrote: Sun Nov 22, 2020 2:35 pm
Ferdy wrote: Sun Nov 22, 2020 3:59 am Tried to run the perft from elcabesa perft.txt, it failed on 27 out of 6752 positions on depth 1 and 2 only.
Some positions where it failed.

Code: Select all

line: r3kb1r/p1p2ppp/2n4n/1p3bq1/P2pp1PP/1PN2P2/2PPP3/R1BQKBNR w KQkq -,26,1166,30119,1307169,34774744,1484852572, status: fail, depth: 2, nodes: 1141, data: 1166
line: r2n3r/1bNk2pp/6P1/pP3p2/3pPqnP/1P1P1p1R/2P3B1/Q1B1bKN1 b - e3,50,1630,76411,2468318,113665410,3693285671, status: fail, depth: 2, nodes: 1632, data: 1630
line: r3kbnr/p3p3/bqnp1p2/1pp4p/1P3p1P/P1PP1N2/3KPPP1/RNQ2B1R w kq -,25,789,20061,630780,16454035,524512877, status: fail, depth: 2, nodes: 765, data: 789
line: rB2kbnr/pb6/1p3q2/5p1P/PpPp4/1Q5N/3PPP1P/RN2KB1R w KQkq -,35,1385,48116,1913479,66836437,2659333292, status: fail, depth: 2, nodes: 1381, data: 1385
line: r3kbnr/p1p2p1p/b3p1p1/1p1pq3/4P1PP/N2B4/P1QPKP2/R1B3R1 w kq -,32,1284,40641,1562977,50184262,1881050419, status: fail, depth: 2, nodes: 1256, data: 1284
line: r3kbnr/2qn2p1/8/pppBpp1P/3P1Pb1/P1P1P3/1P2Q2P/RNB1K1NR w KQkq -,43,1674,67202,2613497,100202988,3920538052, status: fail, depth: 2, nodes: 1635, data: 1674
I have not understood your sentence, are you saying the number in perft.txt are wrong or that the program XXX is not able to calculate the perft number?
There are duplicates in perft.txt, 6752 is the number of unique positions.
Ferdy
Posts: 4833
Joined: Sun Aug 10, 2008 3:15 pm
Location: Philippines

Re: Place to find correct perft result from a fen position

Post by Ferdy »

Correction on one of the perft routines.

From:

Code: Select all

def sample_perft(gamestate, depth):
    nodes = 0

    if depth < 1:
        return 1

    valid_moves = gamestate.get_valid_moves()

    for move in valid_moves:
        fr, to, prom = move[0], move[1], move[2]
        gamestate.make_move(fr, to, prom)
        nodes += perft(gamestate, depth - 1)
        gamestate.unmake_move()

    return nodes
To:

Code: Select all

def sample_perft(gamestate, depth):
    nodes = 0

    if depth < 1:
        return 1

    valid_moves = gamestate.get_valid_moves()

    for move in valid_moves:
        fr, to, prom = move[0], move[1], move[2]
        gamestate.make_move(fr, to, prom)
        nodes += sample_perft(gamestate, depth - 1)
        gamestate.unmake_move()

    return nodes
Ferdy
Posts: 4833
Joined: Sun Aug 10, 2008 3:15 pm
Location: Philippines

Re: Place to find correct perft result from a FEN position.

Post by Ferdy »

Ajedrecista wrote: Sun Nov 22, 2020 12:51 pm Hello Ferdinand:
Ferdy wrote: Sun Nov 22, 2020 3:59 am[...]

Tried to run the perft from elcabesa perft.txt, it failed on 27 out of 6752 positions on depth 1 and 2 only.
Some positions where it failed.

Code: Select all

line: r3kb1r/p1p2ppp/2n4n/1p3bq1/P2pp1PP/1PN2P2/2PPP3/R1BQKBNR w KQkq -,26,1166,30119,1307169,34774744,1484852572, status: fail, depth: 2, nodes: 1141, data: 1166
line: r2n3r/1bNk2pp/6P1/pP3p2/3pPqnP/1P1P1p1R/2P3B1/Q1B1bKN1 b - e3,50,1630,76411,2468318,113665410,3693285671, status: fail, depth: 2, nodes: 1632, data: 1630
line: r3kbnr/p3p3/bqnp1p2/1pp4p/1P3p1P/P1PP1N2/3KPPP1/RNQ2B1R w kq -,25,789,20061,630780,16454035,524512877, status: fail, depth: 2, nodes: 765, data: 789
line: rB2kbnr/pb6/1p3q2/5p1P/PpPp4/1Q5N/3PPP1P/RN2KB1R w KQkq -,35,1385,48116,1913479,66836437,2659333292, status: fail, depth: 2, nodes: 1381, data: 1385
line: r3kbnr/p1p2p1p/b3p1p1/1p1pq3/4P1PP/N2B4/P1QPKP2/R1B3R1 w kq -,32,1284,40641,1562977,50184262,1881050419, status: fail, depth: 2, nodes: 1256, data: 1284
line: r3kbnr/2qn2p1/8/pppBpp1P/3P1Pb1/P1P1P3/1P2Q2P/RNB1K1NR w KQkq -,43,1674,67202,2613497,100202988,3920538052, status: fail, depth: 2, nodes: 1635, data: 1674
[...]
I confirm your results up to perft(6) with the help of JetChess. I also computed perft(7) values:

Code: Select all

r3kb1r/p1p2ppp/2n4n/1p3bq1/P2pp1PP/1PN2P2/2PPP3/R1BQKBNR w KQkq -
perft(7) = 40,667,640,384

r2n3r/1bNk2pp/6P1/pP3p2/3pPqnP/1P1P1p1R/2P3B1/Q1B1bKN1 b - e3
perft(7) = 167,545,699,632

r3kbnr/p3p3/bqnp1p2/1pp4p/1P3p1P/P1PP1N2/3KPPP1/RNQ2B1R w kq -
perft(7) = 14,114,307,381

rB2kbnr/pb6/1p3q2/5p1P/PpPp4/1Q5N/3PPP1P/RN2KB1R w KQkq -
perft(7) = 94,037,467,389

r3kbnr/p1p2p1p/b3p1p1/1p1pq3/4P1PP/N2B4/P1QPKP2/R1B3R1 w kq -
perft(7) = 61,441,578,159

r3kbnr/2qn2p1/8/pppBpp1P/3P1Pb1/P1P1P3/1P2Q2P/RNB1K1NR w KQkq -
perft(7) = 146,035,314,968
Regards from Spain.

Ajedrecista.
Thanks.
elcabesa
Posts: 855
Joined: Sun May 23, 2010 1:32 pm

Re: Place to find correct perft result from a fen position

Post by elcabesa »

Ferdy wrote: Sun Nov 22, 2020 3:49 pm There are duplicates in perft.txt, 6752 is the number of unique positions.
yes, they come from a sampling from a pgn file. so there are duplicates, but it does the work :) it's a good set to check perft
abulmo2
Posts: 433
Joined: Fri Dec 16, 2016 11:04 am
Location: France
Full name: Richard Delorme

Re: Place to find correct perft result from a fen position

Post by abulmo2 »

elcabesa wrote: Fri Nov 20, 2020 4:06 pm
eligolf wrote: Fri Nov 20, 2020 4:02 pm Thank you elca! Are these confirmed to be correct?
I hope so, Vajolet and Stockfish indipendently give the same result on those positions, so I suppose they are confirmed. But I haven't tried counting all the moves using a chessboard :)
My programs amoeba and dumb also agree on the solutions.
Richard Delorme