From: Fabian Fichter Date: Fri, 7 Feb 2020 12:19:19 +0000 (+0100) Subject: Simplify do_move and undo_move X-Git-Url: http://winboard.nl/cgi-bin?a=commitdiff_plain;h=76f213c944cbf28007516e62199e18541776ea94;p=fairystockfish.git Simplify do_move and undo_move No functional change. --- diff --git a/src/position.cpp b/src/position.cpp index 78866ae..b84d9b6 100644 --- a/src/position.cpp +++ b/src/position.cpp @@ -286,7 +286,9 @@ Position& Position::set(const Variant* v, const string& fenStr, bool isChess960, else if ((idx = piece_to_char().find(token)) != string::npos || (idx = piece_to_char_synonyms().find(token)) != string::npos) { - put_piece(Piece(idx), sq); + if (ss.peek() == '~') + ss >> token; + put_piece(Piece(idx), sq, token == '~'); ++sq; } // Promoted shogi pieces @@ -294,14 +296,9 @@ Position& Position::set(const Variant* v, const string& fenStr, bool isChess960, { ss >> token; idx = piece_to_char().find(token); - unpromotedBoard[sq] = Piece(idx); - promotedPieces |= SquareBB[sq]; - put_piece(make_piece(color_of(Piece(idx)), promoted_piece_type(type_of(Piece(idx)))), sq); + put_piece(make_piece(color_of(Piece(idx)), promoted_piece_type(type_of(Piece(idx)))), sq, true, Piece(idx)); ++sq; } - // Set flag for promoted pieces - else if (token == '~') - promotedPieces |= SquareBB[sq - 1]; // Stop before pieces in hand else if (token == '[') break; @@ -1124,7 +1121,8 @@ void Position::do_move(Move m, StateInfo& newSt, bool givesCheck) { assert(type_of(m) == PROMOTION && sittuyin_promotion()); captured = NO_PIECE; } - Piece unpromotedCaptured = unpromoted_piece_on(to); + st->capturedpromoted = is_promoted(to); + st->unpromotedCapturedPiece = captured ? unpromoted_piece_on(to) : NO_PIECE; assert(color_of(pc) == us); assert(captured == NO_PIECE || color_of(captured) == (type_of(m) != CASTLING ? them : us)); @@ -1172,19 +1170,18 @@ void Position::do_move(Move m, StateInfo& newSt, bool givesCheck) { st->nonPawnMaterial[them] -= PieceValue[MG][captured]; // Update board and piece lists + bool capturedPromoted = is_promoted(capsq); + Piece unpromotedCaptured = unpromoted_piece_on(capsq); remove_piece(captured, capsq); - st->capturedpromoted = is_promoted(to); if (captures_to_hand()) { - Piece pieceToHand = !is_promoted(to) || drop_loop() ? ~captured + Piece pieceToHand = !capturedPromoted || drop_loop() ? ~captured : unpromotedCaptured ? ~unpromotedCaptured : make_piece(~color_of(captured), PAWN); add_to_hand(pieceToHand); k ^= Zobrist::inHand[pieceToHand][pieceCountInHand[color_of(pieceToHand)][type_of(pieceToHand)] - 1] ^ Zobrist::inHand[pieceToHand][pieceCountInHand[color_of(pieceToHand)][type_of(pieceToHand)]]; } - promotedPieces -= to; - unpromotedBoard[to] = NO_PIECE; // Update material hash key and prefetch access to materialTable k ^= Zobrist::psq[captured][capsq]; @@ -1270,10 +1267,7 @@ void Position::do_move(Move m, StateInfo& newSt, bool givesCheck) { assert(type_of(promotion) >= KNIGHT && type_of(promotion) < KING); remove_piece(pc, to); - put_piece(promotion, to); - promotedPieces |= to; - if (type_of(m) == PIECE_PROMOTION) - unpromotedBoard[to] = pc; + put_piece(promotion, to, true, type_of(m) == PIECE_PROMOTION ? pc : NO_PIECE); // Update hash keys k ^= Zobrist::psq[pc][to] ^ Zobrist::psq[promotion][to]; @@ -1296,9 +1290,7 @@ void Position::do_move(Move m, StateInfo& newSt, bool givesCheck) { Piece promotion = make_piece(us, promoted_piece_type(type_of(pc))); remove_piece(pc, to); - put_piece(promotion, to); - promotedPieces |= to; - unpromotedBoard[to] = pc; + put_piece(promotion, to, true, pc); // Update hash keys k ^= Zobrist::psq[pc][to] ^ Zobrist::psq[promotion][to]; @@ -1310,12 +1302,10 @@ void Position::do_move(Move m, StateInfo& newSt, bool givesCheck) { } else if (type_of(m) == PIECE_DEMOTION) { - Piece demotion = unpromoted_piece_on(from); + Piece demotion = unpromoted_piece_on(to); remove_piece(pc, to); put_piece(demotion, to); - promotedPieces ^= from; - unpromotedBoard[from] = NO_PIECE; // Update hash keys k ^= Zobrist::psq[pc][to] ^ Zobrist::psq[demotion][to]; @@ -1328,9 +1318,6 @@ void Position::do_move(Move m, StateInfo& newSt, bool givesCheck) { // Set capture piece st->capturedPiece = captured; - st->unpromotedCapturedPiece = captured ? unpromotedCaptured : NO_PIECE; - if (captures_to_hand() && !captured) - st->capturedpromoted = false; // Add gating piece if (is_gating(m)) @@ -1363,20 +1350,6 @@ void Position::do_move(Move m, StateInfo& newSt, bool givesCheck) { // Calculate checkers bitboard (if move gives check) st->checkersBB = givesCheck ? attackers_to(square(them), us) & pieces(us) : Bitboard(0); - // Update information about promoted pieces - if (type_of(m) != DROP && is_promoted(from)) - promotedPieces = (promotedPieces - from) | to; - else if (type_of(m) == DROP && in_hand_piece_type(m) != dropped_piece_type(m)) - promotedPieces = promotedPieces | to; - - if (type_of(m) != DROP && unpromoted_piece_on(from)) - { - unpromotedBoard[to] = unpromotedBoard[from]; - unpromotedBoard[from] = NO_PIECE; - } - else if (type_of(m) == DROP && in_hand_piece_type(m) != dropped_piece_type(m)) - unpromotedBoard[to] = make_piece(us, in_hand_piece_type(m)); - sideToMove = ~sideToMove; if ( counting_rule() @@ -1448,23 +1421,20 @@ void Position::undo_move(Move m) { remove_piece(pc, to); pc = make_piece(us, PAWN); put_piece(pc, to); - promotedPieces -= to; } else if (type_of(m) == PIECE_PROMOTION) { + Piece unpromotedPiece = unpromoted_piece_on(to); remove_piece(pc, to); - pc = unpromoted_piece_on(to); + pc = unpromotedPiece; put_piece(pc, to); - unpromotedBoard[to] = NO_PIECE; - promotedPieces -= to; } else if (type_of(m) == PIECE_DEMOTION) { remove_piece(pc, to); - unpromotedBoard[from] = pc; + Piece unpromotedPc = pc; pc = make_piece(us, promoted_piece_type(type_of(pc))); - put_piece(pc, to); - promotedPieces |= from; + put_piece(pc, to, true, unpromotedPc); } if (type_of(m) == CASTLING) @@ -1478,18 +1448,6 @@ void Position::undo_move(Move m) { undrop_piece(make_piece(us, in_hand_piece_type(m)), pc, to); // Remove the dropped piece else move_piece(pc, to, from); // Put the piece back at the source square - if (is_promoted(to)) - { - promotedPieces = (promotedPieces - to); - if (type_of(m) != DROP) - promotedPieces |= from; - } - if (unpromoted_piece_on(to)) - { - if (type_of(m) != DROP) - unpromotedBoard[from] = unpromotedBoard[to]; - unpromotedBoard[to] = NO_PIECE; - } if (st->capturedPiece) { @@ -1506,16 +1464,11 @@ void Position::undo_move(Move m) { assert(st->capturedPiece == make_piece(~us, PAWN)); } - put_piece(st->capturedPiece, capsq); // Restore the captured piece + put_piece(st->capturedPiece, capsq, st->capturedpromoted, st->unpromotedCapturedPiece); // Restore the captured piece if (captures_to_hand()) remove_from_hand(!drop_loop() && st->capturedpromoted ? (st->unpromotedCapturedPiece ? ~st->unpromotedCapturedPiece : make_piece(~color_of(st->capturedPiece), PAWN)) : ~st->capturedPiece); - - if (st->capturedpromoted) - promotedPieces |= to; - if (st->unpromotedCapturedPiece) - unpromotedBoard[to] = st->unpromotedCapturedPiece; } } diff --git a/src/position.h b/src/position.h index 6b0270e..b6b8a24 100644 --- a/src/position.h +++ b/src/position.h @@ -264,7 +264,7 @@ private: void set_check_info(StateInfo* si) const; // Other helpers - void put_piece(Piece pc, Square s); + void put_piece(Piece pc, Square s, bool isPromoted = false, Piece unpromotedPc = NO_PIECE); void remove_piece(Piece pc, Square s); void move_piece(Piece pc, Square from, Square to); template @@ -913,7 +913,7 @@ inline Thread* Position::this_thread() const { return thisThread; } -inline void Position::put_piece(Piece pc, Square s) { +inline void Position::put_piece(Piece pc, Square s, bool isPromoted, Piece unpromotedPc) { board[s] = pc; byTypeBB[ALL_PIECES] |= s; @@ -923,6 +923,9 @@ inline void Position::put_piece(Piece pc, Square s) { pieceList[pc][index[s]] = s; pieceCount[make_piece(color_of(pc), ALL_PIECES)]++; psq += PSQT::psq[pc][s]; + if (isPromoted) + promotedPieces |= s; + unpromotedBoard[s] = unpromotedPc; } inline void Position::remove_piece(Piece pc, Square s) { @@ -941,6 +944,8 @@ inline void Position::remove_piece(Piece pc, Square s) { pieceList[pc][pieceCount[pc]] = SQ_NONE; pieceCount[make_piece(color_of(pc), ALL_PIECES)]--; psq -= PSQT::psq[pc][s]; + promotedPieces -= s; + unpromotedBoard[s] = NO_PIECE; } inline void Position::move_piece(Piece pc, Square from, Square to) { @@ -956,6 +961,10 @@ inline void Position::move_piece(Piece pc, Square from, Square to) { index[to] = index[from]; pieceList[pc][index[to]] = to; psq += PSQT::psq[pc][to] - PSQT::psq[pc][from]; + if (is_promoted(from)) + promotedPieces ^= fromTo; + unpromotedBoard[to] = unpromotedBoard[from]; + unpromotedBoard[from] = NO_PIECE; } inline void Position::do_move(Move m, StateInfo& newSt) { @@ -980,7 +989,7 @@ inline void Position::remove_from_hand(Piece pc) { inline void Position::drop_piece(Piece pc_hand, Piece pc_drop, Square s) { assert(pieceCountInHand[color_of(pc_hand)][type_of(pc_hand)]); - put_piece(pc_drop, s); + put_piece(pc_drop, s, pc_drop != pc_hand, pc_drop != pc_hand ? pc_hand : NO_PIECE); remove_from_hand(pc_hand); } diff --git a/tests/perft.sh b/tests/perft.sh index 8e7eb9a..1baba94 100755 --- a/tests/perft.sh +++ b/tests/perft.sh @@ -53,6 +53,7 @@ if [[ $1 == "" || $1 == "variant" ]]; then expect perft.exp ai-wok startpos 5 13275068 > /dev/null expect perft.exp euroshogi startpos 5 9451149 > /dev/null expect perft.exp minishogi startpos 5 533203 > /dev/null + expect perft.exp kyotoshogi startpos 5 225903 > /dev/null expect perft.exp horde startpos 6 5396554 > /dev/null expect perft.exp placement startpos 4 1597696 > /dev/null expect perft.exp sittuyin startpos 3 580096 > /dev/null