+ pretty += "#";
+ }
+ pos->undo_move(move);
+ }
+
+ decoded->set_pretty(pretty);
+}
+
+void HashProbeImpl::ProbeMove(Position* pos, std::deque<StateInfo>* setup_states, bool invert, HashProbeLine* response) {
+ bool found;
+ TTEntry *entry = TT.probe(pos->key(), found);
+ response->set_found(found);
+ if (found) {
+ Value value = entry->value();
+ Value eval = entry->eval();
+ Bound bound = entry->bound();
+
+ if (invert) {
+ value = -value;
+ eval = -eval;
+ if (bound == BOUND_UPPER) {
+ bound = BOUND_LOWER;
+ } else if (bound == BOUND_LOWER) {
+ bound = BOUND_UPPER;
+ }
+ }
+
+ response->set_depth(entry->depth());
+ FillValue(eval, response->mutable_eval());
+ if (entry->depth() > DEPTH_NONE) {
+ FillValue(value, response->mutable_value());
+ }
+ response->set_bound(HashProbeLine::ValueBound(bound));
+
+ // Follow the PV until we hit an illegal move.
+ std::stack<Move> pv;
+ std::set<Key> seen;
+ while (found && is_ok(entry->move()) &&
+ pos->pseudo_legal(entry->move()) &&
+ pos->legal(entry->move())) {
+ FillMove(pos, entry->move(), response->add_pv());
+ if (seen.count(pos->key())) break;
+ pv.push(entry->move());
+ seen.insert(pos->key());
+ setup_states->push_back(StateInfo());
+ pos->do_move(entry->move(), setup_states->back());
+ entry = TT.probe(pos->key(), found);