/** Find global moves that match a playout pattern or set a block into atari.
    @param[out] pattern
    @param[out] atari
    @param[out] empty As a side effect, this function finds all empty points
    on the board
    @return @c true if any such moves was found */
bool GoUctDefaultPriorKnowledge::FindGlobalPatternAndAtariMoves(
                                                     SgPointSet& pattern,
                                                     SgPointSet& atari,
                                                     GoPointList& empty)
{
	// Minimum value for pattern gamma to be used.
    static const float EPSILON = 0.00000000001;
    const GoBoard& bd = Board();
    SG_ASSERT(empty.IsEmpty());
    const GoUctPatterns<GoBoard>& patterns = m_policy.GlobalPatterns();
    bool result = false;
    m_maxPatternGamma = -1.f;
    for (GoBoard::Iterator it(bd); it; ++it)
        if (bd.IsEmpty(*it))
        {
            empty.PushBack(*it);
            float gamma = patterns.GetPatternGamma(bd, *it, bd.ToPlay());
            if (gamma > EPSILON)
            {
                pattern.Include(*it);
                result = true;
                m_patternGammas[*it] = gamma;
                if (gamma > m_maxPatternGamma)
                    m_maxPatternGamma = gamma;
            }
            if (SetsAtari(bd, *it))
            {
                atari.Include(*it);
                result = true;
            }
        }
    return result;
}
示例#2
0
void GoLadder::ReduceToBlocks(GoPointList& stones)
{
    // Single block is frequent case, don't compute block.
    if (stones.IsEmpty())
        ; // nothing to do
    else if (stones.Length() <= 1)
    {
        if (m_bd->IsEmpty(stones[0]))
            stones.Clear();
    }
    else
    {
        GoPointList visited;
        // TODO: create SgMarker member in GoLadder and use it for visited
        // points
        GoPointList result;
        for (GoPointList::Iterator it(stones); it; ++it)
        {
            SgPoint stone = *it;
            if (m_bd->Occupied(stone) && ! visited.Contains(stone))
            {
                result.PushBack(stone);
                for (GoBoard::StoneIterator it(*m_bd, stone); it; ++it)
                    visited.PushBack(*it);
            }
        }
        stones = result;
    }
}
/** Find global moves that match a playout pattern or set a block into atari.
    @param[out] pattern
    @param[out] atari
    @param[out] empty As a side effect, this function finds all empty points
    on the board
    @return @c true if any such moves was found
*/
bool GoUctDefaultPriorKnowledge::FindGlobalPatternAndAtariMoves(
                                                     SgPointSet& pattern,
                                                     SgPointSet& atari,
                                                     GoPointList& empty) const
{
    SG_ASSERT(empty.IsEmpty());
    const GoUctPatterns<GoBoard>& patterns = m_policy.Patterns();
    bool result = false;
    for (GoBoard::Iterator it(m_bd); it; ++it)
        if (m_bd.IsEmpty(*it))
        {
            empty.PushBack(*it);
            if (patterns.MatchAny(*it))
            {
                pattern.Include(*it);
                result = true;
            }
            if (SetsAtari(m_bd, *it))
            {
                atari.Include(*it);
                result = true;
            }
        }
    return result;
}
示例#4
0
int GoLadder::HunterLadder(int depth, SgPoint lib1, SgPoint lib2, 
                           const GoPointList& adjBlk,
                           SgVector<SgPoint>* sequence)
{
    if (CheckMoveOverflow())
        return GOOD_FOR_PREY;
    int result = 0;
    if (m_bd->NumEmptyNeighbors(lib1) < m_bd->NumEmptyNeighbors(lib2))
    {
        swap(lib1, lib2);
    }
    if (m_bd->NumEmptyNeighbors(lib1) == 3
        && ! SgPointUtil::AreAdjacent(lib1, lib2))
    {
        // If not playing at lib1, then prey will play at lib1 and
        // get three liberties; little to update in this case.
        m_bd->Play(lib1, m_hunterColor);
        result = PreyLadder(depth + 1, lib2, adjBlk, sequence);
        if (sequence)
            sequence->PushBack(lib1);
        m_bd->Undo();
    }
    else
    {
        // Two liberties, hunter to play, but not standard case.
        if (! adjBlk.IsEmpty()
            && *GoBoard::LibertyIterator(*m_bd, adjBlk[0]) == lib2)
        {
            swap(lib1, lib2); // protect hunter blocks in atari
        }
        result = PlayHunterMove(depth, lib1, lib1, lib2,
                                adjBlk, sequence);
        if (0 <= result) // escaped
        {
            if (sequence)
            {
                SgVector<SgPoint> seq2;
                int result2 = PlayHunterMove(depth, lib2, lib1, lib2,
                                             adjBlk, &seq2);
                if (result2 < result)
                {   result = result2;
                    sequence->SwapWith(&seq2);
                }
            }
            else
            {
                int result2 = PlayHunterMove(depth, lib2, lib1, lib2,
                                             adjBlk, 0);
                if (result2 < result)
                    result = result2;
            }
        }
    }
    return result;
}