]> git.sesse.net Git - stockfish/blobdiff - src/position.cpp
Retire do_capture_move()
[stockfish] / src / position.cpp
index 4935a2c643ed965992944a4563695619b7ac9b70..397c87dd694c8eaba043f273d2255a883b68b69c 100644 (file)
@@ -781,11 +781,66 @@ void Position::do_move(Move m, StateInfo& newSt, const CheckInfo& ci, bool moveI
 
   assert(color_of(piece_on(from)) == us);
   assert(color_of(piece_on(to)) == them || square_is_empty(to));
-  assert(!(ep || pm) || piece == make_piece(us, PAWN));
-  assert(!pm || relative_rank(us, to) == RANK_8);
+  assert(capture != KING);
 
   if (capture)
-      do_capture_move(key, capture, them, to, ep);
+  {
+      Square capsq = to;
+
+      // If the captured piece was a pawn, update pawn hash key, otherwise
+      // update non-pawn material.
+      if (capture == PAWN)
+      {
+          if (ep) // En passant?
+          {
+              capsq += pawn_push(them);
+
+              assert(pt == PAWN);
+              assert(to == st->epSquare);
+              assert(relative_rank(us, to) == RANK_6);
+              assert(piece_on(to) == PIECE_NONE);
+              assert(piece_on(capsq) == make_piece(them, PAWN));
+
+              board[capsq] = PIECE_NONE;
+          }
+
+          st->pawnKey ^= zobrist[them][PAWN][capsq];
+      }
+      else
+          st->npMaterial[them] -= PieceValueMidgame[capture];
+
+      // Remove captured piece
+      clear_bit(&byColorBB[them], capsq);
+      clear_bit(&byTypeBB[capture], capsq);
+      clear_bit(&byTypeBB[0], capsq);
+
+      // Update hash key
+      key ^= zobrist[them][capture][capsq];
+
+      // Update incremental scores
+      st->value -= pst(make_piece(them, capture), capsq);
+
+      // Update piece count
+      pieceCount[them][capture]--;
+
+      // Update material hash key
+      st->materialKey ^= zobrist[them][capture][pieceCount[them][capture]];
+
+      // Update piece list, move the last piece at index[capsq] position
+      //
+      // WARNING: This is a not perfectly revresible operation. When we
+      // will reinsert the captured piece 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.
+      Square lastPieceSquare = pieceList[them][capture][pieceCount[them][capture]];
+      index[lastPieceSquare] = index[capsq];
+      pieceList[them][capture][index[lastPieceSquare]] = lastPieceSquare;
+      pieceList[them][capture][pieceCount[them][capture]] = SQ_NONE;
+
+      // Reset rule 50 counter
+      st->rule50 = 0;
+  }
 
   // Update hash key
   key ^= zobrist[us][pt][from] ^ zobrist[us][pt][to];
@@ -930,69 +985,6 @@ void Position::do_move(Move m, StateInfo& newSt, const CheckInfo& ci, bool moveI
 }
 
 
-/// Position::do_capture_move() is a private method used to update captured
-/// piece info. It is called from the main Position::do_move function.
-
-void Position::do_capture_move(Key& key, PieceType capture, Color them, Square to, bool ep) {
-
-    assert(capture != KING);
-
-    Square capsq = to;
-
-    // If the captured piece was a pawn, update pawn hash key,
-    // otherwise update non-pawn material.
-    if (capture == PAWN)
-    {
-        if (ep) // en passant ?
-        {
-            capsq = to + pawn_push(them);
-
-            assert(to == st->epSquare);
-            assert(relative_rank(flip(them), to) == RANK_6);
-            assert(piece_on(to) == PIECE_NONE);
-            assert(piece_on(capsq) == make_piece(them, PAWN));
-
-            board[capsq] = PIECE_NONE;
-        }
-        st->pawnKey ^= zobrist[them][PAWN][capsq];
-    }
-    else
-        st->npMaterial[them] -= PieceValueMidgame[capture];
-
-    // Remove captured piece
-    clear_bit(&byColorBB[them], capsq);
-    clear_bit(&byTypeBB[capture], capsq);
-    clear_bit(&byTypeBB[0], capsq);
-
-    // Update hash key
-    key ^= zobrist[them][capture][capsq];
-
-    // Update incremental scores
-    st->value -= pst(make_piece(them, capture), capsq);
-
-    // Update piece count
-    pieceCount[them][capture]--;
-
-    // Update material hash key
-    st->materialKey ^= zobrist[them][capture][pieceCount[them][capture]];
-
-    // Update piece list, move the last piece at index[capsq] position
-    //
-    // WARNING: This is a not perfectly revresible operation. When we
-    // will reinsert the captured piece 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.
-    Square lastPieceSquare = pieceList[them][capture][pieceCount[them][capture]];
-    index[lastPieceSquare] = index[capsq];
-    pieceList[them][capture][index[lastPieceSquare]] = lastPieceSquare;
-    pieceList[them][capture][pieceCount[them][capture]] = SQ_NONE;
-
-    // Reset rule 50 counter
-    st->rule50 = 0;
-}
-
-
 /// 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
@@ -1204,62 +1196,49 @@ void Position::undo_move(Move m) {
 }
 
 
-/// 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.
-
+/// Position::do_null_move() is used to do/undo a "null move": It flips the side
+/// to move and updates the hash key without executing any move on the board.
+template<bool Do>
 void Position::do_null_move(StateInfo& backupSt) {
 
   assert(!in_check());
 
   // Back up the information necessary to undo the null move to the supplied
-  // StateInfo object.
-  // Note that differently from normal case here backupSt is actually used as
-  // a backup storage not as a new state to be used.
-  backupSt.key      = st->key;
-  backupSt.epSquare = st->epSquare;
-  backupSt.value    = st->value;
-  backupSt.previous = st->previous;
-  backupSt.pliesFromNull = st->pliesFromNull;
-  st->previous = &backupSt;
-
-  // Update the necessary information
-  if (st->epSquare != SQ_NONE)
-      st->key ^= zobEp[st->epSquare];
-
-  st->key ^= zobSideToMove;
-  prefetch((char*)TT.first_entry(st->key));
+  // StateInfo object. Note that differently from normal case here backupSt
+  // is actually used as a backup storage not as the new state. This reduces
+  // the number of fields to be copied.
+  StateInfo* src = Do ? st : &backupSt;
+  StateInfo* dst = Do ? &backupSt : st;
+
+  dst->key      = src->key;
+  dst->epSquare = src->epSquare;
+  dst->value    = src->value;
+  dst->rule50   = src->rule50;
+  dst->pliesFromNull = src->pliesFromNull;
 
   sideToMove = flip(sideToMove);
-  st->epSquare = SQ_NONE;
-  st->rule50++;
-  st->pliesFromNull = 0;
-  st->value += (sideToMove == WHITE) ?  TempoValue : -TempoValue;
-
-  assert(pos_is_ok());
-}
-
-
-/// Position::undo_null_move() unmakes a "null move".
 
-void Position::undo_null_move() {
-
-  assert(!in_check());
+  if (Do)
+  {
+      if (st->epSquare != SQ_NONE)
+          st->key ^= zobEp[st->epSquare];
 
-  // Restore information from the our backup StateInfo object
-  StateInfo* backupSt = st->previous;
-  st->key      = backupSt->key;
-  st->epSquare = backupSt->epSquare;
-  st->value    = backupSt->value;
-  st->previous = backupSt->previous;
-  st->pliesFromNull = backupSt->pliesFromNull;
+      st->key ^= zobSideToMove;
+      prefetch((char*)TT.first_entry(st->key));
 
-  // Update the necessary information
-  sideToMove = flip(sideToMove);
-  st->rule50--;
+      st->epSquare = SQ_NONE;
+      st->rule50++;
+      st->pliesFromNull = 0;
+      st->value += (sideToMove == WHITE) ?  TempoValue : -TempoValue;
+  }
 
   assert(pos_is_ok());
 }
 
+// Explicit template instantiations
+template void Position::do_null_move<false>(StateInfo& backupSt);
+template void Position::do_null_move<true>(StateInfo& backupSt);
+
 
 /// Position::see() is a static exchange evaluator: It tries to estimate the
 /// material gain or loss resulting from a move. There are three versions of