Retire undo_null_move()
authorMarco Costalba <mcostalba@gmail.com>
Sat, 29 Oct 2011 16:49:20 +0000 (17:49 +0100)
committerMarco Costalba <mcostalba@gmail.com>
Sat, 29 Oct 2011 17:01:56 +0000 (18:01 +0100)
Use a templetized do_null_move() to do/undo the null move.

No functional change.

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

index 4935a2c643ed965992944a4563695619b7ac9b70..a1823c12220ca2ba0b71b08607b17df3d49ccb24 100644 (file)
@@ -1204,62 +1204,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
index 4cfa34f643a0fb7356883d49df367f7e4ddb23f0..1bb2e3888e47edfe155cf863f68b7ec0efc0b126 100644 (file)
@@ -166,8 +166,7 @@ public:
   void do_move(Move m, StateInfo& st);
   void do_move(Move m, StateInfo& st, const CheckInfo& ci, bool moveIsCheck);
   void undo_move(Move m);
-  void do_null_move(StateInfo& st);
-  void undo_null_move();
+  template<bool Do> void do_null_move(StateInfo& st);
 
   // Static exchange evaluation
   int see(Move m) const;
index da95877cf793f232a7b2f6c600fbb8895b612189..25a3984d69331cb8a927e4424c6d0734e8440f29 100644 (file)
@@ -870,12 +870,12 @@ namespace {
         if (refinedValue - PawnValueMidgame > beta)
             R++;
 
-        pos.do_null_move(st);
+        pos.do_null_move<true>(st);
         (ss+1)->skipNullMove = true;
         nullValue = depth-R*ONE_PLY < ONE_PLY ? -qsearch<NonPV>(pos, ss+1, -beta, -alpha, DEPTH_ZERO)
                                               : - search<NonPV>(pos, ss+1, -beta, -alpha, depth-R*ONE_PLY);
         (ss+1)->skipNullMove = false;
-        pos.undo_null_move();
+        pos.do_null_move<false>(st);
 
         if (nullValue >= beta)
         {