Пример #1
0
/** 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;
}
/** 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;
}
Пример #3
0
SgPointSet SpUtil::GetRelevantMoves(GoBoard& bd, SgBlackWhite toPlay,
                                    bool useFilter)
{
    SgPointSet legal;
    for (SgSetIterator it(bd.AllEmpty()); it; ++it)
        if (bd.IsLegal(*it))
            legal.Include(*it);
    if (! useFilter)
        return legal;
    GoSafetySolver safetySolver(bd);
    SgBWSet safe;
    safetySolver.FindSafePoints(&safe);
    SgBlackWhite opp = SgOppBW(toPlay);
    SgPointSet moves;
    const GoRules& rules = bd.Rules();
    const bool captureDead = rules.CaptureDead();
    //const bool japaneseScoring = rules.JapaneseScoring();
    for (SgSetIterator it(legal); it; ++it)
    {
        SgPoint p = *it;
        const bool isSafe = safe[toPlay].Contains(p);
        const bool isSafeOpp = safe[opp].Contains(p);
        const bool hasOppNeighbors = bd.HasNeighbors(p, opp);
        if (  (! isSafe && ! isSafeOpp)
           || (isSafe && captureDead && hasOppNeighbors)
           // || (isSafeOpp && ! japaneseScoring)
           )
            moves.Include(p);
    }
    return moves;
}
Пример #4
0
void GoBlock::CheckConsistency() const
{
    SG_ASSERT(Stones().SubsetOf(m_bd.All(Color())));
    SgPoint anchor = Anchor();
    SG_ASSERT(m_bd.Anchor(anchor) == Anchor());
    SgPointSet stones;
    for (GoBoard::StoneIterator it(m_bd, anchor); it; ++it)
        stones.Include(*it);
    SG_ASSERT(Stones() == stones);
}
Пример #5
0
// improved by using recursive extension to find 2-conn paths.
bool GoRegion::Find2ConnForAllInterior(SgMiaiStrategy* miaiStrategy,
                                       SgVector<SgPoint>& usedLibs) const
{
    SgVector<SgMiaiPair> myStrategy;
    const int size = m_bd.Size();
    SgPointSet interior = AllInsideLibs();
    if (interior.IsEmpty())
    {
        return true;
    }
    //if (GetFlag(GO_REGION_SINGLE_BLOCK_BOUNDARY))
    {
        SgPointSet testSet = interior;
        SgPointSet originalLibs = testSet.Border(size) & Dep().Border(size)
                                & m_bd.AllEmpty() & Points();
        SgPointSet updateLibs = originalLibs;

        // now try to find miai-paths to remaining interior points recursively
        bool changed = true;
        while (changed)
        {
            changed = false;
            if (testSet.IsEmpty())
            {
                SgVector<SgPoint> jlibs;
                JointLibs(&jlibs);
                SgVector<SgPoint> ips;
                GetIPs(&ips);
                SgVector<SgMiaiPair> updateStrg;

                for (SgSetIterator it(interior); it; ++it)
                {
                    SgPoint p = *it;
                    SgPointSet s1;
                    s1.Include(p);
                    SgPointSet rest = s1.Border(size) & updateLibs;
                    if (! rest.IsEmpty())
                    {
                        for (SgVectorIterator<SgMiaiPair> it2(myStrategy);
                             it2; ++it2)
                        {
                            SgMiaiPair x = *it2;
                            if (   SgPointUtil::AreAdjacent(p, x.first)
                                && SgPointUtil::AreAdjacent(p, x.second)
                               )
                            {
                                if (ips.Contains(x.first))
                                {
                                    updateLibs.Include(x.first);
                                    usedLibs.Exclude(x.first);
                                    SgPoint t = rest.PointOf();
                                    x.first = t;
                                    updateLibs.Exclude(t);
                                    rest.Exclude(t);
                                    usedLibs.Include(t);
                                }
                                if (  ips.Contains(x.second)
                                   && ! rest.IsEmpty()
                                   )
                                {
                                    updateLibs.Include(x.second);
                                    usedLibs.Exclude(x.second);
                                    SgPoint t = rest.PointOf();
                                    x.second = t;
                                    updateLibs.Exclude(t);
                                    rest.Exclude(t);
                                    usedLibs.Include(t);
                                }
                                updateStrg.Include(x);
                            }
                        }
                    }
                }
                miaiStrategy->SetStrategy(updateStrg);
                /* */ return true; /* */
            }
            for (SgSetIterator it(interior); it; ++it)
            {
                SgMiaiPair miaiPair;
                if (Find2BestLibs(*it, updateLibs, testSet, &miaiPair))
                {
                    if (miaiPair.first == miaiPair.second)
                    {
                        SgDebug() <<"\nmiaipair are same: "
                                  << SgWritePoint(miaiPair.first)
                                  << SgWritePoint(miaiPair.second);
                        SgDebug() <<"\ncurrent region is:\n";
                        Points().Write(SgDebug(), size);
                        SG_ASSERT(false);
                    }
                    myStrategy.PushBack(miaiPair);
                    usedLibs.PushBack(miaiPair.first);
                    usedLibs.PushBack(miaiPair.second);
                    updateLibs.Exclude(miaiPair.first);
                    updateLibs.Exclude(miaiPair.second);
                    updateLibs.Include(*it);
                    testSet.Exclude(*it);
                    changed = true;
                }
            }
        } // while  loop for recursive finding
    }
    miaiStrategy->Clear();
    return false;
}
Пример #6
0
bool GoEyeUtil::NumberOfMoveToEye2(const GoBoard& board, SgBlackWhite color,
                                   SgPoint p, int& nummoves)
{
    nummoves = 0;
    bool capturing = false;
    SgVector<SgPoint> usedpoints;
    usedpoints.PushBack(p);
    SgPointSet counted;

    // Can never turn own stone into an eye
    if (board.IsColor(p, color))
        return false;
    
    // If opponent stone then it must be captured to make eye
    if (board.IsColor(p, SgOppBW(color)))
    {
        capturing = true;
    
        // If it is obviously safe then it can never be an eye
        if (SinglePointSafe2(board, p)) // Quick, naive safety test
            return false;

        for (GoBoard::LibertyIterator libit(board, p); libit; ++libit)
            counted.Include(*libit);
    }

    // Count immediate adjacencies
    for (SgNb4Iterator nb(p); nb; ++nb)
    {
        SgPoint adj = *nb;
        
        // Empty points must be filled
        if (board.IsColor(adj, SG_EMPTY))
        {
            counted.Include(adj);
        }
        
        // If adjacent opponent then can never be an eye
        else if (board.IsColor(adj, SgOppBW(color)))
        {
            if (capturing)
                counted.Include(adj); // must capture and then fill
            else
                return false;
        }
    }

    // Up to one diagonal can be ignored: estimate most costly
    SgPoint toignore = SG_NULLPOINT;
    int maxcost = 0;
    int infcost = 1000;
    if (board.Line(p) > 1)
    {
        for (SgNb4DiagIterator nbd(p); nbd; ++nbd)
        {
            SgPoint diag = *nbd;
            int cost = 0;

            if (  board.IsColor(diag, SG_EMPTY)
               && ! IsSinglePointEye2(board, diag, color, usedpoints))
            {
                cost = 1;
            }
            
            else if (board.IsColor(diag, SgOppBW(color)))
            {
                // quick safety test
                if (SinglePointSafe2(board, diag))
                    cost = infcost;
                else
                    cost = board.NumLiberties(diag);
            }

            if (cost > maxcost)
            {
                maxcost = cost;
                toignore = diag;
            }
        }
    }

    // Now mark points that must be played to secure diagonals
    for (SgNb4DiagIterator nbd(p); nbd; ++nbd)
    {
        SgPoint diag = *nbd;
        if (diag == toignore)
            continue;
        
        // Empty points must be filled (unless they are eyes)
        if (  board.IsColor(diag, SG_EMPTY)
           && ! IsSinglePointEye2(board, diag, color, usedpoints))
        {
            counted.Include(diag);
        }
        
        // Opponent stones on diagonals must be captured and filled
        else if (board.IsColor(diag, SgOppBW(color)))
        {
            if (SinglePointSafe2(board, diag))
                return false;
            else
            {
                counted.Include(diag);
                for (GoBoard::LibertyIterator libit(board, diag); libit;
                     ++libit)
                    counted.Include(*libit);
            }
        }
    }

    nummoves = counted.Size();
    return true;
}