Return the entire PV, and in slightly more parseable form.
authorSteinar H. Gunderson <sgunderson@bigfoot.com>
Sat, 19 Mar 2016 19:08:53 +0000 (20:08 +0100)
committerSteinar H. Gunderson <sgunderson@bigfoot.com>
Sat, 24 Nov 2018 10:17:41 +0000 (11:17 +0100)
src/client.cpp
src/hashprobe.proto
src/main.cpp

index 054e4ce..9f20357 100644 (file)
@@ -13,14 +13,9 @@ using grpc::ClientContext;
 using grpc::Status;
 using namespace hashprobe;
 
-std::string FormatMove(Move move) {
-  if (move == MOVE_NULL) {
-    return "Null-move";
-  } else if (move == MOVE_NONE) {
-    return "MOVE_NONE";
-  } else {
-    return UCI::square(from_sq(move)) + UCI::square(to_sq(move));
-  }
+std::string FormatMove(const HashProbeMove &move) {
+  if (move.from_sq().empty()) return "MOVE_NONE";
+  return move.from_sq() + move.to_sq() + move.promotion();
 }
 
 int main(int argc, char** argv) {
@@ -45,26 +40,29 @@ int main(int argc, char** argv) {
     Status status = stub->Probe(&context, request, &response);
 
     if (status.ok()) {
-      for (const HashProbeMove &hpmove : response.move()) {
-        std::cout << FormatMove(Move(hpmove.move())) << " ";
-        std::cout << hpmove.found() << " ";
-        std::cout << FormatMove(Move(hpmove.pv_move())) << " ";
-        switch (hpmove.bound()) {
-        case HashProbeMove::BOUND_NONE:
+      for (const HashProbeLine &line : response.line()) {
+        std::cout << FormatMove(line.move()) << " ";
+        std::cout << line.found() << " ";
+       for (const HashProbeMove &move : line.pv()) {
+          std::cout << FormatMove(move) << ",";
+        }
+        std::cout << " ";
+        switch (line.bound()) {
+        case HashProbeLine::BOUND_NONE:
           std::cout << "?";
           break;
-        case HashProbeMove::BOUND_EXACT:
+        case HashProbeLine::BOUND_EXACT:
           std::cout << "==";
           break;
-        case HashProbeMove::BOUND_UPPER:
+        case HashProbeLine::BOUND_UPPER:
           std::cout << "<=";
           break;
-        case HashProbeMove::BOUND_LOWER:
+        case HashProbeLine::BOUND_LOWER:
           std::cout << ">=";
           break;
         } 
-        std::cout << " " << UCI::value(Value(hpmove.value())) << " ";
-        std::cout << hpmove.depth() << std::endl;
+        std::cout << " " << UCI::value(Value(line.value())) << " ";
+        std::cout << line.depth() << std::endl;
       }
       std::cout << "END" << std::endl;
     } else {
index 505f06e..b02a7a9 100644 (file)
@@ -5,16 +5,16 @@ message HashProbeRequest {
        string fen = 1;
 }
 message HashProbeResponse {
-       repeated HashProbeMove move = 1;
+       repeated HashProbeLine line = 1;
 }
-message HashProbeMove {
-       int32 move = 7;  // See types.h
+message HashProbeLine {
+       HashProbeMove move = 1;
+       bool found = 2;
 
-       bool found = 1;
-       int32 pv_move = 2;  // See types.h
-       int32 value = 3;  // Dynamic eval (may be inexact, see the "bound" field)
-       int32 eval = 4;  // Static eval
-       int32 depth = 5;
+       repeated HashProbeMove pv = 3;
+       int32 value = 4;  // Dynamic eval (may be inexact, see the "bound" field)
+       int32 eval = 5;  // Static eval
+       int32 depth = 6;
 
        enum ValueBound {
                BOUND_NONE = 0;
@@ -22,7 +22,13 @@ message HashProbeMove {
                BOUND_LOWER = 2;
                BOUND_EXACT = 3;
        };
-       ValueBound bound = 6;
+       ValueBound bound = 7;
+}
+
+message HashProbeMove {
+       string from_sq = 1;  // a1, a2, etc.
+       string to_sq = 2;
+       string promotion = 3;  // Q, R, etc.
 }
 
 service HashProbe {
index 0d94cd4..4be9aaf 100644 (file)
@@ -52,24 +52,45 @@ public:
                }
 
                bool invert = (pos.side_to_move() == BLACK);
+               Search::StateStackPtr setup_states = Search::StateStackPtr(new std::stack<StateInfo>);
 
-               HashProbeMove *root_move = response->add_move();
-               root_move->set_move(MOVE_NONE);
-               ProbeMove(pos.key(), invert, root_move);
+               HashProbeLine *root_line = response->add_line();
+               ProbeMove(&pos, setup_states.get(), invert, root_line);
 
                MoveList<LEGAL> moves(pos);
                for (const ExtMove* em = moves.begin(); em != moves.end(); ++em) {
-                       HashProbeMove *move = response->add_move();
-                       move->set_move(em->move);
-                       ProbeMove(pos.key_after(em->move), !invert, move);
+                       HashProbeLine *line = response->add_line();
+                       FillMove(em->move, line->mutable_move());
+                       setup_states->push(StateInfo());
+                       pos.do_move(em->move, setup_states->top(), pos.gives_check(em->move, CheckInfo(pos)));
+                       ProbeMove(&pos, setup_states.get(), !invert, line);
+                       pos.undo_move(em->move);
                }
 
                return Status::OK;
        }
 
-       void ProbeMove(const int64_t key, bool invert, HashProbeMove* response) {
+       void FillMove(Move move, HashProbeMove* decoded) {
+               if (!is_ok(move)) return;
+
+               Square from = from_sq(move);
+               Square to = to_sq(move);
+
+               if (type_of(move) == CASTLING) {
+                       to = make_square(to > from ? FILE_G : FILE_C, rank_of(from));
+               }
+                       
+               decoded->set_from_sq(UCI::square(from));
+               decoded->set_to_sq(UCI::square(to));
+
+               if (type_of(move) == PROMOTION) {
+                       decoded->set_promotion(std::string() + " PNBRQK"[promotion_type(move)]);
+               }
+       }
+
+       void ProbeMove(Position* pos, std::stack<StateInfo>* setup_states, bool invert, HashProbeLine* response) {
                bool found;
-               TTEntry *entry = TT.probe(key, found);
+               TTEntry *entry = TT.probe(pos->key(), found);
                response->set_found(found);
                if (found) {
                        Value value = entry->value();
@@ -86,11 +107,26 @@ public:
                                }
                        }
 
-                       response->set_pv_move(entry->move());
                        response->set_depth(entry->depth());
                        response->set_eval(eval);
                        response->set_value(value);
-                       response->set_bound(HashProbeMove::ValueBound(bound));
+                       response->set_bound(HashProbeLine::ValueBound(bound));
+
+                       // Follow the PV until we hit an illegal move.
+                       std::stack<Move> pv;
+                       while (found && is_ok(entry->move())) {
+                               FillMove(entry->move(), response->add_pv());
+                               pv.push(entry->move());
+                               setup_states->push(StateInfo());
+                               pos->do_move(entry->move(), setup_states->top(), pos->gives_check(entry->move(), CheckInfo(*pos)));
+                               entry = TT.probe(pos->key(), found);
+                       }
+
+                       // Unroll the PV back again, so the Position object remains unchanged.
+                       while (!pv.empty()) {
+                               pos->undo_move(pv.top());
+                               pv.pop();
+                       }
                }
        }
 };