Try hard to retrieve a ponder move
authorMarco Costalba <mcostalba@gmail.com>
Tue, 20 Jan 2015 08:13:30 +0000 (09:13 +0100)
committerJoona Kiiski <joona.kiiski@gmail.com>
Sat, 24 Jan 2015 19:35:31 +0000 (19:35 +0000)
In case we stop the search during a fail-high
it is possible we return to GUI without a ponder
move. This patch try harder to find a ponder move
retrieving it from TT. This is important in games
played with 'ponder on'.

bench: 8080602

Resolves #221

src/search.cpp
src/search.h

index cdbf9897bd8caf88f56bb68f0557a3cf0881696b..da306a1a6150a487b3f6a734375e12023fd55862 100644 (file)
@@ -276,7 +276,7 @@ void Search::think() {
 
   sync_cout << "bestmove " << UCI::move(RootMoves[0].pv[0], RootPos.is_chess960());
 
-  if (RootMoves[0].pv.size() > 1)
+  if (RootMoves[0].pv.size() > 1 || RootMoves[0].extract_ponder_from_tt(RootPos))
       std::cout << " ponder " << UCI::move(RootMoves[0].pv[1], RootPos.is_chess960());
 
   std::cout << sync_endl;
@@ -1491,6 +1491,30 @@ void RootMove::insert_pv_in_tt(Position& pos) {
 }
 
 
+/// RootMove::extract_ponder_from_tt() is called in case we have no ponder move before
+/// exiting the search, for instance in case we stop the search during a fail high at
+/// root. We try hard to have a ponder move to return to the GUI, otherwise in case of
+/// 'ponder on' we have nothing to think on.
+
+Move RootMove::extract_ponder_from_tt(Position& pos)
+{
+    StateInfo st;
+    bool found;
+
+    assert(pv.size() == 1);
+
+    pos.do_move(pv[0], st);
+    TTEntry* tte = TT.probe(pos.key(), found);
+    Move m = found ? tte->move() : MOVE_NONE;
+    if (!MoveList<LEGAL>(pos).contains(m))
+        m = MOVE_NONE;
+
+    pos.undo_move(pv[0]);
+    pv.push_back(m);
+    return m;
+}
+
+
 /// Thread::idle_loop() is where the thread is parked when it has no work to do
 
 void Thread::idle_loop() {
index 409e9e754c68bda2ffc50c80123e417b04621780..5a0ad5df5790708e3a0e1d8d37f2926fcb3b668a 100644 (file)
@@ -60,6 +60,7 @@ struct RootMove {
   bool operator<(const RootMove& m) const { return score > m.score; } // Ascending sort
   bool operator==(const Move& m) const { return pv[0] == m; }
   void insert_pv_in_tt(Position& pos);
+  Move extract_ponder_from_tt(Position& pos);
 
   Value score;
   Value previousScore;