- /* 
-     Protector -- a UCI chess engine 
-   
-     Copyright (C) 2009-2010 Raimund Heid (Raimund_Heid@yahoo.com) 
-   
-     This program is free software: you can redistribute it and/or modify 
-     it under the terms of the GNU General Public License as published by 
-     the Free Software Foundation, either version 3 of the License, or 
-     (at your option) any later version. 
-   
-     This program is distributed in the hope that it will be useful, 
-     but WITHOUT ANY WARRANTY; without even the implied warranty of 
-     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
-     GNU General Public License for more details. 
-   
-     You should have received a copy of the GNU General Public License 
-     along with this program.  If not, see <http://www.gnu.org/licenses/>. 
-   
- */ 
-   
- #include "fen.h" 
- #include <string.h> 
- #include <stdlib.h> 
- #include <ctype.h> 
- #include <stdio.h> 
- #include <assert.h> 
-   
- static int initialized = 0; 
- static Piece pieceCode[256]; 
- static char pieceToken[16]; 
-   
- static void initialize() 
- { 
-    if (!initialized) 
-    { 
-       int i; 
-   
-       for (i = 0; i < 256; i++) 
-       { 
-          pieceCode[i] = NO_PIECE; 
-       } 
-   
-       pieceCode['K'] = WHITE_KING; 
-       pieceCode['Q'] = WHITE_QUEEN; 
-       pieceCode['R'] = WHITE_ROOK; 
-       pieceCode['B'] = WHITE_BISHOP; 
-       pieceCode['N'] = WHITE_KNIGHT; 
-       pieceCode['P'] = WHITE_PAWN; 
-       pieceCode['k'] = BLACK_KING; 
-       pieceCode['q'] = BLACK_QUEEN; 
-       pieceCode['r'] = BLACK_ROOK; 
-       pieceCode['b'] = BLACK_BISHOP; 
-       pieceCode['n'] = BLACK_KNIGHT; 
-       pieceCode['p'] = BLACK_PAWN; 
-   
-       pieceToken[WHITE_KING] = 'K'; 
-       pieceToken[WHITE_QUEEN] = 'Q'; 
-       pieceToken[WHITE_ROOK] = 'R'; 
-       pieceToken[WHITE_BISHOP] = 'B'; 
-       pieceToken[WHITE_KNIGHT] = 'N'; 
-       pieceToken[WHITE_PAWN] = 'P'; 
-       pieceToken[BLACK_KING] = 'k'; 
-       pieceToken[BLACK_QUEEN] = 'q'; 
-       pieceToken[BLACK_ROOK] = 'r'; 
-       pieceToken[BLACK_BISHOP] = 'b'; 
-       pieceToken[BLACK_KNIGHT] = 'n'; 
-       pieceToken[BLACK_PAWN] = 'p'; 
-   
-       initialized = 1; 
-    } 
- } 
-   
- static int setPieces(const char *fen, Position * position) 
- { 
-    Square square; 
-    Rank rank = RANK_8; 
-    File file = FILE_A; 
-    Piece p; 
-    int index = 0; 
-    int-  imax  = (int) (strlen(- fen )) - 1;
 
-    char current = '\0'; 
-   
-    ITERATE(square) 
-    { 
-       position->piece[square] = NO_PIECE; 
-    } 
-   
-    while (index <= imax && (current = fen[index]) != ' ') 
-    { 
-       if (current == '/') 
-       { 
-          rank--; 
-          file = FILE_A; 
-       } 
-       else if (current >= '1' && current <= '8') 
-       { 
-          file = (File) (file + current - '0'); 
-       } 
-       else 
-       { 
-          p = pieceCode[(int) current]; 
-   
-          if (p != NO_PIECE) 
-          { 
-             position->piece[getSquare(file, rank)] = p; 
-             file++; 
-          } 
-          else 
-          { 
-             return -1; 
-          } 
-       } 
-   
-       index++; 
-    } 
-   
-    return rank == RANK_1 ? index : -1; 
- } 
-   
- static int stringContainsChar(char *string, char c) 
- { 
-    while (*string != '\0') 
-    { 
-       if (*(string++) == c) 
-       { 
-          return 1; 
-       } 
-    } 
-   
-    return 0; 
- } 
-   
- int readFen(const char *fen, Position * position) 
- { 
-    int index; 
-   
-    /* 
-     * Initialize this module. 
-     */ 
-    initialize(); 
-   
-    /* 
-     * Get the piece positions. 
-     */ 
-    if ((index = setPieces(fen, position)) < 0) 
-    { 
-       return -1; 
-    } 
-   
-    /* 
-     * Get the active color. 
-     */ 
-    while (fen[index] == ' ') 
-    { 
-       index++; 
-    } 
-   
-    if (stringContainsChar("bw", fen[index])) 
-    { 
-       position->activeColor = (fen[index] == 'w' ? WHITE : BLACK); 
-       index++; 
-    } 
-    else 
-    { 
-       return -1;                /* fen format error */ 
-    } 
-   
-    /* 
-     * Get the castling rights. 
-     */ 
-    while (fen[index] == ' ') 
-    { 
-       index++; 
-    } 
-   
-    position->castlingRights = NO_CASTLINGS; 
-   
-    while (fen[index] != ' ') 
-    { 
-       switch (fen[index++]) 
-       { 
-       case 'K': 
-          position->castlingRights += WHITE_00; 
-          break; 
-       case 'Q': 
-          position->castlingRights += WHITE_000; 
-          break; 
-       case 'k': 
-          position->castlingRights += BLACK_00; 
-          break; 
-       case 'q': 
-          position->castlingRights += BLACK_000; 
-          break; 
-       case '-': 
-          position->castlingRights = NO_CASTLINGS; 
-          break; 
-       default: 
-          return -1;             /* fen format error */ 
-       } 
-    } 
-   
-    /* 
-     * Get the en passant square. 
-     */ 
-    while (fen[index] == ' ') 
-    { 
-       index++; 
-    } 
-   
-    if (fen[index] == '-') 
-    { 
-       position->enPassantSquare = NO_SQUARE; 
-       index++; 
-    } 
-    else if (fen[index] >= 'a' && fen[index] <= 'h' && 
-             (fen[index + 1] == '3' || fen[index + 1] == '6')) 
-    { 
-       File file = (File) (fen[index++] - 'a'); 
-       Rank rank = (Rank) (fen[index++] - '1'); 
-   
-       position->enPassantSquare = getSquare(file, rank); 
-    } 
-    else 
-    { 
-       return -1;                /* fen format error */ 
-    } 
-   
-    /* 
-     * Get the half move clock value. 
-     */ 
-    while (fen[index] == ' ') 
-    { 
-       index++; 
-    } 
-   
-    position ->- halfMoveClock  = atoi(- fen  +-  index );
-   
-    /* 
-     * Get the move number value. 
-     */ 
-    while (fen[index] != ' ') 
-    { 
-       { 
-          return -1;             /* fen format error */ 
-       } 
-   
-       index++; 
-    } 
-   
-    while (fen[index] == ' ') 
-    { 
-       index++; 
-    } 
-   
-    position ->- moveNumber  = atoi(- fen  +-  index );
-   
-    return 0; 
- } 
-   
- void getFen(const Position * position, char *fen) 
- { 
-    int rank, file; 
-    char buffer[16]; 
-   
-    /* 
-     * Initialize this module. 
-     */ 
-    initialize(); 
-   
-    for (rank = RANK_8; rank >= RANK_1; rank--) 
-    { 
-       int emptyCount = 0; 
-   
-       for (file = FILE_A; file <= FILE_H; file++) 
-       { 
-          Square square = getSquare(file, rank); 
-   
-          if (position->piece[square] != NO_PIECE) 
-          { 
-             if (emptyCount > 0) 
-             { 
-                *fen++ = ((char) ('0' + emptyCount)); 
-                emptyCount = 0; 
-             } 
-   
-             *fen++ = pieceToken[position->piece[square]]; 
-          } 
-          else 
-          { 
-             emptyCount++; 
-          } 
-       } 
-   
-       if (emptyCount > 0) 
-       { 
-          *fen++ = ((char) ('0' + emptyCount)); 
-       } 
-   
-       if (rank > RANK_1) 
-       { 
-          *fen++ = '/'; 
-       } 
-    } 
-   
-    *fen++ = ' '; 
-    *fen++ = (position->activeColor == WHITE ? 'w' : 'b'); 
-    *fen++ = ' '; 
-   
-    if (position->castlingRights) 
-    { 
-       if (position->castlingRights & WHITE_00) 
-       { 
-          *fen++ = 'K'; 
-       } 
-   
-       if (position->castlingRights & WHITE_000) 
-       { 
-          *fen++ = 'Q'; 
-       } 
-   
-       if (position->castlingRights & BLACK_00) 
-       { 
-          *fen++ = 'k'; 
-       } 
-   
-       if (position->castlingRights & BLACK_000) 
-       { 
-          *fen++ = 'q'; 
-       } 
-    } 
-    else 
-    { 
-       *fen++ = '-'; 
-    } 
-   
-    *fen++ = ' '; 
-   
-    if (position->enPassantSquare != NO_SQUARE) 
-    { 
-       char file = (char) (file(position->enPassantSquare) + 'a'); 
-       char rank = (char) (rank(position->enPassantSquare) + '1'); 
-   
-       *fen++ = file; 
-       *fen++ = rank; 
-    } 
-    else 
-    { 
-       *fen++ = '-'; 
-    } 
-   
-    *fen = '\0'; 
-    sprintf(- buffer , " %i %i",-  position ->- halfMoveClock ,-  position ->- moveNumber );
 
- } 
-   
- int initializeModuleFen() 
- { 
-    return 0; 
- } 
-   
- int testModuleFen() 
- { 
-    char *fen1 = FEN_GAMESTART; 
-    char *fen2 = 
-       "rn3rk1/pbppq1pp/1p2pb2/4N2Q/3PN3/3B4/PPP2PPP/R3K2R w KQ - 4 11"; 
-    char *fen3 = "8/8/1R5p/q5pk/PR3pP1/7P/8/7K b - g3 0 1"; 
-    char buffer[256]; 
-    Position position; 
-    Square square; 
-   
-    readFen(fen1, &position); 
-    getFen(&position, buffer); 
-   
-    assert(- position. activeColor ==-  WHITE );
 
-    assert(- position. enPassantSquare ==-  NO_SQUARE );
 
-    assert(- position. halfMoveClock == 0);
 
-    assert(- position. moveNumber == 1);
 
-    assert(- position. castlingRights ==
 
-           (WHITE_00 | WHITE_000 | BLACK_00 | BLACK_000)); 
-    assert(- position. piece[- A1 ] ==-  WHITE_ROOK );
 
-    assert(- position. piece[- H1 ] ==-  WHITE_ROOK );
 
-    assert(- position. piece[- B1 ] ==-  WHITE_KNIGHT );
 
-    assert(- position. piece[- G1 ] ==-  WHITE_KNIGHT );
 
-    assert(- position. piece[- C1 ] ==-  WHITE_BISHOP );
 
-    assert(- position. piece[- F1 ] ==-  WHITE_BISHOP );
 
-    assert(- position. piece[- D1 ] ==-  WHITE_QUEEN );
 
-    assert(- position. piece[- E1 ] ==-  WHITE_KING );
 
-   
-    assert(- position. piece[- A8 ] ==-  BLACK_ROOK );
 
-    assert(- position. piece[- H8 ] ==-  BLACK_ROOK );
 
-    assert(- position. piece[- B8 ] ==-  BLACK_KNIGHT );
 
-    assert(- position. piece[- G8 ] ==-  BLACK_KNIGHT );
 
-    assert(- position. piece[- C8 ] ==-  BLACK_BISHOP );
 
-    assert(- position. piece[- F8 ] ==-  BLACK_BISHOP );
 
-    assert(- position. piece[- D8 ] ==-  BLACK_QUEEN );
 
-    assert(- position. piece[- E8 ] ==-  BLACK_KING );
 
-   
-    for (square = A2; square <= H2; square++) 
-    { 
-       assert(- position. piece[- square ] ==-  WHITE_PAWN );
 
-       assert(- position. piece[- square  + 8] ==-  NO_PIECE );
 
-       assert(- position. piece[- square  + 16] ==-  NO_PIECE );
 
-       assert(- position. piece[- square  + 24] ==-  NO_PIECE );
 
-       assert(- position. piece[- square  + 32] ==-  NO_PIECE );
 
-       assert(- position. piece[- square  + 40] ==-  BLACK_PAWN );
 
-    } 
-   
-    readFen(fen2, &position); 
-    getFen(&position, buffer); 
-   
-    readFen(fen3, &position); 
-    getFen(&position, buffer); 
-   
-    return 0; 
- } 
-