void TranspositionTable::extractPVMoves(const Position& rootPos, const Move& mFirst, std::vector<Move>& pv) { Position pos(rootPos); Move m(mFirst); UndoInfo ui; std::vector<U64> hashHistory; while (true) { pv.push_back(m); pos.makeMove(m, ui); if (contains(hashHistory, pos.zobristHash())) break; hashHistory.push_back(pos.zobristHash()); TTEntry ent; ent.clear(); probe(pos.historyHash(), ent); if (ent.getType() == TType::T_EMPTY) break; ent.getMove(m); MoveList moves; MoveGen::pseudoLegalMoves(pos, moves); MoveGen::removeIllegal(pos, moves); bool contains = false; for (int mi = 0; mi < moves.size; mi++) if (moves[mi].equals(m)) { contains = true; break; } if (!contains) break; } }
/** Extract the PV starting from posIn, using hash entries, both exact scores and bounds. */ std::string TranspositionTable::extractPV(const Position& posIn) { std::string ret; Position pos(posIn); bool first = true; TTEntry ent; ent.clear(); probe(pos.historyHash(), ent); UndoInfo ui; std::vector<U64> hashHistory; bool repetition = false; while (ent.getType() != TType::T_EMPTY) { Move m; ent.getMove(m); MoveList moves; MoveGen::pseudoLegalMoves(pos, moves); MoveGen::removeIllegal(pos, moves); bool valid = false; for (int mi = 0; mi < moves.size; mi++) if (moves[mi].equals(m)) { valid = true; break; } if (!valid) break; if (repetition) break; if (!first) ret += ' '; if (ent.getType() == TType::T_LE) ret += '<'; else if (ent.getType() == TType::T_GE) ret += '>'; std::string moveStr = TextIO::moveToString(pos, m, false); ret += moveStr; pos.makeMove(m, ui); if (contains(hashHistory, pos.zobristHash())) repetition = true; hashHistory.push_back(pos.zobristHash()); probe(pos.historyHash(), ent); first = false; } return ret; }