Retire undo_castle_move()
authorMarco Costalba <mcostalba@gmail.com>
Sat, 29 Oct 2011 15:49:59 +0000 (16:49 +0100)
committerMarco Costalba <mcostalba@gmail.com>
Sat, 29 Oct 2011 16:31:15 +0000 (17:31 +0100)
Use a templetized do_castle_move() to do/undo the castling.

No functional change.

Signed-off-by: Marco Costalba <mcostalba@gmail.com>
src/position.cpp
src/position.h

index d49c0c2d7da23a0698e4656b3bafc00b82fe8b93..4935a2c643ed965992944a4563695619b7ac9b70 100644 (file)
@@ -764,7 +764,7 @@ void Position::do_move(Move m, StateInfo& newSt, const CheckInfo& ci, bool moveI
   if (is_castle(m))
   {
       st->key = key;
-      do_castle_move(m);
+      do_castle_move<true>(m);
       return;
   }
 
@@ -993,39 +993,43 @@ void Position::do_capture_move(Key& key, PieceType capture, Color them, Square t
 }
 
 
-/// Position::do_castle_move() is a private method used to make a castling
-/// move. It is called from the main Position::do_move function. Note that
-/// castling moves are encoded as "king captures friendly rook" moves, for
-/// instance white short castling in a non-Chess960 game is encoded as e1h1.
-
+/// Position::do_castle_move() is a private method used to do/undo a castling
+/// move. Note that castling moves are encoded as "king captures friendly rook"
+/// moves, for instance white short castling in a non-Chess960 game is encoded
+/// as e1h1.
+template<bool Do>
 void Position::do_castle_move(Move m) {
 
   assert(is_ok(m));
   assert(is_castle(m));
 
-  Color us = side_to_move();
-  Color them = flip(us);
-
-  // Find source squares for king and rook
-  Square kfrom = move_from(m);
-  Square rfrom = move_to(m);
-  Square kto, rto;
+  Square kto, kfrom, rfrom, rto, kAfter, rAfter;
 
-  assert(piece_on(kfrom) == make_piece(us, KING));
-  assert(piece_on(rfrom) == make_piece(us, ROOK));
+  Color us = side_to_move();
+  Square kBefore = move_from(m);
+  Square rBefore = move_to(m);
 
-  // Find destination squares for king and rook
-  if (rfrom > kfrom) // O-O
+  // Find after-castle squares for king and rook
+  if (rBefore > kBefore) // O-O
   {
-      kto = relative_square(us, SQ_G1);
-      rto = relative_square(us, SQ_F1);
+      kAfter = relative_square(us, SQ_G1);
+      rAfter = relative_square(us, SQ_F1);
   }
   else // O-O-O
   {
-      kto = relative_square(us, SQ_C1);
-      rto = relative_square(us, SQ_D1);
+      kAfter = relative_square(us, SQ_C1);
+      rAfter = relative_square(us, SQ_D1);
   }
 
+  kfrom = Do ? kBefore : kAfter;
+  rfrom = Do ? rBefore : rAfter;
+
+  kto = Do ? kAfter : kBefore;
+  rto = Do ? rAfter : rBefore;
+
+  assert(piece_on(kfrom) == make_piece(us, KING));
+  assert(piece_on(rfrom) == make_piece(us, ROOK));
+
   // Remove pieces from source squares
   clear_bit(&byColorBB[us], kfrom);
   clear_bit(&byTypeBB[KING], kfrom);
@@ -1056,38 +1060,44 @@ void Position::do_castle_move(Move m) {
   index[kto] = index[kfrom];
   index[rto] = tmp;
 
-  // Reset capture field
-  st->capturedType = PIECE_TYPE_NONE;
+  if (Do)
+  {
+      // Reset capture field
+      st->capturedType = PIECE_TYPE_NONE;
 
-  // Update incremental scores
-  st->value += pst_delta(king, kfrom, kto);
-  st->value += pst_delta(rook, rfrom, rto);
+      // Update incremental scores
+      st->value += pst_delta(king, kfrom, kto);
+      st->value += pst_delta(rook, rfrom, rto);
 
-  // Update hash key
-  st->key ^= zobrist[us][KING][kfrom] ^ zobrist[us][KING][kto];
-  st->key ^= zobrist[us][ROOK][rfrom] ^ zobrist[us][ROOK][rto];
+      // Update hash key
+      st->key ^= zobrist[us][KING][kfrom] ^ zobrist[us][KING][kto];
+      st->key ^= zobrist[us][ROOK][rfrom] ^ zobrist[us][ROOK][rto];
 
-  // Clear en passant square
-  if (st->epSquare != SQ_NONE)
-  {
-      st->key ^= zobEp[st->epSquare];
-      st->epSquare = SQ_NONE;
-  }
+      // Clear en passant square
+      if (st->epSquare != SQ_NONE)
+      {
+          st->key ^= zobEp[st->epSquare];
+          st->epSquare = SQ_NONE;
+      }
 
-  // Update castling rights
-  st->key ^= zobCastle[st->castleRights];
-  st->castleRights &= castleRightsMask[kfrom];
-  st->key ^= zobCastle[st->castleRights];
+      // Update castling rights
+      st->key ^= zobCastle[st->castleRights];
+      st->castleRights &= castleRightsMask[kfrom];
+      st->key ^= zobCastle[st->castleRights];
 
-  // Reset rule 50 counter
-  st->rule50 = 0;
+      // Reset rule 50 counter
+      st->rule50 = 0;
 
-  // Update checkers BB
-  st->checkersBB = attackers_to(king_square(them)) & pieces(us);
+      // Update checkers BB
+      st->checkersBB = attackers_to(king_square(flip(us))) & pieces(us);
 
-  // Finish
-  sideToMove = flip(sideToMove);
-  st->value += (sideToMove == WHITE ?  TempoValue : -TempoValue);
+      // Finish
+      sideToMove = flip(sideToMove);
+      st->value += (sideToMove == WHITE ?  TempoValue : -TempoValue);
+  }
+  else
+      // Undo: point our state pointer back to the previous state
+      st = st->previous;
 
   assert(pos_is_ok());
 }
@@ -1104,7 +1114,7 @@ void Position::undo_move(Move m) {
 
   if (is_castle(m))
   {
-      undo_castle_move(m);
+      do_castle_move<false>(m);
       return;
   }
 
@@ -1194,78 +1204,6 @@ void Position::undo_move(Move m) {
 }
 
 
-/// Position::undo_castle_move() is a private method used to unmake a castling
-/// move. It is called from the main Position::undo_move function. Note that
-/// castling moves are encoded as "king captures friendly rook" moves, for
-/// instance white short castling in a non-Chess960 game is encoded as e1h1.
-
-void Position::undo_castle_move(Move m) {
-
-  assert(is_ok(m));
-  assert(is_castle(m));
-
-  // When we have arrived here, some work has already been done by
-  // Position::undo_move. In particular, the side to move has been switched,
-  // so the code below is correct.
-  Color us = side_to_move();
-
-  // Find source squares for king and rook
-  Square kfrom = move_from(m);
-  Square rfrom = move_to(m);
-  Square kto, rto;
-
-  // Find destination squares for king and rook
-  if (rfrom > kfrom) // O-O
-  {
-      kto = relative_square(us, SQ_G1);
-      rto = relative_square(us, SQ_F1);
-  }
-  else // O-O-O
-  {
-      kto = relative_square(us, SQ_C1);
-      rto = relative_square(us, SQ_D1);
-  }
-
-  assert(piece_on(kto) == make_piece(us, KING));
-  assert(piece_on(rto) == make_piece(us, ROOK));
-
-  // Remove pieces from destination squares
-  clear_bit(&byColorBB[us], kto);
-  clear_bit(&byTypeBB[KING], kto);
-  clear_bit(&byTypeBB[0], kto);
-  clear_bit(&byColorBB[us], rto);
-  clear_bit(&byTypeBB[ROOK], rto);
-  clear_bit(&byTypeBB[0], rto);
-
-  // Put pieces on source squares
-  set_bit(&byColorBB[us], kfrom);
-  set_bit(&byTypeBB[KING], kfrom);
-  set_bit(&byTypeBB[0], kfrom);
-  set_bit(&byColorBB[us], rfrom);
-  set_bit(&byTypeBB[ROOK], rfrom);
-  set_bit(&byTypeBB[0], rfrom);
-
-  // Update board
-  Piece king = make_piece(us, KING);
-  Piece rook = make_piece(us, ROOK);
-  board[kto] = board[rto] = PIECE_NONE;
-  board[kfrom] = king;
-  board[rfrom] = rook;
-
-  // Update piece lists
-  pieceList[us][KING][index[kto]] = kfrom;
-  pieceList[us][ROOK][index[rto]] = rfrom;
-  int tmp = index[rto];  // In Chess960 could be rto == kfrom
-  index[kfrom] = index[kto];
-  index[rfrom] = tmp;
-
-  // Finally point our state pointer back to the previous state
-  st = st->previous;
-
-  assert(pos_is_ok());
-}
-
-
 /// Position::do_null_move makes() a "null move": It switches the side to move
 /// and updates the hash key without executing any move on the board.
 
index d6c79ee181840553b6858c6dcfcf5416898db506..4cfa34f643a0fb7356883d49df367f7e4ddb23f0 100644 (file)
@@ -219,8 +219,7 @@ private:
 
   // Helper functions for doing and undoing moves
   void do_capture_move(Key& key, PieceType capture, Color them, Square to, bool ep);
-  void do_castle_move(Move m);
-  void undo_castle_move(Move m);
+  template<bool Do> void do_castle_move(Move m);
 
   template<bool FindPinned>
   Bitboard hidden_checkers() const;