diff --git a/src/bookmaker.cpp b/src/bookmaker.cpp index 8574f68..fc2c87a 100644 --- a/src/bookmaker.cpp +++ b/src/bookmaker.cpp @@ -390,9 +390,8 @@ void BookMaker::toBook() auto maxScore = 0; for(auto && it : nodeMap) { if (it.second.hitCount() >= paraRecord.minHit) { - auto isWhite = it.first.find(" w ") > 0; for(auto && wdl : it.second.moveMap) { - auto score = scoreForPolyglot(wdl.second, isWhite); + auto score = scoreForPolyglot(wdl.second, it.second.isWhite()); maxScore = std::max(maxScore, score); } } @@ -401,8 +400,6 @@ void BookMaker::toBook() if (maxScore > 0xffff) { polyglotScaleFactor = 0xffff / static_cast(maxScore); } - - tmpPolyglotBoard = bslib::Funcs::createBoard(bslib::ChessVariant::standard); } uint64_t cnt = 0; @@ -460,11 +457,6 @@ void BookMaker::toBook() } else if (textBookFile.is_open()) { textBookFile.close(); - - if (tmpPolyglotBoard) { - delete tmpPolyglotBoard; - tmpPolyglotBoard = nullptr; - } } auto elapsed = getElapse(startTime2); @@ -501,8 +493,7 @@ void BookMaker::toBookPgnEpd(bslib::BoardCore* board, std::set& visted assert(board); // check if the position is in the tree and the hit number is accepted - auto epdString = board->getEPD(true, false); - auto it = nodeMap.find(epdString); + auto it = nodeMap.find(board->hashKey); if ( it == nodeMap.end() || it->second.hitCount() < paraRecord.minHit || vistedSet.find(board->hashKey) != vistedSet.end()) { @@ -595,7 +586,7 @@ void BookMaker::savePgnEpd(bslib::BoardCore* board) } } -void BookMaker::add(int& fenID, const std::string& epdString, const BookNode& node) +void BookMaker::add(int& fenID, uint64_t key, const BookNode& node) { std::vector moveWDLVec; for(auto && it : node.moveMap) { @@ -616,10 +607,10 @@ void BookMaker::add(int& fenID, const std::string& epdString, const BookNode& no switch (bookType) { case CreateBookType::obs: - add2Db(fenID, epdString, moveWDLVec); + add2Db(fenID, node.epd, moveWDLVec); break; case CreateBookType::polyglot: - add2Polyglot(epdString, moveWDLVec); + add2Polyglot(key, moveWDLVec, node.isWhite()); break; default: @@ -673,11 +664,10 @@ int BookMaker::scoreForPolyglot(const WinDrawLoss& a, bool isWhite) const return score; } -void BookMaker::add2Polyglot(const std::string& epdString, std::vector& moveWDLVec) +void BookMaker::add2Polyglot(uint64_t hashKey, std::vector& moveWDLVec, bool isWhite) { - assert(!epdString.empty() && !moveWDLVec.empty() && tmpPolyglotBoard); - bool isWhite = epdString.find(" w ") > 0; - + assert(hashKey && !moveWDLVec.empty()); + // sort by values std::sort(moveWDLVec.begin(), moveWDLVec.end(), [=](const WinDrawLoss& a, const WinDrawLoss& b) -> bool { @@ -701,10 +691,8 @@ void BookMaker::add2Polyglot(const std::string& epdString, std::vector& bslib::Move move; int castled; a.moveFromInt(move, castled); - tmpPolyglotBoard->newGame(epdString); - - bslib::BookPolyglotItem item(tmpPolyglotBoard->key(), move.from, move.dest, move.promotion, castled, score); - assert(item.move); + bslib::BookPolyglotItem item(hashKey, move.from, move.dest, move.promotion, castled, score); + assert(item.key == hashKey && item.move); item.convertLittleEndian(); vec.push_back(item); } diff --git a/src/bookmaker.h b/src/bookmaker.h index d96c28c..e70010c 100644 --- a/src/bookmaker.h +++ b/src/bookmaker.h @@ -54,9 +54,9 @@ class BookMaker : public ocgdb::DbRead, public ocgdb::PGNRead void threadAddGame(const std::unordered_map& itemMap, const char* moveText); - void add(int& fenID, const std::string& epdString, const BookNode&); - void add2Db(int& fenID, const std::string& epdString, const std::vector&); - void add2Polyglot(const std::string& epdString, std::vector&); + void add(int& fenID, uint64_t key, const BookNode&); + void add2Db(int& fenID, const std::string& fenString, const std::vector&); + void add2Polyglot(uint64_t hashKey, std::vector&, bool isWhite); int scoreForPolyglot(const WinDrawLoss& a, bool isWhite) const; void setupRandonSavingPly(); @@ -65,7 +65,7 @@ class BookMaker : public ocgdb::DbRead, public ocgdb::PGNRead SQLite::Database* bookDb = nullptr; std::mutex nodeMapMutex; - std::map nodeMap; + std::map nodeMap; std::set lastEpdSet; int randomSavingPly; @@ -78,8 +78,6 @@ class BookMaker : public ocgdb::DbRead, public ocgdb::PGNRead CreateBookType bookType = CreateBookType::obs; std::ofstream textBookFile; - - bslib::BoardCore* tmpPolyglotBoard = nullptr; }; diff --git a/src/bookrecords.h b/src/bookrecords.h index 56cee36..28c5768 100644 --- a/src/bookrecords.h +++ b/src/bookrecords.h @@ -22,7 +22,7 @@ namespace oobs { -const std::string VersionString = "beta 1"; +const std::string VersionString = "beta 2"; const std::string VersionDatabaseString = "0.1"; class WinDrawLoss { @@ -58,14 +58,21 @@ class MoveWDL : public WinDrawLoss { class BookNode { public: - // map move-int to BookNodeMove + std::string epd; + + // map move int to BookNodeMove std::unordered_map moveMap; void clear() { + epd.clear(); moveMap.clear(); } bool isValid() const { + if (epd.empty()) { + return false; + } + for(auto && it : moveMap) { if (it.first == 0 || !it.second.isValid()) { return false; @@ -83,6 +90,7 @@ class BookNode { } void addFrom(const BookNode& node) { + assert(epd == node.epd); assert(node.isValid()); for(auto && m : node.moveMap) { @@ -96,6 +104,10 @@ class BookNode { assert(isValid()); } + + bool isWhite() const { + return epd.find(" w ") != std::string::npos; + } }; diff --git a/src/main.cpp b/src/main.cpp index 9605e14..d30c28a 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -197,7 +197,7 @@ void print_usage() " PGN: .pgn\n" \ " EPD: .epd (Extended Position Description)\n" \ " -elo discard games with Elo under n (for creating), default is 0\n" \ - " -plycount discard games with ply-count under n (for creating), default is 0\n" \ + " -plycount discard games with ply-count under n (for creating), set 0 for all, default is 0\n" \ " -plytake use first n moves to build openings, default is 20\n" \ " -plydelta random range for plytake, use for PGN/EPD books, default is 1\n" \ " -hit ignore nodes with number of games/hit under n, default is 1\n" \ diff --git a/src/records.cpp b/src/records.cpp index 20283f7..d4d648c 100644 --- a/src/records.cpp +++ b/src/records.cpp @@ -253,7 +253,8 @@ void ThreadRecord::resetStats() errCnt = gameCnt = nodeCnt = 0; } -void ThreadRecord::boardToNodes(std::map& nodeMap, const ParaRecord& paraRecord, const std::string& resultString) + +void ThreadRecord::boardToNodes(std::map& nodeMap, const ParaRecord& paraRecord, const std::string& resultString) { auto n = board->getHistListSize(); if (n < paraRecord.limitLen) { @@ -269,28 +270,18 @@ void ThreadRecord::boardToNodes(std::map& nodeMap, board2->newGame(board->getStartingFen()); for(auto i = 0, e = std::min(paraRecord.ply_take + paraRecord.ply_delta + 1, n); i < e; i++) { -// auto hashKey = board2->hashKey; - - auto epdString = board2->getEPD(true, false); + auto hashKey = board2->hashKey; auto hist = board->getHistAt(i); assert(hist.move.isValid()); - auto node = &nodeMap[epdString]; - if (node->moveMap.empty()) { + auto node = &nodeMap[hashKey]; + if (node->epd.empty()) { nodeCnt++; -// auto epdString = board2->getEPD(true, false); -// node->epd = epdString; + auto epdString = board2->getEPD(true, false); + node->epd = epdString; } else { -// if (node->epd != board2->getEPD(true, false)) { -// std::cout << "node->epd : " << node->epd -// << "\nboard2->getEPD: " << board2->getEPD(true, false) -// << std::endl; -// -// std::cout << "board:\n" << board->toString() << std::endl; -// std::cout << "board2:\n" << board2->toString() << std::endl; -// } -// assert(node->epd == board2->getEPD(true, false)); + assert(node->epd == board2->getEPD(true, false)); } auto moveInt = oobs::MoveWDL::move2Int(hist.move.from, hist.move.dest, hist.move.promotion, hist.castled); diff --git a/src/records.h b/src/records.h index a942f31..4a22086 100644 --- a/src/records.h +++ b/src/records.h @@ -106,7 +106,7 @@ class ThreadRecord void init(); void resetStats(); - void boardToNodes(std::map&, const ParaRecord&, const std::string&); + void boardToNodes(std::map&, const ParaRecord&, const std::string&); public: bslib::BoardCore *board = nullptr, *board2 = nullptr;