@@ -41,7 +41,6 @@ void ChessBoard::makeZobristKey() {
4141 }
4242 }
4343
44-
4544 for (u64 x2 = chessboard[RIGHT_CASTLE_IDX]; x2; RESET_LSB (x2)) {
4645 const int position = BITScanForward (x2);
4746 updateZobristKey (RIGHT_CASTLE_IDX, position);// 12
@@ -63,18 +62,168 @@ int ChessBoard::loadFen() {
6362 return loadFen (fenString);
6463}
6564
66- int ChessBoard::loadFen (const string& fen) {
65+ string ChessBoard::boardToFen () const {
66+ string fen;
67+ for (int y = 0 ; y < 8 ; y++) {
68+ int l = 0 ;
69+ string row;
70+ for (int x = 0 ; x < 8 ; x++) {
71+ int q = board::getPieceAt<BLACK>(POW2[63 - ((y * 8 ) + x)], chessboard);
72+ if (q == SQUARE_EMPTY) {
73+ q = board::getPieceAt<WHITE>(POW2[63 - ((y * 8 ) + x)], chessboard);
74+ }
75+ if (q == SQUARE_EMPTY) {
76+ l++;
77+ } else {
78+ if (l > 0 ) {
79+ row.append (1 , (char ) (l + 48 ));
80+ }
81+ l = 0 ;
82+ row.append (1 , FEN_PIECE[q]);
83+ }
84+ }
85+ if (l > 0 ) {
86+ row.append (1 , (char ) (l + 48 ));
87+ }
88+ fen.append (row.c_str ());
89+ if (y < 7 ) {
90+ fen.append (" /" );
91+ }
92+ }
93+ if (chessboard[SIDETOMOVE_IDX] == BLACK) {
94+ fen.append (" b " );
95+ } else {
96+ fen.append (" w " );
97+ }
98+ int cst = 0 ;
99+ if (chessboard[RIGHT_CASTLE_IDX] & RIGHT_KING_CASTLE_WHITE_MASK) {
100+ fen += whiteRookKingSideCastle;
101+ cst++;
102+ }
103+ if (chessboard[RIGHT_CASTLE_IDX] & RIGHT_QUEEN_CASTLE_WHITE_MASK) {
104+ fen += whiteRookQueenSideCastle;
105+ cst++;
106+ }
107+ if (chessboard[RIGHT_CASTLE_IDX] & RIGHT_KING_CASTLE_BLACK_MASK) {
108+ fen += blackRookKingSideCastle;
109+ cst++;
110+ }
111+ if (chessboard[RIGHT_CASTLE_IDX] & RIGHT_QUEEN_CASTLE_BLACK_MASK) {
112+ fen += whiteRookKingSideCastle;
113+ cst++;
114+ }
115+ if (!cst) {
116+ fen.append (" -" );
117+ }
118+ if (chessboard[ENPASSANT_IDX] == NO_ENPASSANT) {
119+ fen.append (" -" );
120+ } else {
121+ fen.append (" " );
122+ chessboard[SIDETOMOVE_IDX] ? fen.append (BOARD[chessboard[ENPASSANT_IDX] + 8 ]) : fen.append (
123+ BOARD[chessboard[ENPASSANT_IDX] - 8 ]);
124+ }
125+ fen.append (" 0 " );
126+ fen.append (to_string (movesCount));
127+ return fen;
128+ }
129+
130+ void ChessBoard::display () const {
131+ cout << endl << " a b c d e f g h" ;
132+ for (int t = 0 ; t <= 63 ; t++) {
133+ char x = ' ' ;
134+ if (t % 8 == 0 ) {
135+ cout << endl << " ----+---+---+---+---+---+---+----" << endl;
136+ cout << " " << 8 - RANK_AT[t] << " | " ;
137+ }
138+ x = (x = (x = FEN_PIECE[board::getPieceAt<WHITE>(POW2[63 - t], chessboard)]) != ' -' ? x
139+ : FEN_PIECE[board::getPieceAt<BLACK>(
140+ POW2[63 - t], chessboard)]) == ' -' ? ' ' : x;
141+ x != ' ' ? cout << x : POW2[t] & WHITE_SQUARES ? cout << " " : cout << " ." ;
142+ cout << " | " ;
143+ };
144+ cout << endl << " ----+---+---+---+---+---+---+----" << endl;
145+ cout << " a b c d e f g h" << endl << endl << " fen:\t\t " << boardToFen () << endl;
146+
147+ cout << " side:\t\t " << (chessboard[SIDETOMOVE_IDX] ? " White" : " Black" ) << endl;
148+ cout << " castle:\t\t " ;
149+ if (chessboard[RIGHT_CASTLE_IDX] & RIGHT_KING_CASTLE_WHITE_MASK) cout << whiteRookKingSideCastle;
150+ if (chessboard[RIGHT_CASTLE_IDX] & RIGHT_QUEEN_CASTLE_WHITE_MASK) cout << whiteRookQueenSideCastle;
151+ if (chessboard[RIGHT_CASTLE_IDX] & RIGHT_KING_CASTLE_BLACK_MASK) cout << blackRookKingSideCastle;
152+ if (chessboard[RIGHT_CASTLE_IDX] & RIGHT_QUEEN_CASTLE_BLACK_MASK) cout << blackRookQueenSideCastle;
153+ cout << endl;
154+
155+ cout << " ep:\t\t\t "
156+ << (chessboard[ENPASSANT_IDX] == 100 ? " " : (chessboard[SIDETOMOVE_IDX] ? BOARD[chessboard[ENPASSANT_IDX] + 8 ]
157+ : BOARD[chessboard[ENPASSANT_IDX] -
158+ 8 ])) << endl;
159+ cout << " Chess960:\t " << (chess960 ? " true" : " false" ) << endl;
160+ #ifdef DEBUG_MODE
161+ cout << " zobristKey:\t 0x" << hex << chessboard[ZOBRISTKEY_IDX] << " ull" << dec << endl;
162+ #endif
163+ cout << endl;
164+ }
165+
166+ string ChessBoard::moveToString (const _Tmove *move) {
167+ string a = decodeBoardinv (move->s .type , move->s .from , move->s .side );
168+ if (move->s .type & 0xc ) return a;
169+ string b = decodeBoardinv (move->s .type , move->s .to , move->s .side );
170+ if (move->s .promotionPiece != -1 ) (a + b) += (char ) tolower (FEN_PIECE[move->s .promotionPiece ]);
171+ return a + b;
172+ }
173+
174+ void ChessBoard::print (const _Tmove *move, const _Tchessboard &chessboard) {
175+ cout << moveToString (move) << " " << flush;
176+ }
177+
178+ string ChessBoard::decodeBoardinv (const uchar type, const int a, const int side) {
179+ if (type & QUEEN_SIDE_CASTLE_MOVE_MASK && side == WHITE) {
180+ return isChess960 () ? BOARD[startPosWhiteKing] + BOARD[startPosWhiteRookQueenSide] : " e1c1" ;
181+ }
182+ if (type & KING_SIDE_CASTLE_MOVE_MASK && side == WHITE) {
183+ return isChess960 () ? BOARD[startPosWhiteKing] + BOARD[startPosWhiteRookKingSide] : " e1g1" ;
184+ }
185+ if (type & QUEEN_SIDE_CASTLE_MOVE_MASK && side == BLACK) {
186+ return isChess960 () ? BOARD[startPosBlackKing] + BOARD[startPosBlackRookQueenSide] : " e8c8" ;
187+ }
188+ if (type & KING_SIDE_CASTLE_MOVE_MASK && side == BLACK) {
189+ return isChess960 () ? BOARD[startPosBlackKing] + BOARD[startPosBlackRookKingSide] : " e8g8" ;
190+ }
191+ ASSERT (!(type & 0xC ));
192+ if (a >= 0 && a < 64 ) {
193+ return BOARD[a];
194+ }
195+ _assert (0 );
196+ }
197+
198+ int ChessBoard::loadFen (const string &fen) {
67199 if (fen.empty ()) {
68200 return loadFen ();
69201 }
202+ startPosWhiteKing = -1 ;
203+ startPosWhiteRookKingSide = -1 ;
204+ startPosWhiteRookQueenSide = -1 ;
205+
206+ startPosBlackKing = -1 ;
207+ startPosBlackRookKingSide = -1 ;
208+ startPosBlackRookQueenSide = -1 ;
209+ MATCH_QUEENSIDE = " " ;
210+ MATCH_QUEENSIDE_WHITE = " O-O-O " ;
211+ MATCH_KINGSIDE_WHITE = " O-O " ;
212+ MATCH_QUEENSIDE_BLACK = " O-O-O " ;
213+ MATCH_KINGSIDE_BLACK = " O-O " ;
70214 fenString = fen;
71215 memset (chessboard, 0 , sizeof (_Tchessboard));
72216 istringstream iss (fen);
73- string pos, castle, enpassant, side;
217+ string pos, castle, enpassant, side, a1, a2 ;
74218 iss >> pos;
75219 iss >> side;
76220 iss >> castle;
77221 iss >> enpassant;
222+ iss >> a1;
223+ iss >> a2;
224+ a2 += " 1" ;
225+ movesCount = stoi (a2);
226+
78227 int ix = 0 ;
79228 array<int , 64 > s;
80229 for (unsigned ii = 0 ; ii < pos.length (); ii++) {
@@ -110,74 +259,75 @@ int ChessBoard::loadFen(const string& fen) {
110259 } else {
111260 chessboard[p] &= NOTPOW2[i];
112261 }
262+ }
263+ startPosWhiteKing = BITScanForward (chessboard[KING_WHITE]);
264+ startPosBlackKing = BITScanForward (chessboard[KING_BLACK]);
265+ auto whiteRookKingSide = [&](const char c) {
266+ startPosWhiteRookKingSide = BITScanForward (chessboard[ROOK_WHITE] & 0xffULL );
267+ updateZobristKey (RIGHT_CASTLE_IDX, 4 );
268+ ASSERT (4 == BITScanForward (RIGHT_KING_CASTLE_WHITE_MASK));
269+ chessboard[RIGHT_CASTLE_IDX] |= RIGHT_KING_CASTLE_WHITE_MASK;
270+ whiteRookKingSideCastle = c;
271+ };
272+ auto blackRookKingSide = [&](const char c) {
273+ startPosBlackRookKingSide = BITScanForward (chessboard[ROOK_BLACK] & 0xff00000000000000ULL );
274+ updateZobristKey (RIGHT_CASTLE_IDX, 6 );
275+ ASSERT (6 == BITScanForward (RIGHT_KING_CASTLE_BLACK_MASK));
276+ chessboard[RIGHT_CASTLE_IDX] |= RIGHT_KING_CASTLE_BLACK_MASK;
277+ blackRookKingSideCastle = c;
278+ };
279+ auto whiteRookQueenSide = [&](const char c) {
280+ startPosWhiteRookQueenSide = BITScanReverse (chessboard[ROOK_WHITE] & 0xffULL );
281+ updateZobristKey (RIGHT_CASTLE_IDX, 5 );
282+ ASSERT (5 == BITScanForward (RIGHT_QUEEN_CASTLE_WHITE_MASK));
283+ chessboard[RIGHT_CASTLE_IDX] |= RIGHT_QUEEN_CASTLE_WHITE_MASK;
284+ whiteRookQueenSideCastle = c;
285+ };
286+ auto blackRookQueenSide = [&](const char c) {
287+ startPosBlackRookQueenSide = BITScanReverse (chessboard[ROOK_BLACK] & 0xff00000000000000ULL );
288+ updateZobristKey (RIGHT_CASTLE_IDX, 7 );
289+ ASSERT (7 == BITScanForward (RIGHT_QUEEN_CASTLE_BLACK_MASK));
290+ chessboard[RIGHT_CASTLE_IDX] |= RIGHT_QUEEN_CASTLE_BLACK_MASK;
291+ blackRookQueenSideCastle = c;
113292 };
114-
115293 for (unsigned e = 0 ; e < castle.length (); e++) {
116294 const char c = castle.at (e);
117295 switch (c) {
118296 case ' K' :
119- startPosWhiteKing = BITScanForward (chessboard[KING_WHITE]);
120- startPosWhiteRookKingSide = BITScanForward (chessboard[ROOK_WHITE] & 0xffULL );
121- updateZobristKey (RIGHT_CASTLE_IDX, 4 );
122- ASSERT (4 == BITScanForward (RIGHT_KING_CASTLE_WHITE_MASK));
123- chessboard[RIGHT_CASTLE_IDX] |= RIGHT_KING_CASTLE_WHITE_MASK;
297+ whiteRookKingSide (c);
124298 break ;
125299 case ' k' :
126- startPosBlackKing = BITScanForward (chessboard[KING_BLACK]);
127- startPosBlackRookKingSide = BITScanForward (chessboard[ROOK_BLACK] & 0xff00000000000000ULL );
128- updateZobristKey (RIGHT_CASTLE_IDX, 6 );
129- ASSERT (6 == BITScanForward (RIGHT_KING_CASTLE_BLACK_MASK));
130- chessboard[RIGHT_CASTLE_IDX] |= RIGHT_KING_CASTLE_BLACK_MASK;
300+ blackRookKingSide (c);
131301 break ;
132302 case ' Q' :
133- startPosWhiteKing = BITScanForward (chessboard[KING_WHITE]);
134- startPosWhiteRookQueenSide = BITScanReverse (chessboard[ROOK_WHITE] & 0xffULL );
135- updateZobristKey (RIGHT_CASTLE_IDX, 5 );
136- ASSERT (5 == BITScanForward (RIGHT_QUEEN_CASTLE_WHITE_MASK));
137- chessboard[RIGHT_CASTLE_IDX] |= RIGHT_QUEEN_CASTLE_WHITE_MASK;
303+ whiteRookQueenSide (c);
138304 break ;
139305 case ' q' :
140- startPosBlackKing = BITScanForward (chessboard[KING_BLACK]);
141- startPosBlackRookQueenSide = BITScanReverse (chessboard[ROOK_BLACK] & 0xff00000000000000ULL );
142- updateZobristKey (RIGHT_CASTLE_IDX, 7 );
143- ASSERT (7 == BITScanForward (RIGHT_QUEEN_CASTLE_BLACK_MASK));
144- chessboard[RIGHT_CASTLE_IDX] |= RIGHT_QUEEN_CASTLE_BLACK_MASK;
306+ blackRookQueenSide (c);
145307 break ;
146308 case ' -' :
147309 break ;
148310 default :
149311 // x-fen
312+ setChess960 (true );
150313 const int wKing = FILE_AT[BITScanForward (chessboard[KING_WHITE])];
151314 const int bKing = FILE_AT[BITScanForward (chessboard[KING_BLACK])];
152315
153316 if (isupper (c)) {
154- startPosWhiteKing = BITScanForward (chessboard[KING_WHITE]);
155317 if (board::getFile (c) < wKing) {
156- startPosWhiteRookKingSide = BITScanForward (chessboard[ROOK_WHITE] & 0xffULL );
157- updateZobristKey (RIGHT_CASTLE_IDX, 4 );
158- ASSERT (4 == BITScanForward (RIGHT_KING_CASTLE_WHITE_MASK));
159- chessboard[RIGHT_CASTLE_IDX] |= RIGHT_KING_CASTLE_WHITE_MASK;
318+ whiteRookKingSide (c);
160319 break ;
161320 } else {
162- startPosWhiteRookQueenSide = BITScanReverse (chessboard[ROOK_WHITE] & 0xffULL );
163- updateZobristKey (RIGHT_CASTLE_IDX, 5 );
164- ASSERT (5 == BITScanForward (RIGHT_QUEEN_CASTLE_WHITE_MASK));
165- chessboard[RIGHT_CASTLE_IDX] |= RIGHT_QUEEN_CASTLE_WHITE_MASK;
321+ whiteRookQueenSide (c);
166322 break ;
167323 }
168324 } else {
169- startPosBlackKing = BITScanForward (chessboard[KING_BLACK]);
325+
170326 if (board::getFile (c) < bKing) {
171- startPosBlackRookKingSide = BITScanForward (chessboard[ROOK_BLACK] & 0xff00000000000000ULL );
172- updateZobristKey (RIGHT_CASTLE_IDX, 6 );
173- ASSERT (6 == BITScanForward (RIGHT_KING_CASTLE_BLACK_MASK));
174- chessboard[RIGHT_CASTLE_IDX] |= RIGHT_KING_CASTLE_BLACK_MASK;
327+ blackRookKingSide (c);
175328 break ;
176329 } else {
177- startPosBlackRookQueenSide = BITScanReverse (chessboard[ROOK_BLACK] & 0xff00000000000000ULL );
178- updateZobristKey (RIGHT_CASTLE_IDX, 7 );
179- ASSERT (7 == BITScanForward (RIGHT_QUEEN_CASTLE_BLACK_MASK));
180- chessboard[RIGHT_CASTLE_IDX] |= RIGHT_QUEEN_CASTLE_BLACK_MASK;
330+ blackRookQueenSide (c);
181331 break ;
182332 }
183333 }
@@ -198,5 +348,28 @@ int ChessBoard::loadFen(const string& fen) {
198348 }
199349 }
200350
351+ if (isChess960 ()) {
352+ if (startPosWhiteRookKingSide != -1 )
353+ MATCH_KINGSIDE_WHITE += BOARD[startPosWhiteKing] + BOARD[startPosWhiteRookKingSide];
354+ if (startPosBlackRookQueenSide != -1 )
355+ MATCH_QUEENSIDE_BLACK += BOARD[startPosBlackKing] + BOARD[startPosBlackRookQueenSide];
356+ if (startPosWhiteRookQueenSide != -1 )
357+ MATCH_QUEENSIDE_WHITE += BOARD[startPosWhiteKing] + BOARD[startPosWhiteRookQueenSide];
358+ if (startPosBlackRookKingSide != -1 )
359+ MATCH_KINGSIDE_BLACK += BOARD[startPosBlackKing] + BOARD[startPosBlackRookKingSide];
360+ if (startPosBlackRookQueenSide != -1 )
361+ MATCH_QUEENSIDE +=
362+ MATCH_QUEENSIDE_BLACK + " " + BOARD[startPosBlackKing] + BOARD[startPosBlackRookQueenSide];
363+ if (startPosWhiteRookQueenSide != -1 )
364+ MATCH_QUEENSIDE +=
365+ MATCH_QUEENSIDE_WHITE + " " + BOARD[startPosWhiteKing] + BOARD[startPosWhiteRookQueenSide];
366+ } else {
367+ MATCH_QUEENSIDE_WHITE += " e1c1" ;
368+ MATCH_KINGSIDE_WHITE += " e1g1" ;
369+ MATCH_QUEENSIDE_BLACK += " e8c8" ;
370+ MATCH_KINGSIDE_BLACK += " e8g8" ;
371+ MATCH_QUEENSIDE = MATCH_QUEENSIDE_WHITE + " e8c8" ;
372+ }
373+
201374 return chessboard[SIDETOMOVE_IDX];
202375}
0 commit comments