Page 1 of 1

code to get FRC fen from id number

Posted: Mon Sep 10, 2007 8:40 am
by Uri Blass
seeking frc fen from id number

You will probably have better code than my code to get frc fen from id number but here is my code

Note that setup is external function that I use for fen so my code does not return a string but simply use it in another function.

Here is my code(I wonder if you can check that I have no bugs)

Code: Select all

static void fenfrc(int id)
{
	char position[256];
	char numfil[8]={0,0,0,0,0,0,0,0};
	int emptyfiles[5]={-1,-1,-1,-1,-1};
	int lightbishfil=(id%4)*2+1;
	int blackbishfil=((id>>2)%4)*2;
	numfil[lightbishfil]='b';
	numfil[blackbishfil]='b';
	int queenfil=((id>>4)%6);
	if (queenfil>=min(lightbishfil,blackbishfil))
		queenfil++;
	if (queenfil>=max(lightbishfil,blackbishfil))
		queenfil++;
	numfil[queenfil]='q';
	int i=0;
	int j=0;
	while (j<5)
	{
		if (numfil[i]==0)
		{
			emptyfiles[j]=i;
			j++;
		}
		i++;
	}
	while (numfil[i]>0)
		i++;
	int knightcode=id/96;
	if (knightcode<=3)
	{
		numfil[emptyfiles[0]]='n';
		numfil[emptyfiles[1+knightcode]]='n';
		if (knightcode==0)
		{
			numfil[emptyfiles[2]]='r';
			numfil[emptyfiles[3]]='k';
			numfil[emptyfiles[4]]='r';
		}
		else
		{
			numfil[emptyfiles[1]]='r';
			if (knightcode==1)
			{
					numfil[emptyfiles[3]]='k';
					numfil[emptyfiles[4]]='r';
			}
			else
			{
				numfil[emptyfiles[2]]='k';
				numfil[emptyfiles[6-knightcode]]='r';
			}
		}
	}
	else
	{
		numfil[emptyfiles[0]]='r';
		if (knightcode<=6)
		{
			numfil[emptyfiles[1]]='n';
			numfil[emptyfiles[knightcode-2]]='n';
			if (knightcode==4)
			{
				numfil[emptyfiles[3]]='k';
				numfil[emptyfiles[4]]='r';
			}
			else
			{
				numfil[emptyfiles[2]]='k';
				numfil[emptyfiles[9-knightcode]]='r';
			}
		}
		else
		{
			numfil[emptyfiles[1]]='k';
			numfil[emptyfiles[2]]='n';
			numfil[emptyfiles[3]]='n';
			numfil[emptyfiles[4]]='n';
			//delete one knight
			numfil[emptyfiles[11-knightcode]]='r';
		}

	}
	char position1[8];
	for (i=0;i<8;i++)
	{
		position[i]=numfil[i];
		position1[i]=numfil[i]+'A'-'a';
		position[8]=0;
		position1[8]=0;
	}

	strncat(position,"/pppppppp/8/8/8/8/PPPPPPPP/",99);
	strncat(position,position1,12);
	strncat(position," w KQkq - 0 1",15);
	setup(position);
}

Re: code to get FRC fen from id number

Posted: Mon Sep 10, 2007 6:34 pm
by Alessandro Scotti
Hi Uri,
very nice, thanks for sharing this!

Re: code to get FRC fen from id number

Posted: Mon Sep 10, 2007 7:42 pm
by pijl
my alternative. It fills an array with all possible FRC starting positions. It is a table based approach, putting position 1 in startFEN[1] etc. IIRC it is much like the method in Reinhard's book.

Code: Select all

const char kingTable[61][8]= {
	"QNNRKR", "NQNRKR", "NNQRKR", "NNRQKR",
	"NNRKQR", "NNRKRQ", "QNRNKR", "NQRNKR",
	"NRQNKR", "NRNQKR", "NRNKQR", "NRNKRQ",
	"QNRKNR", "NQRKNR", "NRQKNR", "NRKQNR",
	"NRKNQR", "NRKNRQ", "QNRKRN", "NQRKRN",
	"NRQKRN", "NRKQRN", "NRKRQN", "NRKRNQ",
	"QRNNKR", "RQNNKR", "RNQNKR", "RNNQKR",
	"RNNKQR", "RNNKRQ", "QRNKNR", "RQNKNR",
	"RNQKNR", "RNKQNR", "RNKNQR", "RNKNRQ",
	"QRNKRN", "RQNKRN", "RNQKRN", "RNKQRN",
	"RNKRQN", "RNKRNQ", "QRKNNR", "RQKNNR",
	"RKQNNR", "RKNQNR", "RKNNQR", "RKNNRQ",
	"QRKNRN", "RQKNRN", "RKQNRN", "RKNQRN",
	"RKNRQN", "RKNRNQ", "QRKRNN", "RQKRNN",
	"RKQRNN", "RKRQNN", "RKRNQN", "RKRNNQ",
	"QNNRKR"
};
const int bishopTable[16]= {
	0xc0, 0x90, 0x84, 0x81, 0x60, 0x30, 0x24, 0x21, 
	0x48, 0x18, 0x0c, 0x09, 0x42, 0x12, 0x06, 0x03
};
	// Calculate Starting positions
	for (n=0; n<=960; n++) {
		int i,j,k;
		int b;
		const char *s;
		char *f;

		i=n>>4;
		j=bishopTable[n&0x0000000f];
		b=128;
		s=kingTable[i];
		f=startFEN[n];
		for (k=1; k<=8; k++) {
			if (b&j) {
				*(f++)='b';
				b>>=1;
				continue;
			}
			*(f++)=tolower(*(s++));
			b>>=1;
		}

		strcpy(f,"/pppppppp/8/8/8/8/PPPPPPPP/");

		i=n>>4;
		j=bishopTable[n&0x0000000f];
		b=128;
		s=kingTable[i];
		f=startFEN[n]+strlen(startFEN[n]);
		for (k=1; k<=8; k++) {
			if (b&j) {
				*(f++)='B';
				b>>=1;
				continue;
			}
			*(f++)=toupper(*(s++));
			b>>=1;
		}

		strcpy(f," w KQkq -");
	}

Re: code to get FRC fen from id number

Posted: Mon Sep 10, 2007 8:15 pm
by smrf
Hi Richard,

after I wrote my book on Chess960 I simplified the method for generating FRC positions to finally fit upon one single page. The Chess Tigers have published this approach on their site as a PDF document:

http://www.chesstigers.de/download/chess960_regeln.pdf

Moreover one could find this flat two table model even at Wikipedia.

If someone would also be interested in 10x8 CRC positions, there is a combined C++ source covering FRC and CRC positions by a unified routine.

Regards, Reinhard.

P.S.: There are routines generating those starting positions in compatible X-FEN, maybe Shredder needs some modifications here, which is not recommended by myself.

Re: code to get FRC fen from id number

Posted: Mon Sep 10, 2007 8:56 pm
by Uri Blass
pijl wrote:my alternative. It fills an array with all possible FRC starting positions. It is a table based approach, putting position 1 in startFEN[1] etc. IIRC it is much like the method in Reinhard's book.

Code: Select all

const char kingTable[61][8]= {
	"QNNRKR", "NQNRKR", "NNQRKR", "NNRQKR",
	"NNRKQR", "NNRKRQ", "QNRNKR", "NQRNKR",
	"NRQNKR", "NRNQKR", "NRNKQR", "NRNKRQ",
	"QNRKNR", "NQRKNR", "NRQKNR", "NRKQNR",
	"NRKNQR", "NRKNRQ", "QNRKRN", "NQRKRN",
	"NRQKRN", "NRKQRN", "NRKRQN", "NRKRNQ",
	"QRNNKR", "RQNNKR", "RNQNKR", "RNNQKR",
	"RNNKQR", "RNNKRQ", "QRNKNR", "RQNKNR",
	"RNQKNR", "RNKQNR", "RNKNQR", "RNKNRQ",
	"QRNKRN", "RQNKRN", "RNQKRN", "RNKQRN",
	"RNKRQN", "RNKRNQ", "QRKNNR", "RQKNNR",
	"RKQNNR", "RKNQNR", "RKNNQR", "RKNNRQ",
	"QRKNRN", "RQKNRN", "RKQNRN", "RKNQRN",
	"RKNRQN", "RKNRNQ", "QRKRNN", "RQKRNN",
	"RKQRNN", "RKRQNN", "RKRNQN", "RKRNNQ",
	"QNNRKR"
};
const int bishopTable[16]= {
	0xc0, 0x90, 0x84, 0x81, 0x60, 0x30, 0x24, 0x21, 
	0x48, 0x18, 0x0c, 0x09, 0x42, 0x12, 0x06, 0x03
};
	// Calculate Starting positions
	for (n=0; n<=960; n++) {
		int i,j,k;
		int b;
		const char *s;
		char *f;

		i=n>>4;
		j=bishopTable[n&0x0000000f];
		b=128;
		s=kingTable[i];
		f=startFEN[n];
		for (k=1; k<=8; k++) {
			if (b&j) {
				*(f++)='b';
				b>>=1;
				continue;
			}
			*(f++)=tolower(*(s++));
			b>>=1;
		}

		strcpy(f,"/pppppppp/8/8/8/8/PPPPPPPP/");

		i=n>>4;
		j=bishopTable[n&0x0000000f];
		b=128;
		s=kingTable[i];
		f=startFEN[n]+strlen(startFEN[n]);
		for (k=1; k<=8; k++) {
			if (b&j) {
				*(f++)='B';
				b>>=1;
				continue;
			}
			*(f++)=toupper(*(s++));
			b>>=1;
		}

		strcpy(f," w KQkq -");
	}
It seems that your code is not correct

I used the following link
http://www.dwheeler.com/essays/Fischer_ ... Chess.html

based on that link id=0 means that there are bishops at files a and b and based on your code there are bishops at files g and h.

Note that startFEN is not defined in your code but I added to your code
definition and initialization of this array as follow:

char * startFEN[960];
for (i=0;i<960;i++)
startFEN="";

Re: code to get FRC fen from id number

Posted: Mon Sep 10, 2007 9:31 pm
by pijl
Uri Blass wrote: based on that link id=0 means that there are bishops at files a and b and based on your code there are bishops at files g and h.

Note that startFEN is not defined in your code but I added to your code
definition and initialization of this array as follow:

char * startFEN[960];
for (i=0;i<960;i++)
startFEN="";

Position 1 is stored in startFEN[1], Position 960 is stored in startFEN[960].
the contents at index 0 are not used.

declaration should be:
char startFEN[961][FENLENGTH];
where I defined FENLENGTH as 80.
Richard.

Re: code to get FRC fen from id number

Posted: Mon Sep 10, 2007 9:47 pm
by Uri Blass
Thanks

I wanted to verify no errors.

It seems that now I get the same fen from my code and your code for every 0<=i<=959 when I only modify one line and add 0 1 that I have in my fen

strcpy(f," w KQkq - 0 1");

Uri