Does something like a conditional fen generator exist? A quick research revealed nothing.
Let's say as an example, you would be interested in all FENs with one side has 2P + 1R + 1N removed and the other its Q removed and this tool would generate all possible FENs with that combination.
My count is that there should be 28*4*2 combinations = 224 positions in this case. (28 = pawn tuples, 4 = R/N tuples, 2 = colour mirroring)
Guenther
Conditional FEN generator?
Moderator: Ras
-
Guenther
- Posts: 4718
- Joined: Wed Oct 01, 2008 6:33 am
- Location: Regensburg, Germany
- Full name: Guenther Simon
-
Sven
- Posts: 4052
- Joined: Thu May 15, 2008 9:57 pm
- Location: Berlin, Germany
- Full name: Sven Schüle
Re: Conditional FEN generator?
You don't really mean FEN's (which are representing concrete positions on the board) but combinations of present material, do you? There are certainly some orders of magnitude between "224" and the number of different positions with, say, six white pawns on the board (to take only a small part of the material from your example).Guenther wrote:Does something like a conditional fen generator exist? A quick research revealed nothing.
Let's say as an example, you would be interested in all FENs with one side has 2P + 1R + 1N removed and the other its Q removed and this tool would generate all possible FENs with that combination.
My count is that there should be 28*4*2 combinations = 224 positions in this case. (28 = pawn tuples, 4 = R/N tuples, 2 = colour mirroring)
Guenther
-
Guenther
- Posts: 4718
- Joined: Wed Oct 01, 2008 6:33 am
- Location: Regensburg, Germany
- Full name: Guenther Simon
Re: Conditional FEN generator?
Hmmm, I see there is a missunderstanding, I meant what I said, which isSven Schüle wrote:You don't really mean FEN's (which are representing concrete positions on the board) but combinations of present material, do you? There are certainly some orders of magnitude between "224" and the number of different positions with, say, six white pawns on the board (to take only a small part of the material from your example).Guenther wrote:Does something like a conditional fen generator exist? A quick research revealed nothing.
Let's say as an example, you would be interested in all FENs with one side has 2P + 1R + 1N removed and the other its Q removed and this tool would generate all possible FENs with that combination.
My count is that there should be 28*4*2 combinations = 224 positions in this case. (28 = pawn tuples, 4 = R/N tuples, 2 = colour mirroring)
Guenther
all possible FENs with the given material conditions, BUT only for the starting position.
Somehow I wrongly thought that would be clear, no idea why.
Thus the first FENs would be like this (systematically) for my given example: 28 (pawn formations) * 4 (R/N variations) * 2 (colour change)
Code: Select all
rnb1kbnr/pppppppp/8/8/8/8/2PPPPPP/2BQKBNR w Kkq - 0 1
rnb1kbnr/pppppppp/8/8/8/8/1P1PPPPP/2BQKBNR w Kkq - 0 1
rnb1kbnr/pppppppp/8/8/8/8/1PP1PPPP/2BQKBNR w Kkq - 0 1
rnb1kbnr/pppppppp/8/8/8/8/1PPP1PPP/2BQKBNR w Kkq - 0 1
rnb1kbnr/pppppppp/8/8/8/8/1PPPP1PP/2BQKBNR w Kkq - 0 1
rnb1kbnr/pppppppp/8/8/8/8/1PPPPP1P/2BQKBNR w Kkq - 0 1
rnb1kbnr/pppppppp/8/8/8/8/1PPPPPP1/2BQKBNR w Kkq - 0 1
rnb1kbnr/pppppppp/8/8/8/8/P2PPPPP/2BQKBNR w Kkq - 0 1
rnb1kbnr/pppppppp/8/8/8/8/P1P1PPPP/2BQKBNR w Kkq - 0 1
rnb1kbnr/pppppppp/8/8/8/8/P1PP1PPP/2BQKBNR w Kkq - 0 1
rnb1kbnr/pppppppp/8/8/8/8/P1PPP1PP/2BQKBNR w Kkq - 0 1
rnb1kbnr/pppppppp/8/8/8/8/P1PPPP1P/2BQKBNR w Kkq - 0 1
rnb1kbnr/pppppppp/8/8/8/8/P1PPPPP1/2BQKBNR w Kkq - 0 1
rnb1kbnr/pppppppp/8/8/8/8/PP2PPPP/2BQKBNR w Kkq - 0 1
rnb1kbnr/pppppppp/8/8/8/8/PP1P1PPP/2BQKBNR w Kkq - 0 1
rnb1kbnr/pppppppp/8/8/8/8/PP1PP1PP/2BQKBNR w Kkq - 0 1
rnb1kbnr/pppppppp/8/8/8/8/PP1PPP1P/2BQKBNR w Kkq - 0 1
rnb1kbnr/pppppppp/8/8/8/8/PP1PPPP1/2BQKBNR w Kkq - 0 1
...-
Sven
- Posts: 4052
- Joined: Thu May 15, 2008 9:57 pm
- Location: Berlin, Germany
- Full name: Sven Schüle
Re: Conditional FEN generator?
Now I understand. I don't know whether such a tool exists. So what would be the exact input parameters for that tool?
-
Guenther
- Posts: 4718
- Joined: Wed Oct 01, 2008 6:33 am
- Location: Regensburg, Germany
- Full name: Guenther Simon
Re: Conditional FEN generator?
At least for me it would be only the piece(s) which could be removed from each side from the starting position (except the Kings of course) and then iterating all FENs which have that material amount and a colour mirroring trigger.Sven Schüle wrote:Now I understand. I don't know whether such a tool exists. So what would be the exact input parameters for that tool?
It does not need to have an UI - let's say I just give input from the commandline and it asks for W and I just type what to remove for the
possible type of pieces and the same for B or something similar.
e.g. Q 2R 2B 2N 8P as max input for removing from one side, just as an idea, or even for both sides at once like Q r n 2p (original example)
with lowercase for Black and uppercase for White removing pieces... but that's just an implementation detail.
Colour mirroring would then just create the FENs for q R N 2P removed instead.
Guenther
-
Sven
- Posts: 4052
- Joined: Thu May 15, 2008 9:57 pm
- Location: Berlin, Germany
- Full name: Sven Schüle
Re: Conditional FEN generator?
I could send you a Windows executable for testing if you PM me your mail address. The C++ source code (compiled with old VS2010 express) has exactly 200 lines for which I needed exactly 2 hours
If anyone is interested I can also post the source code here.
-
Guenther
- Posts: 4718
- Joined: Wed Oct 01, 2008 6:33 am
- Location: Regensburg, Germany
- Full name: Guenther Simon
Re: Conditional FEN generator?
Sven, thanks for the effort I will PM you.Sven Schüle wrote:I could send you a Windows executable for testing if you PM me your mail address. The C++ source code (compiled with old VS2010 express) has exactly 200 lines for which I needed exactly 2 hours :-) If anyone is interested I can also post the source code here.
Guenther
-
Sven
- Posts: 4052
- Joined: Thu May 15, 2008 9:57 pm
- Location: Berlin, Germany
- Full name: Sven Schüle
Re: Conditional FEN generator?
Maybe this is the highest possible number of FENs here:
Code: Select all
fengen.exe -m R B N 4P r b n 4p | wc -l
627200-
Ajedrecista
- Posts: 2215
- Joined: Wed Jul 13, 2011 9:04 pm
- Location: Madrid, Spain.
Re: Conditional FEN generator?
Hello Sven:
The availability of the source code would be great! 200 lines seem a smart coding.
Thank you in advance.
Regards from Spain.
Ajedrecista.
I would add that 0, 1 and 2 queens OTB (not only two) make the same number of 627200 possibilities.Sven Schüle wrote:Maybe this is the highest possible number of FENs here:Code: Select all
fengen.exe -m R B N 4P r b n 4p | wc -l 627200
The availability of the source code would be great! 200 lines seem a smart coding.
Thank you in advance.
Regards from Spain.
Ajedrecista.
-
Sven
- Posts: 4052
- Joined: Thu May 15, 2008 9:57 pm
- Location: Berlin, Germany
- Full name: Sven Schüle
Re: Conditional FEN generator?
Ajedrecista wrote:The availability of the source code would be great!
Code: Select all
// Usage example: fengen.exe [-m|--mirror] Q r n 2p
// See http://www.talkchess.com/forum/viewtopic.php?t=61003
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cctype>
#include <algorithm>
#include <vector>
// 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 && 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 <= H8; s++) clear(s); }
void printFEN()
{
int nEmpty = 0;
for (int r = 7; r >= 0; r--) {
for (int f = 0; f <= 7; f++) {
Square s = makeSquare(f, r);
if (color[s] == Empty) {
++nEmpty;
} else {
if (nEmpty > 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 > 0) {
if (nEmpty > 0) {
fputc('1' + nEmpty - 1, stdout);
nEmpty = 0;
}
fputc('/', stdout);
}
}
fputs(" w ", stdout);
if (isPiece(E1, White, King) && isPiece(H1, White, Rook)) fputc('K', stdout);
if (isPiece(E1, White, King) && isPiece(A1, White, Rook)) fputc('Q', stdout);
if (isPiece(E8, Black, King) && isPiece(H8, Black, Rook)) fputc('k', stdout);
if (isPiece(E8, Black, King) && 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 <bool Mirror>
void enumerate(Board & b, Color c, Piece p)
{
Color cMiss = (Mirror ? opponent(c) : c);
Color cStop = (Mirror ? White : Black);
PieceInitDescr const & d = pieceInitDescr[c][p];
// setup initial pieces of given color and type
for (int i = 0; i < d.nPieces; i++) {
b.set(d.initSqr[i], c, p);
}
if (p == King && 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<bool> v(d.nPieces);
std::fill(v.end() - nPresent, v.end(), true);
do {
// remove missing pieces
for (int i = 0; i < 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<Mirror>(b, cNext, pNext);
// restore removed pieces
for (int i = 0; i < 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 < 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 < argc; i++) {
char const * arg = argv[i];
if (strcmp(arg, "-m") == 0 || strcmp(arg, "--mirror") == 0) {
mirror = true;
} else
if (strlen(arg) <= 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 && number >= 1 && number <= pieceInitDescr[color][piece].nPieces) {
missing[color][piece] = number;
}
}
}
// enumerate combinations of missing pieces
Board b;
enumerate<false>(b, White, Pawn);
if (mirror) {
enumerate<true>(b, Black, Pawn);
}
return 0;
}