From 408e6ee9b646ed8ce230c75a3cc021a5a4979c72 Mon Sep 17 00:00:00 2001 From: Marco Costalba Date: Thu, 1 Aug 2013 15:58:38 +0200 Subject: [PATCH] Further factor out position update code Along the lines of previous patch. No functional change --- src/position.cpp | 81 ++++++------------------------------------------ src/position.h | 22 +++++++++++-- 2 files changed, 29 insertions(+), 74 deletions(-) diff --git a/src/position.cpp b/src/position.cpp index 6d416276..1e0f46b7 100644 --- a/src/position.cpp +++ b/src/position.cpp @@ -232,7 +232,7 @@ void Position::set(const string& fenStr, bool isChess960, Thread* th) { else if ((p = PieceToChar.find(token)) != string::npos) { - put_piece(Piece(p), sq); + put_piece(sq, color_of(Piece(p)), type_of(Piece(p))); sq++; } } @@ -792,12 +792,7 @@ void Position::do_move(Move m, StateInfo& newSt, const CheckInfo& ci, bool moveI else st->npMaterial[them] -= PieceValue[MG][capture]; - // Remove the captured piece - byTypeBB[ALL_PIECES] ^= capsq; - byTypeBB[capture] ^= capsq; - byColorBB[them] ^= capsq; - - // Update piece lists + // Update board and piece lists remove_piece(capsq, them, capture); // Update material hash key and prefetch access to materialTable @@ -835,17 +830,7 @@ void Position::do_move(Move m, StateInfo& newSt, const CheckInfo& ci, bool moveI // Move the piece. The tricky Chess960 castle is handled earlier if (type_of(m) != CASTLE) - { - Bitboard from_to_bb = SquareBB[from] ^ SquareBB[to]; - byTypeBB[ALL_PIECES] ^= from_to_bb; - byTypeBB[pt] ^= from_to_bb; - byColorBB[us] ^= from_to_bb; - - board[from] = NO_PIECE; - board[to] = pc; - move_piece(from, to, us, pt); - } // If the moving piece is a pawn do some special extra work if (pt == PAWN) @@ -865,14 +850,8 @@ void Position::do_move(Move m, StateInfo& newSt, const CheckInfo& ci, bool moveI assert(relative_rank(us, to) == RANK_8); assert(promotion >= KNIGHT && promotion <= QUEEN); - // Replace the pawn with the promoted piece - byTypeBB[PAWN] ^= to; - byTypeBB[promotion] |= to; - board[to] = make_piece(us, promotion); - - // Update piece lists and add a new promotion piece to the list remove_piece(to, us, PAWN); - add_piece(to, us, promotion); + put_piece(to, us, promotion); // Update hash keys k ^= Zobrist::psq[us][PAWN][to] ^ Zobrist::psq[us][promotion][to]; @@ -962,15 +941,8 @@ void Position::undo_move(Move m) { assert(relative_rank(us, to) == RANK_8); assert(promotion >= KNIGHT && promotion <= QUEEN); - // Replace the promoted piece with the pawn - byTypeBB[promotion] ^= to; - byTypeBB[PAWN] |= to; - board[to] = make_piece(us, PAWN); - - // Update piece lists and add new pawn to the list remove_piece(to, us, promotion); - add_piece(to, us, PAWN); - + put_piece(to, us, PAWN); pt = PAWN; } @@ -985,18 +957,7 @@ void Position::undo_move(Move m) { do_castle(to, from, rto, rfrom); } else - { - // Put the piece back at the source square - Bitboard from_to_bb = SquareBB[from] ^ SquareBB[to]; - byTypeBB[ALL_PIECES] ^= from_to_bb; - byTypeBB[pt] ^= from_to_bb; - byColorBB[us] ^= from_to_bb; - - board[to] = NO_PIECE; - board[from] = make_piece(us, pt); - - move_piece(to, from, us, pt); - } + move_piece(to, from, us, pt); // Put the piece back at the source square if (capture) { @@ -1012,15 +973,7 @@ void Position::undo_move(Move m) { assert(piece_on(capsq) == NO_PIECE); } - // Restore the captured piece - byTypeBB[ALL_PIECES] |= capsq; - byTypeBB[capture] |= capsq; - byColorBB[them] |= capsq; - - board[capsq] = make_piece(them, capture); - - // Update piece list, add a new captured piece in capsq square - add_piece(capsq, them, capture); + put_piece(capsq, them, capture); // Restore the captured piece } // Finally point our state pointer back to the previous state @@ -1215,23 +1168,6 @@ void Position::clear() { } -/// Position::put_piece() puts a piece on the given square of the board, -/// updating the board array, pieces list, bitboards, and piece counts. - -void Position::put_piece(Piece p, Square s) { - - Color c = color_of(p); - PieceType pt = type_of(p); - - board[s] = p; - add_piece(s, c, pt); - - byTypeBB[ALL_PIECES] |= s; - byTypeBB[pt] |= s; - byColorBB[c] |= s; -} - - /// Position::compute_key() computes the hash key of the position. The hash /// key is usually updated incrementally as moves are made and unmade, the /// compute_key() function is only used when a new position is set up, and @@ -1384,7 +1320,10 @@ void Position::flip() { for (Square s = SQ_A1; s <= SQ_H8; s++) if (!pos.is_empty(s)) - put_piece(Piece(pos.piece_on(s) ^ 8), ~s); + { + Piece p = Piece(pos.piece_on(s) ^ 8); + put_piece(~s, color_of(p), type_of(p)); + } if (pos.can_castle(WHITE_OO)) set_castle_right(BLACK, ~pos.castle_rook_square(WHITE, KING_SIDE)); diff --git a/src/position.h b/src/position.h index 1da49c10..bf387dc6 100644 --- a/src/position.h +++ b/src/position.h @@ -188,14 +188,13 @@ public: private: // Initialization helpers (used while setting up a position) void clear(); - void put_piece(Piece p, Square s); void set_castle_right(Color c, Square rfrom); // Helper functions void do_castle(Square kfrom, Square kto, Square rfrom, Square rto); Bitboard hidden_checkers(Square ksq, Color c) const; + void put_piece(Square s, Color c, PieceType pt); void remove_piece(Square s, Color c, PieceType pt); - void add_piece(Square s, Color c, PieceType pt); void move_piece(Square from, Square to, Color c, PieceType pt); // Computing hash keys from scratch (for initialization and debugging) @@ -417,23 +416,40 @@ inline Thread* Position::this_thread() const { return thisThread; } -inline void Position::add_piece(Square s, Color c, PieceType pt) { +inline void Position::put_piece(Square s, Color c, PieceType pt) { + + board[s] = make_piece(c, pt); + byTypeBB[ALL_PIECES] |= s; + byTypeBB[pt] |= s; + byColorBB[c] |= s; index[s] = pieceCount[c][pt]++; pieceList[c][pt][index[s]] = s; } inline void Position::move_piece(Square from, Square to, Color c, PieceType pt) { + // index[from] is not updated and becomes stale. This works as long // as index[] is accessed just by known occupied squares. + Bitboard from_to_bb = SquareBB[from] ^ SquareBB[to]; + byTypeBB[ALL_PIECES] ^= from_to_bb; + byTypeBB[pt] ^= from_to_bb; + byColorBB[c] ^= from_to_bb; + board[from] = NO_PIECE; + board[to] = make_piece(c, pt); index[to] = index[from]; pieceList[c][pt][index[to]] = to; } inline void Position::remove_piece(Square s, Color c, PieceType pt) { + // WARNING: This is not a reversible operation. If we remove a piece in // do_move() and then replace it in undo_move() we will put it at the end of // the list and not in its original place, it means index[] and pieceList[] // are not guaranteed to be invariant to a do_move() + undo_move() sequence. + byTypeBB[ALL_PIECES] ^= s; + byTypeBB[pt] ^= s; + byColorBB[c] ^= s; + /* board[s] = NO_PIECE; */ // Not needed, will be overwritten by capturing Square lastSquare = pieceList[c][pt][--pieceCount[c][pt]]; index[lastSquare] = index[s]; pieceList[c][pt][index[lastSquare]] = lastSquare; -- 2.39.2