Пример #1
0
SgPoint GoUctSearchUtil::TrompTaylorPassCheck(SgPoint move,
                                              const GoUctSearch& search)
{
    const GoBoard& bd = search.Board();
    bool isFirstPass = (bd.GetLastMove() != SG_PASS);
    bool isTrompTaylorRules = bd.Rules().CaptureDead();
    if (move != SG_PASS || ! isTrompTaylorRules || ! isFirstPass)
        return move;
    float komi = bd.Rules().Komi().ToFloat();
    float trompTaylorScore = GoBoardUtil::TrompTaylorScore(bd, komi);
    if (search.ToPlay() != SG_BLACK)
        trompTaylorScore *= -1;
    const SgUctTree& tree = search.Tree();
    const SgUctNode& root = tree.Root();
    SgUctValue value = root.Mean();
    SgUctValue trompTaylorWinValue = (trompTaylorScore > 0 ? 1 : 0);
    if (value < trompTaylorWinValue)
        return move;
    SgDebug() << "GoUctSearchUtil::TrompTaylorPassCheck: bad pass move value="
              << value << " trompTaylorScore=" << trompTaylorScore << '\n';
    std::vector<SgMove> excludeMoves;
    excludeMoves.push_back(SG_PASS);
    const SgUctNode* bestChild = search.FindBestChild(root, &excludeMoves);
    if (bestChild == 0)
    {
        SgDebug() <<
            "GoUctSearchUtil::TrompTaylorPassCheck: "
            "(no second best move found)\n";
        return move;
    }
    return bestChild->Move();
}
void GoUctEstimatorStat::Compute(GoUctSearch& search,
                                 std::size_t trueValueMaxGames,
                                 std::size_t maxGames,
                                 std::size_t stepSize,
                                 const std::string& fileName)
{
    double maxTime = std::numeric_limits<double>::max();
    vector<SgUctMoveInfo> moves;
    search.GenerateAllMoves(moves);
    SgArray<SgUctValue,SG_PASS + 1> trueValues;
    for (size_t i = 0; i < moves.size(); ++i)
    {
        SgPoint p = moves[i].m_move;
        GoModBoard modBoard(search.Board());
        modBoard.Board().Play(p);
        vector<SgMove> sequence;
        SgUctValue value =
            search.Search(SgUctValue(trueValueMaxGames), maxTime, sequence);
        trueValues[p] = SgUctSearch::InverseEstimate(value);
        modBoard.Board().Undo();
    }
    search.StartSearch();
    if (search.MpiSynchronizer()->IsRootProcess())
    {
        std::ofstream out(fileName.c_str(), std::ios::app);
        for (size_t n = 0; n < maxGames; n += stepSize)
        {
            search.PlayGame();
            for (size_t i = 0; i < moves.size(); ++i)
            {
            SgPoint p = moves[i].m_move;
            const SgUctTree& tree = search.Tree();
            const SgUctNode* child =
                SgUctTreeUtil::FindChildWithMove(tree, tree.Root(), p);
            if (child == 0)
                continue; // Root may not have been expanded yet
            out << (format("%1$d\t"
                       "%2$.2f\t"
                       "%3$d\t"
                       "%4$.2f\t"
                       "%5$d\t"
                       "%6$.2f\n"
                       )
                % n // 1
                % trueValues[p] // 2
                % child->MoveCount() // 3
                % (child->HasMean() ?
                   SgUctSearch::InverseEstimate(child->Mean()) : 0) // 4
                % child->RaveCount() // 5
                % (child->HasRaveValue() ? child->RaveValue() : 0) // 6
                );
            }
        }
    }
    search.EndSearch();
}