Пример #1
0
void GoAutoBook::ExportToOldFormat(GoAutoBookState& state, std::ostream& out,
                                   std::set<SgHashCode>& seen) const
{
    if (seen.count(state.GetHashCode()))
        return;
    SgBookNode node;
    if (! Get(state, node))
        return;
    if (node.IsTerminal() || node.IsLeaf())
        return;
    seen.insert(state.GetHashCode());
    SgPoint move = FindBestChild(state);
    // If no move to play here, do not include it in the book
    if (move == SG_NULLMOVE)
        return;
    const GoBoard& brd = state.Board();
    out << brd.Size() << ' ';
    for (int i = 0; i < brd.MoveNumber(); ++i)
        out << ' ' << SgWritePoint(brd.Move(i).Point());
    out << " | " << SgWritePoint(move);
    out << '\n';
    for (GoBoard::Iterator it(brd); it; ++it)
        if (brd.IsLegal(*it))
        {
            state.Play(*it);
            ExportToOldFormat(state, out, seen);
            state.Undo();
        }
}
Пример #2
0
void GoAutoBook::TruncateByDepth(int depth, GoAutoBookState& state, 
                                 GoAutoBook& other, 
                                 std::set<SgHashCode>& seen) const
{
    if (seen.count(state.GetHashCode()))
        return;
    SgBookNode node;
    if (! Get(state, node))
        return;
    seen.insert(state.GetHashCode());
    if (depth == 0)
    {
        // Set this node to be a leaf: copy its heuristic value into
        // its propagated value and set count to 0.
        node.m_count = 0;
        node.m_priority = SgBookNode::LEAF_PRIORITY;
        node.m_value = node.m_heurValue;
        other.Put(state, node);
        return;
    }
    other.Put(state, node);
    if (node.IsLeaf() || node.IsTerminal())
        return;
    for (GoBoard::Iterator it(state.Board()); it; ++it)
    {
        if (state.Board().IsLegal(*it))
        {
            state.Play(*it);
            TruncateByDepth(depth - 1, state, other, seen);
            state.Undo();
        }
    }
}
Пример #3
0
SgMove GoAutoBook::FindBestChild(GoAutoBookState& state) const
{
    std::size_t bestCount = 0;
    SgMove bestMove = SG_NULLMOVE;
    float bestScore = 100.0f;
    SgBookNode node;
    if (!Get(state, node))
        return SG_NULLMOVE;
    if (node.IsLeaf())
        return SG_NULLMOVE;
    for (GoBoard::Iterator it(state.Board()); it; ++it)
    {
        if (state.Board().IsLegal(*it))
        {
            state.Play(*it);
            if (m_disabled.count(state.GetHashCode()) > 0)
                SgDebug() << "Ignoring disabled move " 
                          << SgWritePoint(*it) << '\n';
            // NOTE: Terminal nodes aren't supported at this time, so 
            // we ignore them here.
            else if (Get(state, node) 
                     && !node.IsTerminal() 
                     && node.m_count >= m_param.m_usageCountThreshold)
            {
                if (m_param.m_selectType == GO_AUTOBOOK_SELECT_COUNT)
                {
                    // Select by count, tiebreak by value.
                    if (node.m_count > bestCount)
                    {
                        bestCount = node.m_count;
                        bestMove = *it;
                        bestScore = node.m_value;
                    }
                    // NOTE: do not have access to inverse function,
                    // so we're minimizing here as a temporary solution. 
                    else if (node.m_count == bestCount
                             && node.m_value < bestScore)
                    {
                        bestMove = *it;
                        bestScore = node.m_value;
                    }
                }
                else if (m_param.m_selectType == GO_AUTOBOOK_SELECT_VALUE)
                {
                    // NOTE: do not have access to inverse function,
                    // so we're minimizing here as a temporary solution. 
                    if (node.m_value < bestScore)
                    {
                        bestMove = *it;
                        bestScore = node.m_value;
                    }
                }
            }
            state.Undo();
        }
    }
    return bestMove;
}
Пример #4
0
SgMove GoAutoBook::FindBestChild(GoAutoBookState& state) const
{
    std::size_t bestCount = 0;
    SgMove bestMove = SG_NULLMOVE;
    SgMove bestIgnoredMove = SG_NULLMOVE;
    float bestScore = 100.0f;
    float bestIgnoredMoveScore = 100.0f;
    SgBookNode node;
    // Check for forced moves first
    // Note this will check for forced moves even if the current
    // state is not in the book.
    for (GoBoard::Iterator it(state.Board()); it; ++it)
    {
        if (state.Board().IsLegal(*it))
        {
            state.Play(*it);
            if (m_forced.count(state.GetHashCode()) > 0)
            {
                SgDebug() << "Playing forced move " 
                          << SgWritePoint(*it) << '\n';
                return *it;
            }
            state.Undo();
        }
    }
    if (! Get(state, node))
        return SG_NULLMOVE;
    if (node.IsLeaf())
        return SG_NULLMOVE;
    for (GoBoard::Iterator it(state.Board()); it; ++it)
    {
        if (state.Board().IsLegal(*it))
        {
            state.Play(*it);
            if (m_disabled.count(state.GetHashCode()) > 0)
                SgDebug() << "Ignoring disabled move " 
                          << SgWritePoint(*it) << '\n';
            // NOTE: Terminal nodes aren't supported at this time, so 
            // we ignore them here.
            else if (  Get(state, node) 
                    && ! node.IsTerminal() 
                    )
            {
            	if (node.m_count >= m_param.m_usageCountThreshold)
                {
                    if (m_param.m_selectType == GO_AUTOBOOK_SELECT_COUNT)
                    {
                        // Select by count, tiebreak by value.
                        if (node.m_count > bestCount)
                        {
                            bestCount = node.m_count;
                            bestMove = *it;
                            bestScore = node.m_value;
                        }
                        // NOTE: do not have access to inverse function,
                        // so we're minimizing here as a temporary solution. 
                        else if (node.m_count == bestCount
                                 && node.m_value < bestScore)
                        {
                            bestMove = *it;
                            bestScore = node.m_value;
                        }
                    }
                    else if (m_param.m_selectType == GO_AUTOBOOK_SELECT_VALUE)
                    {
                        // NOTE: do not have access to inverse function,
                        // so we're minimizing here as a temporary solution. 
                        if (node.m_value < bestScore)
                        {
                            bestMove = *it;
                            bestScore = node.m_value;
                        }
                    }
                }
                else // node.m_count < m_param.m_usageCountThreshold
                if (  m_param.m_selectType == GO_AUTOBOOK_SELECT_VALUE
                   && node.m_value < bestIgnoredMoveScore
                   )
                {
                   bestIgnoredMove = *it;
                   bestIgnoredMoveScore = node.m_value;
                }
            }
            state.Undo();
        }
    }
    if (bestMove != SG_NULLMOVE && bestIgnoredMoveScore < bestScore)
    {
        SgDebug() << "Ignoring autobook move "
        << SgWritePoint(bestMove)
        << " since best ignored inverse value " 
        << std::setprecision(5)
        << bestIgnoredMoveScore
        << " of move " 
        << SgWritePoint(bestIgnoredMove)
        << " is better than best value above usage threshold " 
        << bestScore << '\n';
        
    	return SG_NULLMOVE;
    }
    return bestMove;
}