예제 #1
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;
}
예제 #2
0
/** Play prey move and update all the relevant information.
    Extend the prey by playing at its only liberty, or capture a block
    adjacent to the prey. */
int GoLadder::PlayPreyMove(int depth, SgPoint move, SgPoint lib1,
                           const GoPointList& adjBlk,
                           SgVector<SgPoint>* sequence)
{
    int result = 0;
    GoPointList newAdj(adjBlk);
    SgVector<SgPoint> newLib;
    SgVector<SgPoint> newStones;
    SgVector<SgPoint> neighbors;
    if (move == lib1)
    {
        NeighborsOfColor(*m_bd, move, m_preyColor, &neighbors);
        for (SgVectorIterator<SgPoint> iter(neighbors); iter; ++iter)
        {
            SgPoint block = *iter;
            if (! m_partOfPrey[block])
            {
                MarkStonesAsPrey(block, &newStones);
                GoPointList temp =
                    GoBoardUtil::AdjacentStones(*m_bd, block);
                newAdj.PushBackList(temp);
                for (GoBoard::LibertyIterator it(*m_bd, block); it; ++it)
                    newLib.Include(*it);
            }
        }
        m_partOfPrey.Include(move);
    }
    if (PlayIfLegal(*m_bd, move, m_preyColor))
    {
        if (move == lib1)
        {
            NeighborsOfColor(*m_bd, move, SG_EMPTY, &neighbors);
            for (SgVectorIterator<SgPoint> iter(newLib); iter; ++iter)
            {
                SgPoint point = *iter;
                // Test for Empty is necessary because newLib will include
                // the move just played.
                if (m_bd->IsEmpty(point))
                    neighbors.Include(point);
            }
        }
        else
        {
            neighbors.PushBack(lib1);
        }
        if (m_bd->CapturingMove())
        {   // Add the points at the captured stones that are adjacent to the
            // prey to the liberties, at least if exactly one stone captured.
            for (GoPointList::Iterator it(m_bd->CapturedStones()); it;
                 ++it)
            {
                SgPoint stone = *it;
                if (PointIsAdjToPrey(stone))
                    neighbors.Include(stone);
            }
        }
        SG_ASSERT(! neighbors.IsEmpty());
        lib1 = neighbors[0];
        SG_ASSERT(m_bd->IsEmpty(lib1));
        SgArrayList<SgPoint,4> temp =
            NeighborsOfColor(*m_bd, move, m_hunterColor);
        newAdj.PushBackList(temp);
        FilterAdjacent(newAdj);

        if (neighbors.Length() == 1)
            result = HunterLadder(depth + 1, lib1, newAdj, sequence);
        else if (neighbors.Length() == 2)
        {
            SgPoint lib2 = neighbors[1];
            SG_ASSERT(m_bd->IsEmpty(lib2));
            result = HunterLadder(depth + 1, lib1, lib2, newAdj, sequence);
        } 
        else // 3 <= numLib
        {
            if (sequence)
                sequence->Clear();
            result = GOOD_FOR_PREY - (depth + 1);
        }
        if (sequence)
            sequence->PushBack(move);
        m_bd->Undo();
    }
    else
    {
        if (sequence)
            sequence->Clear();
        result = GOOD_FOR_HUNTER + depth;
    }
    m_partOfPrey.Exclude(move);
    m_partOfPrey.Exclude(newStones);

    return result;
}