// State save int BurnStateSave(TCHAR* szName, int bAll) { const char szHeader[] = "FB1 "; // File identifier int nLen = 0, nVer = 0; int nRet = 0; if (bAll) { // Get amount of data StateInfo(&nLen, &nVer, 1); } else { StateInfo(&nLen, &nVer, 0); } if (nLen <= 0) { // No data, so exit without creating a savestate return 0; // Don't return an error code } FILE* fp = _tfopen(szName, _T("wb")); if (fp == NULL) { return 1; } fwrite(&szHeader, 1, 4, fp); nRet = BurnStateSaveEmbed(fp, -1, bAll); fclose(fp); if (nRet < 0) { return 1; } else { return 0; } }
int iCmpExt::NObjCmpConnection::qt_metacall(QMetaObject::Call _c, int _id, void **_a) { typedef Domain::NamedObject QMocSuperClass; _id = QMocSuperClass::qt_metacall(_c, _id, _a); if (_id < 0) return _id; if (_c == QMetaObject::InvokeMetaMethod) { switch (_id) { case 0: StateInfo((*reinterpret_cast< DRI::IAsyncCmd*(*)>(_a[1]))); break; case 1: TdmInfo((*reinterpret_cast< DRI::IAsyncCmd*(*)>(_a[1]))); break; case 2: ChannelInfo((*reinterpret_cast< DRI::IAsyncCmd*(*)>(_a[1])),(*reinterpret_cast< int(*)>(_a[2])),(*reinterpret_cast< bool(*)>(_a[3]))); break; case 3: ConferenceInfo((*reinterpret_cast< DRI::IAsyncCmd*(*)>(_a[1])),(*reinterpret_cast< int(*)>(_a[2]))); break; default: ; } _id -= 4; } #ifndef QT_NO_PROPERTIES else if (_c == QMetaObject::ReadProperty) { void *_v = _a[0]; switch (_id) { case 0: *reinterpret_cast< QString*>(_v) = DriNameBoard(); break; case 1: *reinterpret_cast< QString*>(_v) = GetState(); break; case 2: *reinterpret_cast< int*>(_v) = m_countActivation; break; case 3: *reinterpret_cast< QString*>(_v) = LastActivation(); break; case 4: *reinterpret_cast< QString*>(_v) = LastDeactivation(); break; case 5: *reinterpret_cast< QString*>(_v) = m_lastBoardError; break; case 6: *reinterpret_cast< iCmpExt::ChDataCaptureMode::Value*>(_v) = m_dataCaptureMode; break; case 7: *reinterpret_cast< int*>(_v) = m_maxDataCaptureCount; break; case 8: *reinterpret_cast< int*>(_v) = m_currDataCaptureCount; break; } _id -= 9; } else if (_c == QMetaObject::WriteProperty) { void *_v = _a[0]; switch (_id) { case 6: m_dataCaptureMode = *reinterpret_cast< iCmpExt::ChDataCaptureMode::Value*>(_v); break; case 7: m_maxDataCaptureCount = *reinterpret_cast< int*>(_v); break; case 8: m_currDataCaptureCount = *reinterpret_cast< int*>(_v); break; } _id -= 9; } else if (_c == QMetaObject::ResetProperty) { _id -= 9; } else if (_c == QMetaObject::QueryPropertyDesignable) { _id -= 9; } else if (_c == QMetaObject::QueryPropertyScriptable) { _id -= 9; } else if (_c == QMetaObject::QueryPropertyStored) { _id -= 9; } else if (_c == QMetaObject::QueryPropertyEditable) { _id -= 9; } else if (_c == QMetaObject::QueryPropertyUser) { _id -= 9; } #endif // QT_NO_PROPERTIES return _id; }
void SpinBlock::transform_operators(std::vector<Matrix>& rotateMatrix) { StateInfo oldStateInfo = stateInfo; std::vector<SpinQuantum> newQuanta; std::vector<int> newQuantaStates; std::vector<int> newQuantaMap; for (int Q = 0; Q < rotateMatrix.size (); ++Q) { if (rotateMatrix [Q].Ncols () != 0) { newQuanta.push_back (stateInfo.quanta [Q]); newQuantaStates.push_back (rotateMatrix [Q].Ncols ()); newQuantaMap.push_back (Q); } } StateInfo newStateInfo = StateInfo (newQuanta, newQuantaStates, newQuantaMap); for (std::map<opTypes, boost::shared_ptr< Op_component_base> >::iterator it = ops.begin(); it != ops.end(); ++it) if (! it->second->is_core()) for_all_operators_multithread(*it->second, bind(&SparseMatrix::build_and_renormalise_transform, _1, this, it->first, ref(rotateMatrix) , &newStateInfo)); stateInfo = newStateInfo; stateInfo.AllocatePreviousStateInfo (); *stateInfo.previousStateInfo = oldStateInfo; for (int i = 0; i < newQuantaMap.size (); ++i) assert (stateInfo.quanta [i] == oldStateInfo.quanta [newQuantaMap [i]]); if (dmrginp.outputlevel() > 0) { pout << "\t\t\t total elapsed time " << globaltimer.totalwalltime() << " " << globaltimer.totalcputime() << " ... " << globaltimer.elapsedwalltime() << " " << globaltimer.elapsedcputime() << endl; pout << "\t\t\t Transforming to new basis " << endl; } Timer transformtimer; for (std::map<opTypes, boost::shared_ptr< Op_component_base> >::iterator it = ops.begin(); it != ops.end(); ++it) if ( it->second->is_core()) for_all_operators_multithread(*it->second, bind(&SparseMatrix::renormalise_transform, _1, ref(rotateMatrix), (&this->stateInfo))); for (std::map<opTypes, boost::shared_ptr< Op_component_base> >::iterator it = ops.begin(); it != ops.end(); ++it) if (! it->second->is_core()) ops[it->first]->set_core(true); this->direct = false; if (dmrginp.outputlevel() > 0) pout << "\t\t\t transform time " << transformtimer.elapsedwalltime() << " " << transformtimer.elapsedcputime() << endl; if (leftBlock) leftBlock->clear(); if (rightBlock) rightBlock->clear(); }
static vector<StateInfo> makeInfoTable(const NGHolder &g) { vector<StateInfo> info(num_vertices(g)); for (auto v : vertices_range(g)) { u32 idx = g[v].index; const CharReach &cr = g[v].char_reach; assert(idx < info.size()); info[idx] = StateInfo(v, cr); } return info; }
void SpinBlock::transform_operators(std::vector<Matrix>& rotateMatrix) { StateInfo oldStateInfo = braStateInfo; std::vector<SpinQuantum> newQuanta; std::vector<int> newQuantaStates; std::vector<int> newQuantaMap; for (int Q = 0; Q < rotateMatrix.size (); ++Q) { if (rotateMatrix [Q].Ncols () != 0) { newQuanta.push_back (braStateInfo.quanta [Q]); newQuantaStates.push_back (rotateMatrix [Q].Ncols ()); newQuantaMap.push_back (Q); } } StateInfo newStateInfo = StateInfo (newQuanta, newQuantaStates, newQuantaMap); build_and_renormalise_operators( rotateMatrix, &newStateInfo ); braStateInfo = newStateInfo; braStateInfo.AllocatePreviousStateInfo (); *braStateInfo.previousStateInfo = oldStateInfo; ketStateInfo = braStateInfo; for (int i = 0; i < newQuantaMap.size (); ++i) { assert (braStateInfo.quanta [i] == oldStateInfo.quanta [newQuantaMap [i]]); assert (ketStateInfo.quanta [i] == oldStateInfo.quanta [newQuantaMap [i]]); } tcpu = globaltimer.totalcputime(); twall= globaltimer.totalwalltime(); ecpu = globaltimer.elapsedcputime(); ewall= globaltimer.elapsedwalltime(); p3out << "\t\t\t total elapsed time " << twall << " " << tcpu << " ... " << ewall << " " << ecpu << endl; p1out << "\t\t\t Transforming to new basis " << endl; Timer transformtimer; renormalise_transform( rotateMatrix, &this->braStateInfo ); for (std::map<opTypes, boost::shared_ptr< Op_component_base> >::iterator it = ops.begin(); it != ops.end(); ++it) if (! it->second->is_core()) ops[it->first]->set_core(true); this->direct = false; ecpu = transformtimer.elapsedcputime();ewall= transformtimer.elapsedwalltime(); p3out << "\t\t\t transform time " << ewall << " " << ecpu << endl; if (leftBlock) leftBlock->clear(); if (rightBlock) rightBlock->clear(); }
StateInfo NFA::match_first(const string & text) { _matchStates.push({_start, text.begin()}); while (can_match()) { if (unguarded_match(text)) { break; } } if (_results.size()) { return _results.front(); } return StateInfo(); }
string analyze_game(string moves) { SetupStates = Search::StateStackPtr(new std::stack<StateInfo>); istringstream is(moves); std::stringstream ss; ss << centipawn_evaluate(pos); // Parse move list (if any) while (is >> token && (m = UCI::to_move(pos, token)) != MOVE_NONE) { SetupStates->push(StateInfo()); pos.do_move(m, SetupStates->top(), pos.gives_check(m, CheckInfo(pos))); ss << "," << centipawn_evaluate(pos); } return ss.str(); }
int iCmpExt::NObjWatchdogTest::qt_metacall(QMetaObject::Call _c, int _id, void **_a) { typedef Domain::NamedObject QMocSuperClass; _id = QMocSuperClass::qt_metacall(_c, _id, _a); if (_id < 0) return _id; if (_c == QMetaObject::InvokeMetaMethod) { switch (_id) { case 0: SmallWatchdogTest((*reinterpret_cast< DRI::IAsyncCmd*(*)>(_a[1])),(*reinterpret_cast< const QString(*)>(_a[2]))); break; case 1: HugeWatchdogTest((*reinterpret_cast< DRI::IAsyncCmd*(*)>(_a[1])),(*reinterpret_cast< const QString(*)>(_a[2]))); break; case 2: LoopForeverTest((*reinterpret_cast< DRI::IAsyncCmd*(*)>(_a[1])),(*reinterpret_cast< const QString(*)>(_a[2]))); break; case 3: AssertTest((*reinterpret_cast< DRI::IAsyncCmd*(*)>(_a[1])),(*reinterpret_cast< const QString(*)>(_a[2]))); break; case 4: OutOfMemoryTest((*reinterpret_cast< DRI::IAsyncCmd*(*)>(_a[1])),(*reinterpret_cast< const QString(*)>(_a[2]))); break; case 5: EchoHaltTest((*reinterpret_cast< DRI::IAsyncCmd*(*)>(_a[1])),(*reinterpret_cast< const QString(*)>(_a[2]))); break; case 6: StateInfo((*reinterpret_cast< DRI::IAsyncCmd*(*)>(_a[1])),(*reinterpret_cast< const QString(*)>(_a[2]))); break; case 7: RunWatchdogLoop((*reinterpret_cast< DRI::IAsyncCmd*(*)>(_a[1])),(*reinterpret_cast< const QString(*)>(_a[2])),(*reinterpret_cast< int(*)>(_a[3]))); break; default: ; } _id -= 8; } return _id; }
// State load int BurnStateLoadEmbed(FILE* fp, int nOffset, int bAll, int (*pLoadGame)()) { const char* szHeader = "FS1 "; // Chunk identifier int nLen = 0; int nMin = 0, nFileVer = 0, nFileMin = 0; int t1 = 0, t2 = 0; char ReadHeader[4]; char szForName[33]; int nChunkSize = 0; unsigned char *Def = NULL; int nDefLen = 0; // Deflated version int nRet = 0; if (nOffset >= 0) { fseek(fp, nOffset, SEEK_SET); } else { if (nOffset == -2) { fseek(fp, 0, SEEK_END); } else { fseek(fp, 0, SEEK_CUR); } } memset(ReadHeader, 0, 4); fread(ReadHeader, 1, 4, fp); // Read identifier if (memcmp(ReadHeader, szHeader, 4)) { // Not the right file type return -2; } fread(&nChunkSize, 1, 4, fp); if (nChunkSize <= 0x40) { // Not big enough return -1; } int nChunkData = ftell(fp); fread(&nFileVer, 1, 4, fp); // Version of FB that this file was saved from fread(&t1, 1, 4, fp); // Min version of FB that NV data will work with fread(&t2, 1, 4, fp); // Min version of FB that All data will work with if (bAll) { // Get the min version number which applies to us nFileMin = t2; } else { nFileMin = t1; } fread(&nDefLen, 1, 4, fp); // Get the size of the compressed data block memset(szForName, 0, sizeof(szForName)); fread(szForName, 1, 32, fp); if (nBurnVer < nFileMin) { // Error - emulator is too old to load this state return -5; } // Check the game the savestate is for, and load it if needed. { bool bLoadGame = false; if (nBurnDrvActive < nBurnDrvCount) { if (strcmp(szForName, BurnDrvGetTextA(DRV_NAME))) { // The save state is for the wrong game bLoadGame = true; } } else { // No game loaded bLoadGame = true; } if (bLoadGame) { unsigned int nCurrentGame = nBurnDrvActive; unsigned int i; for (i = 0; i < nBurnDrvCount; i++) { nBurnDrvActive = i; if (strcmp(szForName, BurnDrvGetTextA(DRV_NAME)) == 0) { break; } } if (i == nBurnDrvCount) { nBurnDrvActive = nCurrentGame; return -3; } else { if (pLoadGame == NULL) { return -1; } if (pLoadGame()) { return -1; } } } } StateInfo(&nLen, &nMin, bAll); if (nLen <= 0) { // No memory to load return -1; } // Check if the save state is okay if (nFileVer < nMin) { // Error - this state is too old and cannot be loaded. return -4; } fseek(fp, nChunkData + 0x30, SEEK_SET); // Read current frame fread(&nCurrentFrame, 1, 4, fp); // fseek(fp, 0x0C, SEEK_CUR); // Move file pointer to the start of the compressed block Def = (unsigned char*)malloc(nDefLen); if (Def == NULL) { return -1; } memset(Def, 0, nDefLen); fread(Def, 1, nDefLen, fp); // Read in deflated block nRet = BurnStateDecompress(Def, nDefLen, bAll); // Decompress block into driver if (Def) { free(Def); // free deflated block Def = NULL; } fseek(fp, nChunkData + nChunkSize, SEEK_SET); if (nRet) { return -1; } else { return 0; } }
// Write a savestate as a chunk of an "FB1 " file // nOffset is the absolute offset from the beginning of the file // -1: Append at current position // -2: Append at EOF int BurnStateSaveEmbed(FILE* fp, int nOffset, int bAll) { const char* szHeader = "FS1 "; // Chunk identifier int nLen = 0; int nNvMin = 0, nAMin = 0; int nZero = 0; char szGame[33]; unsigned char *Def = NULL; int nDefLen = 0; // Deflated version int nRet = 0; if (fp == NULL) { return -1; } StateInfo(&nLen, &nNvMin, 0); // Get minimum version for NV part nAMin = nNvMin; if (bAll) { // Get minimum version for All data StateInfo(&nLen, &nAMin, 1); } if (nLen <= 0) { // No memory to save return -1; } if (nOffset >= 0) { fseek(fp, nOffset, SEEK_SET); } else { if (nOffset == -2) { fseek(fp, 0, SEEK_END); } else { fseek(fp, 0, SEEK_CUR); } } fwrite(szHeader, 1, 4, fp); // Chunk identifier int nSizeOffset = ftell(fp); // Reserve space to write the size of this chunk fwrite(&nZero, 1, 4, fp); // fwrite(&nBurnVer, 1, 4, fp); // Version of FB this was saved from fwrite(&nNvMin, 1, 4, fp); // Min version of FB NV data will work with fwrite(&nAMin, 1, 4, fp); // Min version of FB All data will work with fwrite(&nZero, 1, 4, fp); // Reserve space to write the compressed data size memset(szGame, 0, sizeof(szGame)); // Game name sprintf(szGame, "%.32s", BurnDrvGetTextA(DRV_NAME)); // fwrite(szGame, 1, 32, fp); // fwrite(&nCurrentFrame, 1, 4, fp); // Current frame fwrite(&nZero, 1, 4, fp); // Reserved fwrite(&nZero, 1, 4, fp); // fwrite(&nZero, 1, 4, fp); // nRet = BurnStateCompress(&Def, &nDefLen, bAll); // Compress block from driver and return deflated buffer if (Def == NULL) { return -1; } nRet = fwrite(Def, 1, nDefLen, fp); // Write block to disk if (Def) { free(Def); // free deflated block and close file Def = NULL; } if (nRet != nDefLen) { // error writing block to disk return -1; } if (nDefLen & 3) { // Chunk size must be a multiple of 4 fwrite(&nZero, 1, 4 - (nDefLen & 3), fp); // Pad chunk if needed } fseek(fp, nSizeOffset + 0x10, SEEK_SET); // Write size of the compressed data fwrite(&nDefLen, 1, 4, fp); // nDefLen = (nDefLen + 0x43) & ~3; // Add for header size and align fseek(fp, nSizeOffset, SEEK_SET); // Write size of the chunk fwrite(&nDefLen, 1, 4, fp); // fseek (fp, 0, SEEK_END); // Set file pointer to the end of the chunk return nDefLen; }
// 自己対局を行い局面を生成する // 生成した局面はposition_listに追加する void play_game(std::vector<PositionData> &position_list, std::vector<std::vector<std::string>> &book) { std::random_device rnd; std::mt19937 mt(rnd()); std::unordered_map<Key, bool> hash_map; Search::StateStackPtr state = Search::StateStackPtr(new std::stack<StateInfo>()); Position pos; pos.set("lnsgkgsnl/1r5b1/ppppppppp/9/9/9/PPPPPPPPP/1B5R1/LNSGKGSNL b - 1", Threads[0]); hash_map[pos.key()] = true; Thread *thread = pos.this_thread(); if (book.empty()) { std::uniform_real_distribution<> select_prob(0.0, 1.0); std::uniform_int_distribution<> move_prob(kMinBookMove, kMaxBookMove); std::uniform_int_distribution<> search_prob(kMultiPvDepthMin, kMultiPvDepthMax); int book_end = move_prob(mt); for (int k = 0; k < book_end; ++k) { size_t multipv_max = (pos.game_ply() <= 20) ? kMultiPv20 : kMultiPvOver; if (!search(pos, multipv_max, static_cast<Depth>(search_prob(mt)))) return; double prob[kMultiPv20] = {0.0}; double total = 0.0; int pv_end = static_cast<int>(std::min(multipv_max, thread->root_moves_.size())); for (int i = 0; i < pv_end; ++i) { prob[i] = win_rate(thread->root_moves_[i].score); total += prob[i]; } for (int i = 0; i < pv_end; ++i) prob[i] = prob[i] / total; double t = select_prob(mt); int index; total = 0.0; for (index = 0; index < pv_end - 1; ++index) { total += prob[index]; if (total > t) break; } state->push(StateInfo()); pos.do_move(thread->root_moves_[index].pv[0], state->top()); hash_map[pos.key()] = true; } } else { std::uniform_int_distribution<> book_index(0, static_cast<int>(book.size() - 1)); std::vector<std::string> &moves = book[book_index(mt)]; std::uniform_int_distribution<> move_index(kMinBookMove, static_cast<int>(moves.size())); int book_end = move_index(mt); for (int i = 0; i < book_end; ++i) { Move m = USI::to_move(pos, moves[i]); if (m == kMoveNone) return; state->push(StateInfo()); pos.do_move(m, state->top()); hash_map[pos.key()] = true; } int randam_end = 1; if (moves.size() > 30) { std::uniform_int_distribution<> g(0, 1); randam_end = g(mt); } for (int i = 0; i < randam_end; ++i) { Move m = pick_randam_move(pos, mt); if (m == kMoveNone) return; state->push(StateInfo()); pos.do_move(m, state->top()); hash_map[pos.key()] = true; } } Search::clear(); Search::Limits.infinite = 1; Search::Signals.stop_on_ponder_hit = false; Search::Signals.stop = false; thread->pv_index_ = 0; thread->calls_count_ = 0; thread->max_ply_ = 0; thread->root_depth_ = kDepthZero; std::vector<PositionData> game; if (!search(pos, 1, kSearchDepth)) return; Value initial_value = thread->root_moves_[0].score; if (initial_value < -kWinValue || initial_value > kWinValue) return; PositionData d; d.sfen = USI::to_sfen(pos); d.value = initial_value; d.next_move = USI::format_move(thread->root_moves_[0].pv[0]); game.push_back(d); state->push(StateInfo()); pos.do_move(thread->root_moves_[0].pv[0], state->top()); hash_map[pos.key()] = true; Color win = kNoColor; while (true) { TT.new_search(); if (!search(pos, 1, kSearchDepth)) { win = ~pos.side_to_move(); break; } Value v = thread->root_moves_[0].score; if (pos.game_ply() > 1000) { if (v > 0) win = pos.side_to_move(); else if (v < 0) win = ~pos.side_to_move(); else win = kNoColor; break; } PositionData data; data.value = v; data.sfen = USI::to_sfen(pos); data.next_move = USI::format_move(thread->root_moves_[0].pv[0]); game.push_back(data); state->push(StateInfo()); pos.do_move(thread->root_moves_[0].pv[0], state->top()); if (hash_map[pos.key()]) break; hash_map[pos.key()] = true; } if (win != kNoColor) { for (auto &g : game) { g.win = win; position_list.push_back(g); } } }
// 以下のようなフォーマットが入力される。 // <棋譜番号> <日付> <先手名> <後手名> <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; }