]> git.sesse.net Git - stockfish/blobdiff - src/position.cpp
Convert also undo_null_move() to avoid passing UndoInfo object
[stockfish] / src / position.cpp
index fdf3e911e9db32250781f6f8287451cc6eccbedf..c6c315271f1f27a79ccf15ea616564127e6be4fd 100644 (file)
@@ -210,8 +210,8 @@ void Position::from_fen(const std::string& fen) {
   key = compute_key();
   pawnKey = compute_pawn_key();
   materialKey = compute_material_key();
-  mgValue = compute_mg_value();
-  egValue = compute_eg_value();
+  mgValue = compute_value<MidGame>();
+  egValue = compute_value<EndGame>();
   npMaterial[WHITE] = compute_non_pawn_material(WHITE);
   npMaterial[BLACK] = compute_non_pawn_material(BLACK);
 }
@@ -669,62 +669,6 @@ bool Position::move_is_capture(Move m) const {
 }
 
 
-/// Position::backup() is called when making a move. All information
-/// necessary to restore the position when the move is later unmade
-/// is saved to an UndoInfo object. The function Position::restore
-/// does the reverse operation:  When one does a backup followed by
-/// a restore with the same UndoInfo object, the position is restored
-/// to the state before backup was called.
-
-void Position::backup(UndoInfo& u) const {
-
-  u.castleRights = castleRights;
-  u.epSquare     = epSquare;
-  u.checkersBB   = checkersBB;
-  u.key          = key;
-  u.pawnKey      = pawnKey;
-  u.materialKey  = materialKey;
-  u.rule50       = rule50;
-  u.lastMove     = lastMove;
-  u.mgValue      = mgValue;
-  u.egValue      = egValue;
-  u.capture      = NO_PIECE_TYPE;
-
-  for (Color c = WHITE; c <= BLACK; c++)
-  {
-      u.pinners[c]      = pinners[c];
-      u.pinned[c]       = pinned[c];
-      u.dcCandidates[c] = dcCandidates[c];
-  }
-}
-
-
-/// Position::restore() is called when unmaking a move.  It copies back
-/// the information backed up during a previous call to Position::backup.
-
-void Position::restore(const UndoInfo& u) {
-
-  castleRights = u.castleRights;
-  epSquare     = u.epSquare;
-  checkersBB   = u.checkersBB;
-  key          = u.key;
-  pawnKey      = u.pawnKey;
-  materialKey  = u.materialKey;
-  rule50       = u.rule50;
-  lastMove     = u.lastMove;
-  mgValue     = u.mgValue;
-  egValue     = u.egValue;
-  // u.capture is restored in undo_move()
-
-  for (Color c = WHITE; c <= BLACK; c++)
-  {
-      pinners[c]      = u.pinners[c];
-      pinned[c]       = u.pinned[c];
-      dcCandidates[c] = u.dcCandidates[c];
-  }
-}
-
-
 /// Position::update_checkers() is a private method to udpate chekers info
 
 template<PieceType Piece>
@@ -760,7 +704,9 @@ void Position::do_move(Move m, UndoInfo& u) {
 
   // Back up the necessary information to our UndoInfo object (except the
   // captured piece, which is taken care of later.
-  backup(u);
+  u = undoInfoUnion;
+  u.capture = NO_PIECE_TYPE;
+  previous = &u;
 
   // Save the current key to the history[] array, in order to be able to
   // detect repetition draws.
@@ -777,7 +723,7 @@ void Position::do_move(Move m, UndoInfo& u) {
   if (move_is_castle(m))
       do_castle_move(m);
   else if (move_promotion(m))
-      do_promotion_move(m, u);
+      do_promotion_move(m);
   else if (move_is_ep(m))
       do_ep_move(m);
   else
@@ -813,10 +759,10 @@ void Position::do_move(Move m, UndoInfo& u) {
     key ^= zobrist[us][piece][from] ^ zobrist[us][piece][to];
 
     // Update incremental scores
-    mgValue -= mg_pst(us, piece, from);
-    mgValue += mg_pst(us, piece, to);
-    egValue -= eg_pst(us, piece, from);
-    egValue += eg_pst(us, piece, to);
+    mgValue -= pst<MidGame>(us, piece, from);
+    mgValue += pst<MidGame>(us, piece, to);
+    egValue -= pst<EndGame>(us, piece, from);
+    egValue += pst<EndGame>(us, piece, to);
 
     // If the moving piece was a king, update the king square
     if (piece == KING)
@@ -906,8 +852,8 @@ void Position::do_capture_move(Move m, PieceType capture, Color them, Square to)
         pawnKey ^= zobrist[them][PAWN][to];
 
     // Update incremental scores
-    mgValue -= mg_pst(them, capture, to);
-    egValue -= eg_pst(them, capture, to);
+    mgValue -= pst<MidGame>(them, capture, to);
+    egValue -= pst<EndGame>(them, capture, to);
 
     assert(!move_promotion(m) || capture != PAWN);
 
@@ -994,14 +940,14 @@ void Position::do_castle_move(Move m) {
   index[rto] = tmp;
 
   // Update incremental scores
-  mgValue -= mg_pst(us, KING, kfrom);
-  mgValue += mg_pst(us, KING, kto);
-  egValue -= eg_pst(us, KING, kfrom);
-  egValue += eg_pst(us, KING, kto);
-  mgValue -= mg_pst(us, ROOK, rfrom);
-  mgValue += mg_pst(us, ROOK, rto);
-  egValue -= eg_pst(us, ROOK, rfrom);
-  egValue += eg_pst(us, ROOK, rto);
+  mgValue -= pst<MidGame>(us, KING, kfrom);
+  mgValue += pst<MidGame>(us, KING, kto);
+  egValue -= pst<EndGame>(us, KING, kfrom);
+  egValue += pst<EndGame>(us, KING, kto);
+  mgValue -= pst<MidGame>(us, ROOK, rfrom);
+  mgValue += pst<MidGame>(us, ROOK, rto);
+  egValue -= pst<EndGame>(us, ROOK, rfrom);
+  egValue += pst<EndGame>(us, ROOK, rto);
 
   // Update hash key
   key ^= zobrist[us][KING][kfrom] ^ zobrist[us][KING][kto];
@@ -1032,7 +978,7 @@ void Position::do_castle_move(Move m) {
 /// UndoInfo object, which has been initialized in Position::do_move, is
 /// used to store the captured piece (if any).
 
-void Position::do_promotion_move(Move m, UndoInfo &u) {
+void Position::do_promotion_move(Move m) {
 
   Color us, them;
   Square from, to;
@@ -1055,7 +1001,7 @@ void Position::do_promotion_move(Move m, UndoInfo &u) {
 
   if (capture)
   {
-    u.capture = capture;
+    previous->capture = capture;
     do_capture_move(m, capture, them, to);
   }
 
@@ -1094,10 +1040,10 @@ void Position::do_promotion_move(Move m, UndoInfo &u) {
   index[to] = pieceCount[us][promotion] - 1;
 
   // Update incremental scores
-  mgValue -= mg_pst(us, PAWN, from);
-  mgValue += mg_pst(us, promotion, to);
-  egValue -= eg_pst(us, PAWN, from);
-  egValue += eg_pst(us, promotion, to);
+  mgValue -= pst<MidGame>(us, PAWN, from);
+  mgValue += pst<MidGame>(us, promotion, to);
+  egValue -= pst<EndGame>(us, PAWN, from);
+  egValue += pst<EndGame>(us, promotion, to);
 
   // Update material
   npMaterial[us] += piece_value_midgame(promotion);
@@ -1188,12 +1134,12 @@ void Position::do_ep_move(Move m) {
   pawnKey ^= zobrist[them][PAWN][capsq];
 
   // Update incremental scores
-  mgValue -= mg_pst(them, PAWN, capsq);
-  mgValue -= mg_pst(us, PAWN, from);
-  mgValue += mg_pst(us, PAWN, to);
-  egValue -= eg_pst(them, PAWN, capsq);
-  egValue -= eg_pst(us, PAWN, from);
-  egValue += eg_pst(us, PAWN, to);
+  mgValue -= pst<MidGame>(them, PAWN, capsq);
+  mgValue -= pst<MidGame>(us, PAWN, from);
+  mgValue += pst<MidGame>(us, PAWN, to);
+  egValue -= pst<EndGame>(them, PAWN, capsq);
+  egValue -= pst<EndGame>(us, PAWN, from);
+  egValue += pst<EndGame>(us, PAWN, to);
 
   // Reset en passant square
   epSquare = SQ_NONE;
@@ -1211,7 +1157,7 @@ void Position::do_ep_move(Move m) {
 /// important that Position::undo_move is called with the same move and UndoInfo
 /// object as the earlier call to Position::do_move.
 
-void Position::undo_move(Move m, const UndoInfo &u) {
+void Position::undo_move(Move m) {
 
   assert(is_ok());
   assert(move_is_ok(m));
@@ -1221,19 +1167,19 @@ void Position::undo_move(Move m, const UndoInfo &u) {
 
   // Restore information from our UndoInfo object (except the captured piece,
   // which is taken care of later)
-  restore(u);
+  undoInfoUnion = *previous;
 
   if (move_is_castle(m))
       undo_castle_move(m);
   else if (move_promotion(m))
-      undo_promotion_move(m, u);
+      undo_promotion_move(m);
   else if (move_is_ep(m))
       undo_ep_move(m);
   else
   {
       Color us, them;
       Square from, to;
-      PieceType piece, capture;
+      PieceType piece;
 
       us = side_to_move();
       them = opposite_color(us);
@@ -1263,8 +1209,6 @@ void Position::undo_move(Move m, const UndoInfo &u) {
       pieceList[us][piece][index[to]] = from;
       index[from] = index[to];
 
-      capture = u.capture;
-
       if (capture)
       {
           assert(capture != KING);
@@ -1364,11 +1308,11 @@ void Position::undo_castle_move(Move m) {
 /// function. The UndoInfo object, which has been initialized in
 /// Position::do_move, is used to put back the captured piece (if any).
 
-void Position::undo_promotion_move(Move m, const UndoInfo &u) {
+void Position::undo_promotion_move(Move m) {
 
   Color us, them;
   Square from, to;
-  PieceType capture, promotion;
+  PieceType promotion;
 
   assert(move_is_ok(m));
   assert(move_promotion(m));
@@ -1412,8 +1356,6 @@ void Position::undo_promotion_move(Move m, const UndoInfo &u) {
   pieceCount[us][promotion]--;
   pieceCount[us][PAWN]++;
 
-  capture = u.capture;
-
   if (capture)
   {
       assert(capture != KING);
@@ -1503,10 +1445,12 @@ void Position::do_null_move(UndoInfo& u) {
   assert(!is_check());
 
   // Back up the information necessary to undo the null move to the supplied
-  // UndoInfo object.  In the case of a null move, the only thing we need to
+  // UndoInfo object. In the case of a null move, the only thing we need to
   // remember is the last move made and the en passant square.
   u.lastMove = lastMove;
   u.epSquare = epSquare;
+  u.previous = previous;
+  previous = &u;
 
   // Save the current key to the history[] array, in order to be able to
   // detect repetition draws.
@@ -1531,18 +1475,20 @@ void Position::do_null_move(UndoInfo& u) {
 
 /// Position::undo_null_move() unmakes a "null move".
 
-void Position::undo_null_move(const UndoInfo &u) {
+void Position::undo_null_move() {
 
   assert(is_ok());
   assert(!is_check());
 
-  // Restore information from the supplied UndoInfo object:
-  lastMove = u.lastMove;
-  epSquare = u.epSquare;
+  // Restore information from the our UndoInfo object
+  lastMove = previous->lastMove;
+  epSquare = previous->epSquare;
+  previous = previous->previous;
+
   if (epSquare != SQ_NONE)
       key ^= zobEp[epSquare];
 
-  // Update the necessary information.
+  // Update the necessary information
   sideToMove = opposite_color(sideToMove);
   rule50--;
   gamePly--;
@@ -1741,6 +1687,7 @@ void Position::clear() {
   epSquare = SQ_NONE;
   rule50 = 0;
   gamePly = 0;
+  previous = NULL;
 }
 
 
@@ -1866,13 +1813,12 @@ Key Position::compute_material_key() const {
 }
 
 
-/// Position::compute_mg_value() and Position::compute_eg_value() compute the
-/// incremental scores for the middle game and the endgame. These functions
-/// are used to initialize the incremental scores when a new position is set
-/// up, and to verify that the scores are correctly updated by do_move
-/// and undo_move when the program is running in debug mode.
-
-Value Position::compute_mg_value() const {
+/// Position::compute_value() compute the incremental scores for the middle
+/// game and the endgame. These functions are used to initialize the incremental
+/// scores when a new position is set up, and to verify that the scores are correctly
+/// updated by do_move and undo_move when the program is running in debug mode.
+template<Position::GamePhase Phase>
+Value Position::compute_value() const {
 
   Value result = Value(0);
   Bitboard b;
@@ -1886,31 +1832,12 @@ Value Position::compute_mg_value() const {
           {
               s = pop_1st_bit(&b);
               assert(piece_on(s) == piece_of_color_and_type(c, pt));
-              result += mg_pst(c, pt, s);
+              result += pst<Phase>(c, pt, s);
           }
       }
-  result += (side_to_move() == WHITE)? TempoValueMidgame / 2 : -TempoValueMidgame / 2;
-  return result;
-}
-
-Value Position::compute_eg_value() const {
 
-  Value result = Value(0);
-  Bitboard b;
-  Square s;
-
-  for (Color c = WHITE; c <= BLACK; c++)
-    for (PieceType pt = PAWN; pt <= KING; pt++)
-    {
-        b = pieces_of_color_and_type(c, pt);
-        while(b)
-        {
-            s = pop_1st_bit(&b);
-            assert(piece_on(s) == piece_of_color_and_type(c, pt));
-            result += eg_pst(c, pt, s);
-        }
-    }
-  result += (side_to_move() == WHITE)? TempoValueEndgame / 2 : -TempoValueEndgame / 2;
+  const Value TempoValue = (Phase == MidGame ? TempoValueMidgame : TempoValueEndgame);
+  result += (side_to_move() == WHITE)? TempoValue / 2 : -TempoValue / 2;
   return result;
 }
 
@@ -2014,12 +1941,12 @@ bool Position::has_mate_threat(Color c) {
       if (is_mate())
           result = true;
 
-      undo_move(mlist[i].move, u2);
+      undo_move(mlist[i].move);
   }
 
   // Undo null move, if necessary
   if (c != stm)
-      undo_null_move(u1);
+      undo_null_move();
 
   return result;
 }
@@ -2131,8 +2058,8 @@ void Position::flipped_copy(const Position &pos) {
   materialKey = compute_material_key();
 
   // Incremental scores
-  mgValue = compute_mg_value();
-  egValue = compute_eg_value();
+  mgValue = compute_value<MidGame>();
+  egValue = compute_value<EndGame>();
 
   // Material
   npMaterial[WHITE] = compute_non_pawn_material(WHITE);
@@ -2261,10 +2188,10 @@ bool Position::is_ok(int* failedStep) const {
   if (failedStep) (*failedStep)++;
   if (debugIncrementalEval)
   {
-      if (mgValue != compute_mg_value())
+      if (mgValue != compute_value<MidGame>())
           return false;
 
-      if (egValue != compute_eg_value())
+      if (egValue != compute_value<EndGame>())
           return false;
   }