How to iterate over all FENs in Syzygy table? This is a programming question related to chess syzygy endgame tables. I believe that it is better suited on chess stack exchange than on SO because it is too specific to chess and asks for a recommendation. Also I noticed that there are enough people with a lot of programming knowledge here.



I have a syzygy WDL endgame table (just for example I uploaded the file KPPPPvK.rtbw) and for my own purposes I need to iterate over all FENs in this table and see the results for each position.

Is there a library (preferably with python interface) to do this? Most of the libraries that I have seen so far only allows to probe a table.
To my knowledge the Syzygy tablebase doesn't have a function that magically returns all FEN positions from a file. I don't think it should because that's not what tablebase is designed for.

However, there's nothing stopping you from constructing all possible FENs. You know from the file name you have four pawns in the endgame. All you need to is:


Use python-chess package
Generate all possible FENs
For each FEN, use the Python package for probing


Please take a look at:


  http://talkchess.com/forum/viewtopic.php?start=0&amp;t=61003&amp;topic_view=flat


for FEN generation. Sven Schüle is an experienced engine programmer, so please study his code and adjust it if necessary.

// Usage example: fengen.exe [-m|--mirror] Q r n 2p 
// See http://www.talkchess.com/forum/viewtopic.php?t=61003 
#include &lt;cstdio&gt; 
#include &lt;cstdlib&gt; 
#include &lt;cstring&gt; 
#include &lt;cctype&gt; 
#include &lt;algorithm&gt; 
#include &lt;vector&gt; 

// definitions for chess board representation 

typedef int Color; 
enum { White = 0, Black, Empty }; 

typedef int Piece; 
enum { NoPiece = 0, Pawn, Knight, Bishop, Rook, Queen, King }; 

typedef int Square; 
enum { 
    A1 = 0,B1,C1,D1,E1,F1,G1,H1, 
    A2,    B2,C2,D2,E2,F2,G2,H2, 
    A3,    B3,C3,D3,E3,F3,G3,H3, 
    A4,    B4,C4,D4,E4,F4,G4,H4, 
    A5,    B5,C5,D5,E5,F5,G5,H5, 
    A6,    B6,C6,D6,E6,F6,G6,H6, 
    A7,    B7,C7,D7,E7,F7,G7,H7, 
    A8,    B8,C8,D8,E8,F8,G8,H8, 
    FF = 0xff 
}; 

Color opponent(Color c) { return c ^ Black; } 
Square makeSquare(int file, int rank) { return 8 * rank + file; } 

struct Board { 
    Color   color[64]; 
    Piece   piece[64]; 
    bool isPiece(Square s, Color c, Piece p) const { return color[s] == c &amp;&amp; piece[s] == p; } 
    void set(Square s, Color c, Piece p) { color[s] = c; piece[s] = p; } 
    void clear(Square s) { set(s, Empty, NoPiece); } 
    Board() { for (Square s = A1; s &lt;= H8; s++) clear(s); } 

    void printFEN() 
    { 
        int nEmpty = 0; 
        for (int r = 7; r &gt;= 0; r--) { 
            for (int f = 0; f &lt;= 7; f++) { 
                Square s = makeSquare(f, r); 
                if (color[s] == Empty) { 
                    ++nEmpty; 
                } else { 
                    if (nEmpty &gt; 0) { 
                        fputc('1' + nEmpty - 1, stdout); 
                        nEmpty = 0; 
                    } 
                    static char const pieceSym[] = ".pnbrqk"; 
                    if (color[s] == White) { 
                        fputc(toupper(pieceSym[piece[s]]), stdout); 
                    } else { 
                        fputc(tolower(pieceSym[piece[s]]), stdout); 
                    } 
                    nEmpty = 0; 
                } 
            } 
            if (r &gt; 0) { 
                if (nEmpty &gt; 0) { 
                    fputc('1' + nEmpty - 1, stdout); 
                    nEmpty = 0; 
                } 
                fputc('/', stdout); 
            } 
        } 
        fputs(" w ", stdout); 
        if (isPiece(E1, White, King) &amp;&amp; isPiece(H1, White, Rook)) fputc('K', stdout); 
        if (isPiece(E1, White, King) &amp;&amp; isPiece(A1, White, Rook)) fputc('Q', stdout); 
        if (isPiece(E8, Black, King) &amp;&amp; isPiece(H8, Black, Rook)) fputc('k', stdout); 
        if (isPiece(E8, Black, King) &amp;&amp; isPiece(A8, Black, Rook)) fputc('q', stdout); 
        fputs(" - 0 1\n", stdout); 
    } 
}; 

// definitions needed to set up the initial position 
// usually more simple than that but we need to iterate over each group of pieces of same type 

struct PieceInitDescr { 
    int     nPieces; 
    Square  initSqr[8]; 
}; 

PieceInitDescr pieceInitDescr[2][1+6] = { 
    { 
        { 0, { FF,FF,FF,FF,FF,FF,FF,FF } }, 
        { 8, { A2,B2,C2,D2,E2,F2,G2,H2 } }, 
        { 2, { B1,G1,FF,FF,FF,FF,FF,FF } }, 
        { 2, { C1,F1,FF,FF,FF,FF,FF,FF } }, 
        { 2, { A1,H1,FF,FF,FF,FF,FF,FF } }, 
        { 1, { D1,FF,FF,FF,FF,FF,FF,FF } }, 
        { 1, { E1,FF,FF,FF,FF,FF,FF,FF } }, 
    }, 
    { 
        { 0, { FF,FF,FF,FF,FF,FF,FF,FF } }, 
        { 8, { A7,B7,C7,D7,E7,F7,G7,H7 } }, 
        { 2, { B8,G8,FF,FF,FF,FF,FF,FF } }, 
        { 2, { C8,F8,FF,FF,FF,FF,FF,FF } }, 
        { 2, { A8,H8,FF,FF,FF,FF,FF,FF } }, 
        { 1, { D8,FF,FF,FF,FF,FF,FF,FF } }, 
        { 1, { E8,FF,FF,FF,FF,FF,FF,FF } }, 
    }, 
}; 

// data related to command line parameters 

int missing[2][1+6] = { 
    { 0, 0, 0, 0, 0, 0, 0 }, 
    { 0, 0, 0, 0, 0, 0, 0 }, 
}; 

bool mirror = false; 

template &lt;bool Mirror&gt; 
void enumerate(Board &amp; b, Color c, Piece p) 
{ 
    Color cMiss = (Mirror ? opponent(c) : c); 
    Color cStop = (Mirror ? White : Black); 

    PieceInitDescr const &amp; d = pieceInitDescr[c][p]; 

    // setup initial pieces of given color and type 
    for (int i = 0; i &lt; d.nPieces; i++) { 
        b.set(d.initSqr[i], c, p); 
    } 

    if (p == King &amp;&amp; c == cStop) { 
        b.printFEN(); 
    } else { 
        // generate all permutations of missing pieces for the given color and piece type 
        int nPresent = d.nPieces - missing[cMiss][p]; 
        std::vector&lt;bool&gt; v(d.nPieces); 
        std::fill(v.end() - nPresent, v.end(), true); 
        do { 
            // remove missing pieces 
            for (int i = 0; i &lt; d.nPieces; i++) { 
                if (!v[i]) { 
                    b.clear(d.initSqr[i]); 
                } 
            } 
            // recursive call 
            Color cNext = (p == King) ? opponent(c) : c; 
            Piece pNext = (p == King) ? Pawn : p + 1; 
            enumerate&lt;Mirror&gt;(b, cNext, pNext); 
            // restore removed pieces 
            for (int i = 0; i &lt; d.nPieces; i++) { 
                if (!v[i]) { 
                    b.set(d.initSqr[i], c, p); 
                } 
            } 
        } while (std::next_permutation(v.begin(), v.end())); 
    } 

    // clear initial pieces 
    for (int i = 0; i &lt; d.nPieces; i++) { 
        b.clear(d.initSqr[i]); 
    } 
} 

int main(int argc, char * argv[]) 
{ 
    // scan parameters (illegal parameters are ignored for simplicity) 
    for (int i = 1; i &lt; argc; i++) { 
        char const * arg = argv[i]; 
        if (strcmp(arg, "-m") == 0 || strcmp(arg, "--mirror") == 0) { 
            mirror = true; 
        } else 
        if (strlen(arg) &lt;= 2) { 
            int number  = (strlen(arg) == 1) ? 1         : arg[0] + 1 - '1'; 
            char p      = (strlen(arg) == 1) ? arg[0]    : arg[1]; 
            Color color = (p == toupper(p)) ? White : Black; 
            Piece piece = NoPiece; 
            switch (tolower(p)) { 
                case 'p': piece = Pawn;     break; 
                case 'n': piece = Knight;   break; 
                case 'b': piece = Bishop;   break; 
                case 'r': piece = Rook;     break; 
                case 'q': piece = Queen;    break; 
                // king must not be missing 
                default: break; 
            } 
            if (piece != NoPiece &amp;&amp; number &gt;= 1 &amp;&amp; number &lt;= pieceInitDescr[color][piece].nPieces) { 
                missing[color][piece] = number; 
            } 
        } 
    } 

    // enumerate combinations of missing pieces 
    Board b; 
    enumerate&lt;false&gt;(b, White, Pawn); 
    if (mirror) { 
        enumerate&lt;true&gt;(b, Black, Pawn); 
    } 
    return 0; 
}