33#include " ../algorithm/Evaluation.h"
44#include " ../algorithm/Hash.h"
55
6- FenParser::FenParser (Board &board)
7- : _board(board)
8- {
9- }
10-
11- bool FenParser::parseFen (const std::string &fen)
6+ bool FenParser::parseFen (Board &board, const std::string &fen)
127{
138 std::istringstream stream (fen);
149
1510 if (!stream) return false ;
1611
1712 // Clean board
18- _board = {};
13+ board = {};
1914
20- parsePieces (stream);
15+ parsePieces (board, stream);
2116
2217 // Next to move
2318 std::string side;
2419 stream >> side;
25- _board .colorToMove = side == " w" ? WHITE : BLACK;
20+ board .colorToMove = side == " w" ? WHITE : BLACK;
2621
2722 // Castling availability
2823 std::string castling = " -" ;
2924 stream >> castling;
30- _board .castlingRights = CastlingRights::CASTLE_NONE;
25+ board .castlingRights = CastlingRights::CASTLE_NONE;
3126 for (char currChar : castling) {
3227 switch (currChar) {
33- case ' K' : _board .castlingRights |= CastlingRights::CASTLE_WHITE_KING;
28+ case ' K' : board .castlingRights |= CastlingRights::CASTLE_WHITE_KING;
3429 break ;
35- case ' Q' : _board .castlingRights |= CastlingRights::CASTLE_WHITE_QUEEN;
30+ case ' Q' : board .castlingRights |= CastlingRights::CASTLE_WHITE_QUEEN;
3631 break ;
37- case ' k' : _board .castlingRights |= CastlingRights::CASTLE_BLACK_KING;
32+ case ' k' : board .castlingRights |= CastlingRights::CASTLE_BLACK_KING;
3833 break ;
39- case ' q' : _board .castlingRights |= CastlingRights::CASTLE_BLACK_QUEEN;
34+ case ' q' : board .castlingRights |= CastlingRights::CASTLE_BLACK_QUEEN;
4035 break ;
4136 default :
4237 break ;
@@ -45,39 +40,96 @@ bool FenParser::parseFen(const std::string &fen)
4540
4641 std::string ep = " -" ;
4742 stream >> ep;
48- _board .enPassantSq = SQUARE_NB;
43+ board .enPassantSq = SQUARE_NB;
4944 if (ep != " -" )
5045 {
5146 if (ep.length () != 2 )
5247 return false ;
5348 if (!(ep[0 ] >= ' a' && ep[0 ] <= ' h' ))
5449 return false ;
55- if (!((side == " w" && ep[1 ] == ' 6' ) || (side == " b" && ep[1 ] == ' 3' )))
56- return false ;
5750
58- const byte sq = ::toSquare (static_cast <byte> (ep[0 ] - ' a' ), static_cast <byte> (ep[1 ] - ' 1' ));
59- _board .enPassantSq = sq < SQUARE_NB ? sq : SQUARE_NB;
51+ const byte sq = ::toSquare (int (ep[0 ] - ' a' ), int (ep[1 ] - ' 1' ));
52+ board .enPassantSq = sq < SQUARE_NB ? sq : SQUARE_NB;
6053 }
6154
6255 // HalfMove Clock
6356 int halfMove{};
6457 stream >> halfMove;
65- _board .fiftyMoveRule = static_cast <byte>(halfMove);
58+ board .fiftyMoveRule = static_cast <byte>(halfMove);
6659
67- _board .updatePieceList ();
68- _board .updateNonPieceBitboards ();
69- _board .zKey = Hash::compute (_board );
60+ board .updatePieceList ();
61+ board .updateNonPieceBitboards ();
62+ board .zKey = Hash::compute (board );
7063
71- _board .kingAttackers = _board .colorToMove ? _board .allKingAttackers <WHITE>() : _board .allKingAttackers <BLACK>();
64+ board .kingAttackers = board .colorToMove ? board .allKingAttackers <WHITE>() : board .allKingAttackers <BLACK>();
7265 return true ;
7366}
7467
75- std::string FenParser::exportToFen ()
68+ std::string FenParser::exportToFen (const Board &board )
7669{
77- return {};
70+ std::ostringstream out;
71+
72+ for (int rank = 7 ; rank >= 0 ; --rank)
73+ {
74+ for (int file = 0 ; file <= 7 ; ++file)
75+ {
76+ int emptyCount = 0 ;
77+ for (; file <= 7 && board.data [toSquare (file, rank)] == EMPTY_PIECE; ++file)
78+ ++emptyCount;
79+
80+ if (emptyCount)
81+ out << emptyCount;
82+
83+ if (file <= 7 ) {
84+ const Piece piece = board.data [toSquare (file, rank)];
85+ const PieceType type = piece.type ();
86+ char pChar = ' K' ;
87+
88+ if (type == PAWN)
89+ pChar = ' P' ;
90+ else if (type == KNIGHT)
91+ pChar = ' N' ;
92+ else if (type == BISHOP)
93+ pChar = ' B' ;
94+ else if (type == ROOK)
95+ pChar = ' R' ;
96+ else if (type == QUEEN)
97+ pChar = ' Q' ;
98+
99+ if (piece.color () == BLACK)
100+ pChar += 32 ;
101+
102+ out << pChar;
103+ }
104+ }
105+
106+ if (rank > 0 )
107+ out << ' /' ;
108+ }
109+
110+ out << (board.colorToMove == WHITE ? " w " : " b " );
111+
112+ if (board.canCastleKs <WHITE>()) out << ' K' ;
113+
114+ if (board.canCastleQs <WHITE>()) out << ' Q' ;
115+
116+ if (board.canCastleKs <BLACK>()) out << ' k' ;
117+
118+ if (board.canCastleQs <BLACK>()) out << ' q' ;
119+
120+ if (!board.canCastle (WHITE) && !board.canCastle (BLACK)) out << ' -' ;
121+
122+ if (board.enPassantSq < SQ_NONE)
123+ out << ' ' << char (' a' + int (col (board.enPassantSq ))) << int (row (board.enPassantSq )) << ' ' ;
124+ else
125+ out << " - " ;
126+
127+ out << short (board.fiftyMoveRule / 2 );
128+
129+ return out.str ();
78130}
79131
80- void FenParser::parsePieces (std::istringstream &stream)
132+ void FenParser::parsePieces (Board &board, std::istringstream &stream)
81133{
82134 std::string token;
83135 token.reserve (32 );
@@ -89,40 +141,40 @@ void FenParser::parsePieces(std::istringstream &stream)
89141 switch (currChar)
90142 {
91143 case ' p' :
92- _board .data [boardPos++] = { PAWN, BLACK };
144+ board .data [boardPos++] = { PAWN, BLACK };
93145 break ;
94146 case ' r' :
95- _board .data [boardPos++] = { ROOK, BLACK };
147+ board .data [boardPos++] = { ROOK, BLACK };
96148 break ;
97149 case ' n' :
98- _board .data [boardPos++] = { KNIGHT, BLACK };
150+ board .data [boardPos++] = { KNIGHT, BLACK };
99151 break ;
100152 case ' b' :
101- _board .data [boardPos++] = { BISHOP, BLACK };
153+ board .data [boardPos++] = { BISHOP, BLACK };
102154 break ;
103155 case ' q' :
104- _board .data [boardPos++] = { QUEEN, BLACK };
156+ board .data [boardPos++] = { QUEEN, BLACK };
105157 break ;
106158 case ' k' :
107- _board .data [boardPos++] = { KING, BLACK };
159+ board .data [boardPos++] = { KING, BLACK };
108160 break ;
109161 case ' P' :
110- _board .data [boardPos++] = { PAWN, WHITE };
162+ board .data [boardPos++] = { PAWN, WHITE };
111163 break ;
112164 case ' R' :
113- _board .data [boardPos++] = { ROOK, WHITE };
165+ board .data [boardPos++] = { ROOK, WHITE };
114166 break ;
115167 case ' N' :
116- _board .data [boardPos++] = { KNIGHT, WHITE };
168+ board .data [boardPos++] = { KNIGHT, WHITE };
117169 break ;
118170 case ' B' :
119- _board .data [boardPos++] = { BISHOP, WHITE };
171+ board .data [boardPos++] = { BISHOP, WHITE };
120172 break ;
121173 case ' Q' :
122- _board .data [boardPos++] = { QUEEN, WHITE };
174+ board .data [boardPos++] = { QUEEN, WHITE };
123175 break ;
124176 case ' K' :
125- _board .data [boardPos++] = { KING, WHITE };
177+ board .data [boardPos++] = { KING, WHITE };
126178 break ;
127179 case ' /' : boardPos -= 16u ; // Go down one rank
128180 break ;
0 commit comments