void ThreadPool::start_thinking(const Position& pos, const LimitsType& limits, StateStackPtr& states) { wait_for_think_finished(); SearchTime = Time::now(); // As early as possible Signals.stopOnPonderhit = Signals.firstRootMove = false; Signals.stop = Signals.failedLowAtRoot = false; RootMoves.clear(); RootPos = pos; Limits = limits; if (states.get()) // If we don't set a new position, preserve current state { SetupStates = std::move(states); // Ownership transfer here assert(!states.get()); } for (const ExtMove& ms : MoveList<LEGAL>(pos)) if ( limits.searchmoves.empty() || std::count(limits.searchmoves.begin(), limits.searchmoves.end(), ms.move)) RootMoves.push_back(RootMove(ms.move)); main()->thinking = true; main()->notify_one(); // Starts main thread }
void ThreadPool::start_thinking(const Position& pos, const LimitsType& limits, StateStackPtr& states) { main()->join(); Signals.stopOnPonderhit = Signals.firstRootMove = false; Signals.stop = Signals.failedLowAtRoot = false; RootMoves.clear(); RootPos = pos; Limits = limits; if (states.get()) // If we don't set a new position, preserve current state { SetupStates = std::move(states); // Ownership transfer here assert(!states.get()); } for (const auto& m : MoveList<LEGAL>(pos)) if ( limits.searchmoves.empty() || std::count(limits.searchmoves.begin(), limits.searchmoves.end(), m)) RootMoves.push_back(RootMove(m)); main()->thinking = true; main()->notify_one(); // Wake up main thread: 'thinking' must be already set }
// 以下のようなフォーマットが入力される。 // <棋譜番号> <日付> <先手名> <後手名> <0:引き分け, 1:先手勝ち, 2:後手勝ち> <総手数> <棋戦名前> <戦形> // <CSA1行形式の指し手> // // (例) // 1 2003/09/08 羽生善治 谷川浩司 2 126 王位戦 その他の戦型 // 7776FU3334FU2726FU4132KI // // 勝った方の手だけを定跡として使うこととする。 // 出現回数がそのまま定跡として使う確率となる。 // 基本的には棋譜を丁寧に選別した上で定跡を作る必要がある。 // MAKE_SEARCHED_BOOK を on にしていると、定跡生成に非常に時間が掛かる。 void MakeBook(Position& pos, std::istringstream& ssCmd) { std::string fileName; ssCmd >> fileName; std::ifstream ifs(fileName.c_str(), std::ios::binary); if (!ifs) { std::cout << "I cannot open " << fileName << std::endl; return; } std::string line; std::map<Key, std::vector<BookEntry> > bookMap; while (std::getline(ifs, line)) { std::string elem; std::stringstream ss(line); ss >> elem; // 棋譜番号を飛ばす。 ss >> elem; // 対局日を飛ばす。 ss >> elem; // 先手 const std::string sente = elem; ss >> elem; // 後手 const std::string gote = elem; ss >> elem; // (0:引き分け,1:先手の勝ち,2:後手の勝ち) const Color winner = (elem == "1" ? Black : elem == "2" ? White : Color::Null); // 勝った方の指し手を記録していく。 // 又は稲庭戦法側を記録していく。 const Color saveColor = winner; if (!std::getline(ifs, line)) { std::cout << "!!! header only !!!" << std::endl; return; } pos.Set(g_DefaultStartPositionSFEN, pos.GetRucksack()->m_ownerHerosPub.GetFirstCaptain()); StateStackPtr SetUpStates = StateStackPtr(new std::stack<StateInfo>()); UsiOperation usiOperation; while (!line.empty()) { const std::string moveStrCSA = line.substr(0, 6); const Move move = usiOperation.CsaToMove(pos, moveStrCSA); if (move.IsNone()) { pos.Print(); std::cout << "!!! Illegal move = " << moveStrCSA << " !!!" << std::endl; break; } line.erase(0, 6); // 先頭から6文字削除 if (pos.GetTurn() == saveColor) { // 先手、後手の内、片方だけを記録する。 const Key key = Book::GetBookKey(pos); bool isFind = false; if (bookMap.find(key) != bookMap.end()) { for (std::vector<BookEntry>::iterator it = bookMap[key].begin(); it != bookMap[key].end(); ++it) { if (it->m_fromToPro == move.ProFromAndTo()) { ++it->m_count; if (it->m_count < 1) { // 数えられる数の上限を超えたので元に戻す。 --it->m_count; } isFind = true; } } } if (isFind == false) { #if defined MAKE_SEARCHED_BOOK SetUpStates->push(StateInfo()); pos.GetTurn()==Color::Black ? pos.DoMove<Color::Black,Color::White>(move, SetUpStates->top()) : pos.DoMove<Color::White,Color::Black>(move, SetUpStates->top()) ; std::istringstream ssCmd("byoyomi 1000"); UsiOperation usiOperation; usiOperation.Go(pos, ssCmd); pos.GetRucksack()->m_ownerHerosPub.WaitForThinkFinished(); pos.UndoMove(move); SetUpStates->pop(); // doMove してから search してるので点数が反転しているので直す。 const ScoreIndex score = -pos.GetConstRucksack()->m_rootMoves[0].m_score_; #else const ScoreIndex GetScore = ScoreZero; #endif // 未登録の手 BookEntry be; be.m_score = score; be.m_key = key; be.m_fromToPro = static_cast<u16>(move.ProFromAndTo()); be.m_count = 1; bookMap[key].push_back(be); } } SetUpStates->push(StateInfo()); pos.GetTurn() == Color::Black ? pos.DoMove<Color::Black,Color::White>(move, SetUpStates->top()) : pos.DoMove<Color::White,Color::Black>(move, SetUpStates->top()) ; } } // BookEntry::count の値で降順にソート for (auto& elem : bookMap) { std::sort(elem.second.rbegin(), elem.second.rend(), countCompare); } #if 0 // 2 回以上棋譜に出現していない手は削除する。 for (auto& elem : bookMap) { auto& second = elem.second; auto erase_it = std::find_if(second.begin(), second.IsEnd(), [](decltype(*second.begin())& second_elem) { return second_elem.m_count < 2; }); second.erase(erase_it, second.IsEnd()); } #endif #if 0 // narrow book for (auto& elem : bookMap) { auto& second = elem.second; auto erase_it = std::find_if(second.begin(), second.IsEnd(), [&](decltype(*second.begin())& second_elem) { return second_elem.m_count < second[0].m_count / 2; }); second.erase(erase_it, second.IsEnd()); } #endif std::ofstream ofs("book.bin", std::ios::binary); for (auto& elem : bookMap) { for (auto& elel : elem.second) { ofs.write(reinterpret_cast<char*>(&(elel)), sizeof(BookEntry)); } } std::cout << "book making was done" << std::endl; }