From 1588a4e84695e48e47c5c8b83d14ead285530c45 Mon Sep 17 00:00:00 2001 From: Tord Romstad Date: Sun, 24 Jan 2010 16:09:32 +0100 Subject: [PATCH] Fixes a Chess960 bug when playing with more than one search thread. The init_eval() function corrupted the static array castleRightsMask[] in the Position class, resulting in instant crashes in most Chess960 games. Fixed by repairing the damage directly after the function is called. Also modified the Position::to_fen() function to display castle rights correctly for Chess960 positions, and added sanity checks for uncastled rook files in Position::is_ok(). --- src/position.cpp | 42 ++++++++++++++++++++++++++++++++++++++---- src/search.cpp | 4 ++++ 2 files changed, 42 insertions(+), 4 deletions(-) diff --git a/src/position.cpp b/src/position.cpp index fb17f209..7ee63b22 100644 --- a/src/position.cpp +++ b/src/position.cpp @@ -271,10 +271,24 @@ const string Position::to_fen() const { fen += (sideToMove == WHITE ? "w " : "b "); if (st->castleRights != NO_CASTLES) { - if (can_castle_kingside(WHITE)) fen += 'K'; - if (can_castle_queenside(WHITE)) fen += 'Q'; - if (can_castle_kingside(BLACK)) fen += 'k'; - if (can_castle_queenside(BLACK)) fen += 'q'; + if (initialKFile == FILE_E && initialQRFile == FILE_A && initialKRFile == FILE_H) + { + if (can_castle_kingside(WHITE)) fen += 'K'; + if (can_castle_queenside(WHITE)) fen += 'Q'; + if (can_castle_kingside(BLACK)) fen += 'k'; + if (can_castle_queenside(BLACK)) fen += 'q'; + } + else + { + if (can_castle_kingside(WHITE)) + fen += toupper(file_to_char(initialKRFile)); + if (can_castle_queenside(WHITE)) + fen += toupper(file_to_char(initialQRFile)); + if (can_castle_kingside(BLACK)) + fen += file_to_char(initialKRFile); + if (can_castle_queenside(BLACK)) + fen += file_to_char(initialQRFile); + } } else fen += '-'; @@ -1850,6 +1864,7 @@ bool Position::is_ok(int* failedStep) const { static const bool debugNonPawnMaterial = false; static const bool debugPieceCounts = false; static const bool debugPieceList = false; + static const bool debugCastleSquares = false; if (failedStep) *failedStep = 1; @@ -1986,6 +2001,25 @@ bool Position::is_ok(int* failedStep) const { return false; } } + + if (failedStep) (*failedStep)++; + if (debugCastleSquares) { + for (Color c = WHITE; c <= BLACK; c++) { + if (can_castle_kingside(c) && piece_on(initial_kr_square(c)) != piece_of_color_and_type(c, ROOK)) + return false; + if (can_castle_queenside(c) && piece_on(initial_qr_square(c)) != piece_of_color_and_type(c, ROOK)) + return false; + } + if (castleRightsMask[initial_kr_square(WHITE)] != (ALL_CASTLES ^ WHITE_OO)) + return false; + if (castleRightsMask[initial_qr_square(WHITE)] != (ALL_CASTLES ^ WHITE_OOO)) + return false; + if (castleRightsMask[initial_kr_square(BLACK)] != (ALL_CASTLES ^ BLACK_OO)) + return false; + if (castleRightsMask[initial_qr_square(BLACK)] != (ALL_CASTLES ^ BLACK_OOO)) + return false; + } + if (failedStep) *failedStep = 0; return true; } diff --git a/src/search.cpp b/src/search.cpp index 65c29bf3..71b974b6 100644 --- a/src/search.cpp +++ b/src/search.cpp @@ -442,6 +442,10 @@ bool think(const Position& pos, bool infinite, bool ponder, int side_to_move, { ActiveThreads = newActiveThreads; init_eval(ActiveThreads); + // HACK: init_eval() destroys the static castleRightsMask[] array in the + // Position class. The below line repairs the damage. + Position p(pos.to_fen()); + assert(pos.is_ok()); } // Wake up sleeping threads -- 2.39.2