void GoRegionBoard::MergeAdjacentAndAddBlock(SgPoint move,
                                             SgBlackWhite capturedColor)
{
    SgVector<SgPoint> nb;
    for (GoNbIterator it(Board(), move); it; ++it)
        if (Board().IsEmpty(*it))
            nb.PushBack(*it);

    SgVectorOf<GoBlock> captures;
    PreviousBlocksAt(nb, capturedColor, &captures);
    SG_ASSERT(captures.NonEmpty());

    SgPointSet captured;
    {for (SgVectorIteratorOf<GoBlock> it(captures); it; ++it)
        captured |= (*it)->Stones();
    }
    SgVectorOf<GoRegion> adj;
    const int size = Board().Size();
    RegionsAt(captured.Border(size), capturedColor, &adj);
    SG_ASSERT(adj.NonEmpty());
    GoRegion* r = MergeAll(adj, captured, capturedColor);
    SG_UNUSED(r);

    for (SgVectorIteratorOf<GoBlock> it(captures); it; ++it)
        RemoveBlock(*it, true, false);
        // don't remove from regions; already gone.
}
void GoRegionBoard::RemoveBlock(GoBlock* b, bool isExecute,
                                     bool removeFromRegions)
{
    SgBlackWhite color = b->Color();
    for (SgSetIterator it(b->Stones()); it; ++it)
        m_block[*it] = 0;

    bool found = m_allBlocks[color].Exclude(b);
    SG_UNUSED(found);
    SG_ASSERT(found);
    const int size = Board().Size();
    // remove from regions.
    SgPointSet area(b->Stones().Border(size));
    SgVectorOf<GoRegion> regions;
    if (removeFromRegions)
    {
        RegionsAt(area, color, &regions);
        for (SgVectorIteratorOf<GoRegion> it(regions); it; ++it)
        {
            (*it)->RemoveBlock(b);
            if (isExecute)
                m_stack.PushPtr(*it);
        }
    }
    if (isExecute)
    {
        m_stack.PushInt(regions.Length()); // 0 if ! removeFromRegions
        PushBlock(REGION_REMOVE_BLOCK, b);
    }
    else
        delete b;
}
示例#3
0
SgVectorOf<GoBlock> GoRegion::InteriorBlocks() const
{
    SgVectorOf<GoBlock> interior;
    for (SgVectorIteratorOf<GoBlock> it(m_blocks); it; ++it)
        if (IsInteriorBlock(*it))
            interior.PushBack(*it);
    return interior;
}
void GoRegionBoard::FindNewNeighborRegions(SgPoint move,
                                                BlackWhite moveColor)
{ // move was capture -> new region for each captured block.

    SgVector<SgPoint> nb;
    for (Nb4Iterator it(move); it; ++it)
        if (Board().IsEmpty(*it))
            nb.PushBack(*it);

    SgVectorOf<GoBlock> captures;
    PreviousBlocksAt(nb, OppBW(moveColor), &captures);
    SG_ASSERT(captures.NonEmpty());

    for (SgVectorIteratorOf<GoBlock> it(captures); it; ++it)
        BlockToRegion(*it);
}
示例#5
0
void GoSafetySolver::FindTestSets(SgVectorOf<SgVectorOf<GoBlock> >* sets,
                                  SgBlackWhite color) const
{
    SG_ASSERT(sets->IsEmpty());
    SgVectorOf<GoBlock> doneSoFar;
    for (SgVectorIteratorOf<GoChain>
         it(Regions()->AllChains(color)); it; ++it)
    {
        GoBlock* block = *it;
        if (! doneSoFar.Contains(block))
        {
            SgVectorOf<GoBlock>* blocks = new SgVectorOf<GoBlock>;
            blocks->PushBack(block);
            
            FindClosure(blocks);
            doneSoFar.PushBackList(*blocks);
            sets->PushBack(blocks);
        }
    }
}
示例#6
0
void GoRegion::SetBlocks(const SgVectorOf<GoBlock>& blocks)
{
    SG_ASSERT(m_blocks.IsEmpty());
    SG_ASSERT(! blocks.IsEmpty());
    const int size = m_bd.Size();
    SgPointSet area(Points().Border(size));
    for (SgVectorIteratorOf<GoBlock> it(blocks); it; ++it)
    {
        if ((*it)->Stones().Overlaps(area))
            m_blocks.PushBack(*it);
    }
    m_computedFlags.set(GO_REGION_COMPUTED_BLOCKS);
}
void GoRegionBoard::UpdateBlock(int move, SgBlackWhite moveColor)
{
    SgPoint anchor = Board().Anchor(move); // board is already up to date.
    bool done = false;
    const int size = Board().Size();
    if (! Board().IsSingleStone(move)) // find old neighbor blocks
    {
        SgVectorOf<GoBlock> old;
        for (GoNbIterator it(Board(), move); it; ++it)
        {
            if (IsColor(*it, moveColor))
                old.Include(BlockAt(*it));
        }
        if (old.IsLength(1)) // append to single neighbor block
        {
            GoBlock* b = old.Front();
            AppendStone(b, move);
            done = true;
        }
        else // delete old, recompute
        {
            for (SgVectorIteratorOf<GoBlock> it(old); it; ++it)
                RemoveBlock(*it, true, true);
        }
    }

    if (! done) // create new block.
    {
        GoBlock* b = GenBlock(anchor, moveColor);
        SgPointSet area(b->Stones().Border(size));
        // link it to neighbor regions
        SgVectorOf<GoRegion> regions;
        RegionsAt(area, moveColor, &regions);
        for (SgVectorIteratorOf<GoRegion> it(regions); it; ++it)
            (*it)->BlocksNonConst().PushBack(b);
    }
}
void GoRegionBoard::OnUndoneMove()
// Called after a move has been undone. The board is guaranteed to be in
// a legal state.
{
    //SG_ASSERT(false); // incremental code is incomplete, do not call
    if (DEBUG_REGION_BOARD)
        SgDebug() << "OnUndoneMove " << '\n';

    const bool IS_UNDO = false;
    SgVectorOf<GoRegion> changed;

    for (int val = m_stack.PopEvent(); val != SG_NEXTMOVE;
         val = m_stack.PopEvent())
    {

        switch (val)
        {
            case REGION_REMOVE:
            {   GoRegion* r = static_cast<GoRegion*>(m_stack.PopPtr());
                AddRegion(r, IS_UNDO);
                changed.Insert(r);
            }
            break;
            case REGION_ADD:
            {   GoRegion* r = static_cast<GoRegion*>(m_stack.PopPtr());
                RemoveRegion(r, IS_UNDO);
            }
            break;
            case REGION_REMOVE_BLOCK:
            {   GoBlock* b = static_cast<GoBlock*>(m_stack.PopPtr());
                AddBlock(b, IS_UNDO);
                for (int nu = m_stack.PopInt(); nu > 0; --nu)
                {
                    GoRegion* r = static_cast<GoRegion*>(m_stack.PopPtr());
                    if (CHECK)
                        SG_ASSERT(! r->Blocks().Contains(b));
                    r->BlocksNonConst().PushBack(b);
                    changed.Insert(r);
                }
            }
            break;
            case REGION_ADD_BLOCK:
            {   GoBlock* b = static_cast<GoBlock*>(m_stack.PopPtr());
                RemoveBlock(b, IS_UNDO, true);
            }
            break;
            case REGION_ADD_STONE:
            {   GoRegion* r = static_cast<GoRegion*>(m_stack.PopPtr());
                SgPoint p = m_stack.PopInt();
                r->OnRemoveStone(p);
                m_region[r->Color()][p] = r;
                changed.Insert(r);
            }
            break;
            case REGION_ADD_STONE_TO_BLOCK:
            {   GoBlock* b = static_cast<GoBlock*>(m_stack.PopPtr());
                SgPoint p = m_stack.PopInt();
                b->RemoveStone(p);
                m_block[p] = 0;
            }
            break;
            default:
                SG_ASSERT(false);
        }
    }

    for (SgVectorIteratorOf<GoRegion> it(changed); it; ++it)
    {
        (*it)->ResetNonBlockFlags();
        (*it)->ComputeBasicFlags();
    }

    if (HEAVYCHECK)
    {
        for (SgBWIterator it; it; ++it)
        {
            SgBlackWhite color(*it);
            for (SgVectorIteratorOf<GoRegion> it(AllRegions(color)); it; ++it)
            {
                const GoRegion* r = *it;
                SG_UNUSED(r);
                SG_ASSERT(r->IsValid());
            }
        }
    }

    m_code = Board().GetHashCode();
    if (HEAVYCHECK)
        CheckConsistency();
}