ChessUSA.com TalkChess.com
Hosted by Your Move Chess & Games
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

fen to fen functions
Goto page 1, 2  Next
 
Post new topic       TalkChess.com Forum Index -> Computer Chess Club: Programming and Technical Discussions Threaded
View previous topic :: View next topic  
Author Message
Uri Blass



Joined: 08 Mar 2006
Posts: 6012
Location: Tel-Aviv Israel

PostPosted: Mon May 21, 2007 10:17 am    Post subject: fen to fen functions Reply to topic Reply with quote

I wonder if there is a free program with source that finds symmetric positions of a specific position.

The program simply should get a fen and parameter (same side to move in case that there is no problem because of castling rights or different side to move) and return a symmetric fen

Example:

The program should get the following fen

[D]4k3/8/8/pppppppp/8/8/PPPPPPPP/4K3 w - - 0 1
   ::    :: BK ::    ::
::    ::    ::    ::    
   ::    ::    ::    ::
BP BP BP BP BP BP BP BP
   ::    ::    ::    ::
::    ::    ::    ::    
WP WP WP WP WP WP WP WP
::    ::    WK    ::    


it can return the following fens(when the first is for the same side to move and the second is for different side to move)

[D]3k4/8/8/pppppppp/8/8/PPPPPPPP/3K4 w - - 0 1
   ::    BK    ::    ::
::    ::    ::    ::    
   ::    ::    ::    ::
BP BP BP BP BP BP BP BP
   ::    ::    ::    ::
::    ::    ::    ::    
WP WP WP WP WP WP WP WP
::    :: WK ::    ::    

[D]4k3/pppppppp/8/8/PPPPPPPP/8/8/4K3 b - - 0 1
   ::    :: BK ::    ::
BP BP BP BP BP BP BP BP
   ::    ::    ::    ::
::    ::    ::    ::    
WP WP WP WP WP WP WP WP
::    ::    ::    ::    
   ::    ::    ::    ::
::    ::    WK    ::    
Back to top
View user's profile Send private message
Alessandro Scotti
Guest





PostPosted: Mon May 21, 2007 3:20 pm    Post subject: Re: fen to fen functions Reply to topic Reply with quote

There is some code in Kiwi that does something very similar to what you need, it's in engine.cxx function runEvalSuiteEPD.
Back to top
Reinhard Scharnagl



Joined: 13 Mar 2006
Posts: 468
Location: Munich, Germany

PostPosted: Mon May 21, 2007 5:10 pm    Post subject: Re: fen to fen functions Reply to topic Reply with quote

Hi Uri,

SMIRF has such an edit option, but its source is not free. It changes

[D]4k3/8/8/pppppppp/8/8/PPPPPPPP/4K3 w - - 0 1
   ::    :: BK ::    ::
::    ::    ::    ::    
   ::    ::    ::    ::
BP BP BP BP BP BP BP BP
   ::    ::    ::    ::
::    ::    ::    ::    
WP WP WP WP WP WP WP WP
::    ::    WK    ::    


to

[D]4k3/pppppppp/8/8/PPPPPPPP/8/8/4K3 b - - 0 1
   ::    :: BK ::    ::
BP BP BP BP BP BP BP BP
   ::    ::    ::    ::
::    ::    ::    ::    
WP WP WP WP WP WP WP WP
::    ::    ::    ::    
   ::    ::    ::    ::
::    ::    WK    ::    


And this "switch positions" is working also for Chess960 and 10x8 CRC.

Regards, Reinhard.
Back to top
View user's profile Send private message Visit poster's website
Dann Corbit



Joined: 08 Mar 2006
Posts: 5125
Location: Redmond, WA USA

PostPosted: Mon May 21, 2007 5:48 pm    Post subject: Re: fen to fen functions Reply to topic Reply with quote

Uri Blass wrote:
I wonder if there is a free program with source that finds symmetric positions of a specific position.

The program simply should get a fen and parameter (same side to move in case that there is no problem because of castling rights or different side to move) and return a symmetric fen

Example:

The program should get the following fen

[D]4k3/8/8/pppppppp/8/8/PPPPPPPP/4K3 w - - 0 1
   ::    :: BK ::    ::
::    ::    ::    ::    
   ::    ::    ::    ::
BP BP BP BP BP BP BP BP
   ::    ::    ::    ::
::    ::    ::    ::    
WP WP WP WP WP WP WP WP
::    ::    WK    ::    


it can return the following fens(when the first is for the same side to move and the second is for different side to move)

[D]3k4/8/8/pppppppp/8/8/PPPPPPPP/3K4 w - - 0 1
   ::    BK    ::    ::
::    ::    ::    ::    
   ::    ::    ::    ::
BP BP BP BP BP BP BP BP
   ::    ::    ::    ::
::    ::    ::    ::    
WP WP WP WP WP WP WP WP
::    :: WK ::    ::    

[D]4k3/pppppppp/8/8/PPPPPPPP/8/8/4K3 b - - 0 1
   ::    :: BK ::    ::
BP BP BP BP BP BP BP BP
   ::    ::    ::    ::
::    ::    ::    ::    
WP WP WP WP WP WP WP WP
::    ::    ::    ::    
   ::    ::    ::    ::
::    ::    WK    ::    


There is a visual basic utility written by Les Fernandez that does exactly that.

I can send you a copy if you want, including the source code.
Back to top
View user's profile Send private message Visit poster's website
Uri Blass



Joined: 08 Mar 2006
Posts: 6012
Location: Tel-Aviv Israel

PostPosted: Tue May 22, 2007 1:21 pm    Post subject: Re: fen to fen functions Reply to topic Reply with quote

smrf wrote:
Hi Uri,

SMIRF has such an edit option, but its source is not free. It changes

[D]4k3/8/8/pppppppp/8/8/PPPPPPPP/4K3 w - - 0 1
   ::    :: BK ::    ::
::    ::    ::    ::    
   ::    ::    ::    ::
BP BP BP BP BP BP BP BP
   ::    ::    ::    ::
::    ::    ::    ::    
WP WP WP WP WP WP WP WP
::    ::    WK    ::    


to

[D]4k3/pppppppp/8/8/PPPPPPPP/8/8/4K3 b - - 0 1
   ::    :: BK ::    ::
BP BP BP BP BP BP BP BP
   ::    ::    ::    ::
::    ::    ::    ::    
WP WP WP WP WP WP WP WP
::    ::    ::    ::    
   ::    ::    ::    ::
::    ::    WK    ::    


And this "switch positions" is working also for Chess960 and 10x8 CRC.

Regards, Reinhard.


Note that the function that I asked about is not function that is dependent on the move generator and the same function may be useful for many engines.

It is not an hard task to do it and I will write in C a function that does it by myself.

Uri
Back to top
View user's profile Send private message
Alessandro Scotti
Guest





PostPosted: Tue May 22, 2007 3:46 pm    Post subject: Re: fen to fen functions Reply to topic Reply with quote

Just a wild shot:

Code:

void fen2fen( char * fen, char * buf )
{
    for( char * e = strchr(fen,' ') - 1; e >= fen; e-- ) {
        *buf++ = *e ^ (isalpha(*e) ? 0x20 : 0x00);
    }
    strcpy( buf, strchr(fen,' ') );
}
Back to top
Uri Blass



Joined: 08 Mar 2006
Posts: 6012
Location: Tel-Aviv Israel

PostPosted: Tue May 22, 2007 4:24 pm    Post subject: Re: fen to fen functions Reply to topic Reply with quote

Alessandro Scotti wrote:
Just a wild shot:

Code:

void fen2fen( char * fen, char * buf )
{
    for( char * e = strchr(fen,' ') - 1; e >= fen; e-- ) {
        *buf++ = *e ^ (isalpha(*e) ? 0x20 : 0x00);
    }
    strcpy( buf, strchr(fen,' ') );
}


If I understand correctly you try both to replace the side to move and replace the files of the pieces so a1 goes to h8 in this code.

This code also does not replace the side to move that is part of the fen
and it also is not correct for castling because there are order rules
and you need to write KQkq in this order and kqKQ is not correct fen.

This code is clearly shorter than my code.
I did not know the trick of xoring with 0x20 to make big letters small letters and the opposite.

I wrote so far code only for the case of changing side that is always possible and not for the case of left-right symmetry that may be impossible in case of castling rights(unless you use FRC and not normal chess and in that case left-right symmetry is always possible)

I did not go from the end to the beginning of the string and simply saved an array of strings for every rank of the board when later I used strncat to make from them one string(I have a special function to change one line when I do not need to change the order but only change big letters to small letters and the opposite).

I did not check that your code works but
thanks for sharing your code

I can make my code shorter based on the idea that you gave here but I do not think that it is important.

Uri
Back to top
View user's profile Send private message
Alessandro Scotti
Guest





PostPosted: Tue May 22, 2007 4:46 pm    Post subject: Re: fen to fen functions Reply to topic Reply with quote

Hi Uri,
yes my code only tries to address the easiest scenario and it simply copies anything that follows the board representation. After all I'm not H. G. and there is a limit to what I can do in four lines of code! Wink
I think we could run an informal contest for the:
1) shortest code (but clean and elegant);
2) shortest and trickiest code (anything goes).
Anyone interested?
Back to top
Dann Corbit



Joined: 08 Mar 2006
Posts: 5125
Location: Redmond, WA USA

PostPosted: Tue May 22, 2007 6:33 pm    Post subject: Re: fen to fen functions Reply to topic Reply with quote

Uri Blass wrote:
Alessandro Scotti wrote:
Just a wild shot:

Code:

void fen2fen( char * fen, char * buf )
{
    for( char * e = strchr(fen,' ') - 1; e >= fen; e-- ) {
        *buf++ = *e ^ (isalpha(*e) ? 0x20 : 0x00);
    }
    strcpy( buf, strchr(fen,' ') );
}


If I understand correctly you try both to replace the side to move and replace the files of the pieces so a1 goes to h8 in this code.

This code also does not replace the side to move that is part of the fen
and it also is not correct for castling because there are order rules
and you need to write KQkq in this order and kqKQ is not correct fen.

This code is clearly shorter than my code.
I did not know the trick of xoring with 0x20 to make big letters small letters and the opposite.

I wrote so far code only for the case of changing side that is always possible and not for the case of left-right symmetry that may be impossible in case of castling rights(unless you use FRC and not normal chess and in that case left-right symmetry is always possible)

I did not go from the end to the beginning of the string and simply saved an array of strings for every rank of the board when later I used strncat to make from them one string(I have a special function to change one line when I do not need to change the order but only change big letters to small letters and the opposite).

I did not check that your code works but
thanks for sharing your code

I can make my code shorter based on the idea that you gave here but I do not think that it is important.

Uri


The xor trick relies upon the ASCII character set where 'A' is 0x41 and 'a' is 0x61 up to 'Z' is 0x5A and 'z' is 0x7A.

You can make reversing case more plain with:
foo = isupper(foo) ? tolower(foo) : toupper(foo);

Note that the toupper() and tolower() macros/functions do nothing if the input integer is not an alphabetic letter.
Back to top
View user's profile Send private message Visit poster's website
Uri Blass



Joined: 08 Mar 2006
Posts: 6012
Location: Tel-Aviv Israel

PostPosted: Thu May 24, 2007 12:52 pm    Post subject: Re: fen to fen functions Reply to topic Reply with quote

Alessandro Scotti wrote:
Hi Uri,
yes my code only tries to address the easiest scenario and it simply copies anything that follows the board representation. After all I'm not H. G. and there is a limit to what I can do in four lines of code! Wink
I think we could run an informal contest for the:
1) shortest code (but clean and elegant);
2) shortest and trickiest code (anything goes).
Anyone interested?


No chance in competition
I simply tries to write code that works and I am not a good programmer like you but here is my code.

Note that it does not translate move to make in epd files but only the string of the position

Note that I used your trick of xoring with 0x20 to go from small letters to big letters and the opposite otherwise my code could be longer.

I have a different function to check if the string is legal fen so this certainly can crash on illegal fen.


Code:
char fen1[1024];
char shortfen[10];
char * opp_line(char *rankfen)
{
   strcpy(shortfen,rankfen);
   unsigned int i;
   for (i=0;i<strlen(shortfen);i++)
//   if (shortfen[i]>='a'&&shortfen[i]<='z')
//      shortfen[i]+='A'-'a';
//   else
//      if (shortfen[i]>='A'&&shortfen[i]<='Z')
//      shortfen[i]+='a'-'A';
if (isalpha(shortfen[i]))
   shortfen[i]^=0x20;
   return shortfen;
}
char *tranpose_line(char *rankfen)
{
   memset(shortfen,0,10);
   for( char * e = rankfen+strlen(rankfen) - 1; e >= rankfen; e-- )
        shortfen[strlen(shortfen)]=*e;
   return shortfen;

}
enum {shortcastlewhite=1,longcastlewhite=2,shortcastleblack=4,longcastleblack=8};

char * translate_fen_1(char *fen)
{
   memset(fen1,0,1024);
   char tempfen[10];
   char tempfen2[10][10];
   unsigned int l=strlen(fen);
   unsigned int i=0;
   int i0;
   int j=0;
   int cast=0;
   while ((i<l)&&(fen[i]==' '))
      i++;
   while (fen[i]!=' ')
   {
      i0=i;
      while ((fen[i]!='/')&&(fen[i]!=' '))
      i++;
      memset(tempfen,0,10);
      memcpy(tempfen,fen+i0,i-i0+1);
      strcpy(tempfen2[j],opp_line(tempfen));
       if (fen[i]=='/')
      i++;
      j++;
   }
   j--;
   strncat(fen1,tempfen2[j],strlen(tempfen2[j]));
   fen1[strlen(fen1)-1]='/';

   while (j>0)
   {
      j--;
      strncat(fen1,tempfen2[j],strlen(tempfen2[j]));
   }
   fen1[strlen(fen1)-1]=' ';
   i++;
   while (fen[i]==' ')
      i++;
   if ((fen[i]=='w')||(fen[i]=='W'))
   fen1[strlen(fen1)]='b';
   else
      fen1[strlen(fen1)]='w';
   fen1[strlen(fen1)]=' ';
   i++;
   while (fen[i]==' ')
      i++;
   if (fen[i]=='-')
   {
      fen1[strlen(fen1)]='-';
      i++;
   }
   else
   {
      while (fen[i]!=' ')
      {
         if (fen[i]=='k')
            cast|=shortcastlewhite;
         if (fen[i]=='q')
            cast|=longcastlewhite;
         if (fen[i]=='K')
            cast|=shortcastleblack;
         if (fen[i]=='Q')
            cast|=longcastleblack;
         i++;
      }
      if (cast&shortcastlewhite)
         fen1[strlen(fen1)]='K';
      if (cast&longcastlewhite)
         fen1[strlen(fen1)]='Q';
      if (cast&shortcastleblack)
         fen1[strlen(fen1)]='k';
      if (cast&longcastleblack)
         fen1[strlen(fen1)]='q';
   }
   fen1[strlen(fen1)]=' ';
   while (fen[i]==' ')
      i++;
   if (fen[i]=='-')
      fen1[strlen(fen1)]='-';
   else
   {
      fen1[strlen(fen1)]=fen[i];
      i++;
      fen1[strlen(fen1)]=9-fen[i];
   }
   i++;
   while (i!=l)
   {
      fen1[strlen(fen1)]=fen[i];
      i++;
   }

   return fen1;
}
char *translate_fen_2(char *fen)
{
   unsigned int l=strlen(fen);
   unsigned int i=0;
   char tempfen[10];
   int i0;
   int cast=0;
   memset(fen1,0,1024);
   while ((i<l)&&(fen[i]==' '))
      i++;
   while (fen[i]!=' ')
   {
      i0=i;
      while ((fen[i]!='/')&&(fen[i]!=' '))
      i++;
      memset(tempfen,0,10);
      memcpy(tempfen,fen+i0,i-i0);
      strcat(fen1,tranpose_line(tempfen));
      fen1[strlen(fen1)]=fen[i];
      if (fen[i]=='/')
         i++;
   }
   while ((fen[i]==' ')&&(i<l))
      i++;
   //correct color
   if (i<l)
      fen1[strlen(fen1)]=fen[i];
   //correct space after color
   fen1[strlen(fen1)]=' ';
   i++;
   if (fen[i]==' ')
      i++;
   if (i<l)
   if (fen[i]=='-')
   {
      while (i<l)
      {
         fen1[strlen(fen1)]=fen[i];
         i++;
      }
   }
   else
   {
      //castling rights
      
      while ((fen[i]!=' ')&&(i<l))
      {
         if (fen[i]=='k')
            cast|=longcastleblack;
         if (fen[i]=='q')
            cast|=shortcastleblack;
         if (fen[i]=='K')
            cast|=longcastlewhite;
         if (fen[i]=='Q')
            cast|=shortcastlewhite;
         i++;
      }
      if (cast&shortcastlewhite)
         fen1[strlen(fen1)]='K';
      if (cast&longcastlewhite)
         fen1[strlen(fen1)]='Q';
      if (cast&shortcastleblack)
         fen1[strlen(fen1)]='k';
      if (cast&longcastleblack)
         fen1[strlen(fen1)]='q';
      while (i<l)
      {
         fen1[strlen(fen1)]=fen[i];
         i++;
      }

   }
   return fen1;
   
   
}
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic       TalkChess.com Forum Index -> Computer Chess Club: Programming and Technical Discussions All times are GMT
Goto page 1, 2  Next
Threaded
Page 1 of 2

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum




Powered by phpBB © 2001, 2005 phpBB Group
Enhanced with Moby Threads