void ThreadPool::start_thinking(const Position& pos, StateListPtr& states, const Search::LimitsType& limits) { main()->wait_for_search_finished(); Search::Signals.stopOnPonderhit = Search::Signals.stop = false; Search::Limits = limits; Search::RootMoves rootMoves; for (const auto& m : MoveList<LEGAL>(pos)) if ( limits.searchmoves.empty() || std::count(limits.searchmoves.begin(), limits.searchmoves.end(), m)) rootMoves.push_back(Search::RootMove(m)); // After ownership transfer 'states' becomes empty, so if we stop the search // and call 'go' again without setting a new position states.get() == NULL. assert(states.get() || setupStates.get()); if (states.get()) setupStates = std::move(states); // Ownership transfer, states is now empty StateInfo tmp = setupStates->back(); for (Thread* th : Threads) { th->maxPly = 0; th->rootDepth = DEPTH_ZERO; th->rootMoves = rootMoves; th->rootPos.set(pos.fen(), pos.is_chess960(), &setupStates->back(), th); } setupStates->back() = tmp; // Restore st->previous, cleared by Position::set() main()->start_searching(); }
void ThreadPool::start_thinking(Position& pos, StateListPtr& states, const Search::LimitsType& limits, bool ponderMode) { main()->wait_for_search_finished(); stopOnPonderhit = stop = false; ponder = ponderMode; Search::Limits = limits; Search::RootMoves rootMoves; for (const auto& m : MoveList<LEGAL>(pos)) if ( limits.searchmoves.empty() || std::count(limits.searchmoves.begin(), limits.searchmoves.end(), m)) rootMoves.emplace_back(m); if (!rootMoves.empty()) Tablebases::filter_root_moves(pos, rootMoves); // After ownership transfer 'states' becomes empty, so if we stop the search // and call 'go' again without setting a new position states.get() == NULL. assert(states.get() || setupStates.get()); if (states.get()) setupStates = std::move(states); // Ownership transfer, states is now empty // We use Position::set() to set root position across threads. But there are // some StateInfo fields (previous, pliesFromNull, capturedPiece) that cannot // be deduced from a fen string, so set() clears them and to not lose the info // we need to backup and later restore setupStates->back(). Note that setupStates // is shared by threads but is accessed in read-only mode. StateInfo tmp = setupStates->back(); for (Thread* th : *this) { th->nodes = th->tbHits = 0; th->rootDepth = th->completedDepth = DEPTH_ZERO; th->rootMoves = rootMoves; th->rootPos.set(pos.fen(), pos.is_chess960(), &setupStates->back(), th); th->nmp_ply = 0; th->pair = -1; } setupStates->back() = tmp; main()->start_searching(); }
bool lomonosov_root_probe(Position& pos, Search::RootMoves& rootMoves, bool *from_dtm) { if (!lomonosov_loaded) return false; int value; *from_dtm = false; if (!lomonosov_tbprobe(pos, 0, &value, false, 0)) return false; StateInfo st; CheckInfo ci(pos); bool success = false; bool from_dtm_moves = true; // Probe each move. for (size_t i = 0; i < rootMoves.size(); i++) { Move move = rootMoves[i].pv[0]; pos.do_move(move, st, pos.gives_check(move, ci)); int v = 0; bool from_dtm_cur = false; success = lomonosov_tbprobe(pos, 1, &v, false, 0, &from_dtm_cur); pos.undo_move(move); if (!success) return false; from_dtm_moves &= from_dtm_cur; rootMoves[i].score = (Value)v; } size_t j = 0; if (value > 0) { int best = 0; if (from_dtm_moves) { for (size_t i = 0; i < rootMoves.size(); i++) { int v = rootMoves[i].score; if (v < 0 && (v > best || best == 0)) best = v; } } for (size_t i = 0; i < rootMoves.size(); i++) { int v = rootMoves[i].score; if (from_dtm_moves) { if (v == best) { rootMoves[j++] = rootMoves[i]; rootMoves[0].score = VALUE_MATE - value; *from_dtm = true; break; } } else if (v < 0) { rootMoves[j++] = rootMoves[i]; } } } else if (value < 0) { if (from_dtm_moves) { int best = 0; for (size_t i = 0; i < rootMoves.size(); i++) { int v = rootMoves[i].score; if (v > best) best = v; } for (size_t i = 0; i < rootMoves.size(); i++) { if (rootMoves[i].score == best) rootMoves[j++] = rootMoves[i]; } } else j = rootMoves.size(); } else { for (size_t i = 0; i < rootMoves.size(); i++) { if (rootMoves[i].score == 0) rootMoves[j++] = rootMoves[i]; } } rootMoves.resize(j, Search::RootMove(MOVE_NONE)); return true; }