Index   Main   Namespaces   Classes   Hierarchy   Annotated   Files   Compound   Global   Pages  

GoRegionBoard.cpp

Go to the documentation of this file.
00001 //----------------------------------------------------------------------------
00002 /** @file GoRegionBoard.cpp
00003     See GoRegionBoard.h. */
00004 //----------------------------------------------------------------------------
00005 
00006 #include "SgSystem.h"
00007 #include "GoRegionBoard.h"
00008 
00009 #include <iostream>
00010 #include "GoBlock.h"
00011 #include "GoChain.h"
00012 #include "GoEyeUtil.h"
00013 #include "GoRegion.h"
00014 #include "SgDebug.h"
00015 #include "SgConnCompIterator.h"
00016 #include "SgWrite.h"
00017 
00018 //----------------------------------------------------------------------------
00019 
00020 namespace {
00021 static const bool CHECK = SG_CHECK && true;
00022 
00023 static const bool HEAVYCHECK = SG_HEAVYCHECK && CHECK && false;
00024 
00025 static const bool DEBUG_REGION_BOARD = false;
00026 
00027 const int REGION_CODE_BASE = 2000;
00028 const int REGION_REMOVE = REGION_CODE_BASE + 0;
00029 const int REGION_ADD = REGION_CODE_BASE + 1;
00030 const int REGION_REMOVE_BLOCK = REGION_CODE_BASE + 2;
00031 const int REGION_ADD_BLOCK = REGION_CODE_BASE + 3;
00032 const int REGION_ADD_STONE = REGION_CODE_BASE + 4;
00033 const int REGION_ADD_STONE_TO_BLOCK = REGION_CODE_BASE + 5;
00034 }
00035 //----------------------------------------------------------------------------
00036 
00037 bool GoRegionBoard::IsSafeBlock(SgPoint p) const
00038 {
00039     return BlockAt(p)->IsSafe();
00040 }
00041 
00042 void GoRegionBoard::SetToSafe(SgPoint p) const
00043 {
00044     BlockAt(p)->SetToSafe();
00045 }
00046 
00047 void GoRegionBoard::Fini()
00048 {
00049     SG_ASSERT(s_alloc == s_free);
00050 }
00051 
00052 
00053 void GoRegionBoard::SetSafeFlags(const SgBWSet& safe)
00054 {
00055     for (SgBWIterator it; it; ++it)
00056     {
00057         SgBlackWhite color(*it);
00058         for (SgVectorIteratorOf<GoRegion> it(AllRegions(color)); it; ++it)
00059             if ((*it)->Points().Overlaps(safe[color]))
00060                 (*it)->SetToSafe();
00061         for (SgVectorIteratorOf<GoBlock> it(AllBlocks(color)); it; ++it)
00062             if ((*it)->Stones().Overlaps(safe[color]))
00063                 (*it)->SetToSafe();
00064     }
00065 }
00066 
00067 //----------------------------------------------------------------------------
00068 
00069 GoRegionBoard::GoRegionBoard(const GoBoard& board)
00070     : m_board(board),
00071       m_region(SgPointArray<GoRegion*>(0)),
00072       m_block(0),
00073       m_invalid(true),
00074       m_computedHealthy(false),
00075       m_boardSize(board.Size())
00076 {
00077     m_code.Invalidate();
00078     m_chainsCode.Invalidate();
00079     GenBlocksRegions();
00080     ++s_alloc;
00081 }
00082 
00083 GoRegionBoard::~GoRegionBoard()
00084 {
00085     Clear();
00086     ++s_free;
00087 }
00088 
00089 void GoRegionBoard::Clear()
00090 {
00091     if (DEBUG_REGION_BOARD)
00092         SgDebug() << "Clear\n";
00093     for (SgBWIterator it; it; ++it)
00094     {
00095         SgBlackWhite color(*it);
00096         for (SgVectorIteratorOf<GoBlock> it1(AllBlocks(color)); it1; ++it1)
00097             delete *it1;
00098         for (SgVectorIteratorOf<GoRegion> it2(AllRegions(color)); it2; ++it2)
00099             delete *it2;
00100         for (SgVectorIteratorOf<GoChain> it3(AllChains(color)); it3; ++it3)
00101             delete *it3;
00102     }
00103     m_allBlocks[SG_BLACK].Clear();
00104     m_allBlocks[SG_WHITE].Clear();
00105     m_allRegions[SG_BLACK].Clear();
00106     m_allRegions[SG_WHITE].Clear();
00107     m_allChains[SG_BLACK].Clear();
00108     m_allChains[SG_WHITE].Clear();
00109     m_stack.Clear();
00110     m_code.Invalidate();
00111     m_invalid = true;
00112     m_computedHealthy = false;
00113     m_boardSize = m_board.Size();
00114 
00115     for (SgBWIterator it; it; ++it)
00116     {
00117         SgBlackWhite color(*it);
00118         for (SgPoint p = SgPointUtil::Pt(1, 1);
00119              p <= SgPointUtil::Pt(SG_MAX_SIZE, SG_MAX_SIZE);
00120              ++p)
00121         {
00122             m_region[color][p] = 0;
00123         }
00124     }
00125     for (SgPoint p = SgPointUtil::Pt(1, 1);
00126          p <= SgPointUtil::Pt(SG_MAX_SIZE, SG_MAX_SIZE); ++p)
00127         m_block[p] = 0;
00128 }
00129 
00130 void GoRegionBoard::UpdateBlock(int move, SgBlackWhite moveColor)
00131 {
00132     SgPoint anchor = Board().Anchor(move); // board is already up to date.
00133     bool done = false;
00134     const int size = Board().Size();
00135     if (! Board().IsSingleStone(move)) // find old neighbor blocks
00136     {
00137         SgVectorOf<GoBlock> old;
00138         for (SgNb4Iterator it(move); it; ++it)
00139         {
00140             if (IsColor(*it, moveColor))
00141                 old.Include(BlockAt(*it));
00142         }
00143         if (old.IsLength(1)) // append to single neighbor block
00144         {
00145             GoBlock* b = old.Front();
00146             AppendStone(b, move);
00147             done = true;
00148         }
00149         else // delete old, recompute
00150         {
00151             for (SgVectorIteratorOf<GoBlock> it(old); it; ++it)
00152                 RemoveBlock(*it, true, true);
00153         }
00154     }
00155 
00156     if (! done) // create new block.
00157     {
00158         GoBlock* b = GenBlock(anchor, moveColor);
00159         SgPointSet area(b->Stones().Border(size));
00160         // link it to neighbor regions
00161         SgVectorOf<GoRegion> regions;
00162         RegionsAt(area, moveColor, &regions);
00163         for (SgVectorIteratorOf<GoRegion> it(regions); it; ++it)
00164             (*it)->BlocksNonConst().PushBack(b);
00165     }
00166 }
00167 
00168 void GoRegionBoard::AppendStone(GoBlock* b, SgPoint move)
00169 {
00170     m_block[move] = b;
00171     b->AddStone(move);
00172     m_stack.PushInt(move);
00173     m_stack.PushPtrEvent(REGION_ADD_STONE_TO_BLOCK, b);
00174 }
00175 
00176 
00177 void GoRegionBoard::OnExecutedMove(GoPlayerMove move)
00178 {
00179     OnExecutedUncodedMove(move.Point(), move.Color());
00180 }
00181 
00182 void GoRegionBoard::ExecuteMovePrologue()
00183 {
00184     if (! UpToDate()) // full recomputation
00185     {
00186         if (DEBUG_REGION_BOARD)
00187             SgDebug() << "recompute everything\n";
00188         GenBlocksRegions();
00189     }
00190 }
00191 
00192 void GoRegionBoard::OnExecutedUncodedMove(int move, SgBlackWhite moveColor)
00193 {
00194     if (DEBUG_REGION_BOARD)
00195         SgDebug() << "OnExecutedUncodedMove " << SgWritePoint(move) << '\n';
00196     {
00197         m_stack.StartMoveInfo();
00198         if (move != SG_PASS)
00199         {
00200             SG_ASSERT(! Board().LastMoveInfo(GO_MOVEFLAG_SUICIDE));
00201             // can't handle yet,
00202             // should be forbidden anyway. AR: allowed in Chinese rules.
00203             bool fWasCapture = Board().LastMoveInfo(GO_MOVEFLAG_CAPTURING);
00204 
00205             UpdateBlock(move, moveColor);
00206 
00207             {
00208                 GoRegion* r = PreviousRegionAt(move, moveColor);
00209                 bool split = GoEyeUtil::IsSplitPt(move, r->Points());
00210 
00211                 r->OnAddStone(move);
00212                 PushStone(r, move);
00213                 SgPointSet points = r->Points();
00214                 // needed even after RemoveRegion(r).
00215                 if (split || points.IsEmpty())
00216                 // must remove old region before generating new ones,
00217                 // because removing clears m_anchor[]
00218                     RemoveRegion(r);
00219 
00220                 if (split) // find new regions
00221                 {
00222                     for (SgConnCompIterator it(points, Board().Size());
00223                          it; ++it)
00224                         GenRegion(*it, moveColor);
00225                 }
00226             }
00227 
00228             if (fWasCapture)
00229             {
00230             //  FindNewNeighborRegions(move, moveColor);
00231                 MergeAdjacentAndAddBlock(move, SgOppBW(moveColor));
00232             }
00233 
00234             m_code = Board().GetHashCode();
00235             if (HEAVYCHECK)
00236                 CheckConsistency();
00237         }
00238     }
00239 
00240     {
00241         for (SgBWIterator it; it; ++it)
00242         {
00243             SgBlackWhite color(*it);
00244             for (SgVectorIteratorOf<GoRegion> it(AllRegions(color)); it; ++it)
00245             {   GoRegion* r1 = *it;
00246                 if (! r1->IsValid())
00247                     r1->ComputeBasicFlags();
00248             }
00249         }
00250     }
00251 }
00252 
00253 void GoRegionBoard::CheckConsistency() const
00254 {
00255     SG_ASSERT(CHECK && UpToDate());
00256     for (SgBWIterator it; it; ++it)
00257     {
00258         SgBlackWhite color(*it);
00259         SgPointSet blockArea, regionArea;
00260         for (SgVectorIteratorOf<GoRegion> it(AllRegions(color)); it; ++it)
00261         {
00262             SG_ASSERT((*it)->Points().Disjoint(regionArea));
00263             SG_ASSERT((*it)->Points().Disjoint(blockArea));
00264             (*it)->CheckConsistency();
00265             regionArea |= (*it)->Points();
00266         }
00267         for (SgVectorIteratorOf<GoBlock> it(AllBlocks(color)); it; ++it)
00268         {
00269             SG_ASSERT((*it)->Stones().Disjoint(regionArea));
00270             SG_ASSERT((*it)->Stones().Disjoint(blockArea));
00271             for (SgSetIterator it2((*it)->Stones()); it2; ++it2)
00272                 SG_ASSERT(m_block[*it2] == *it);
00273             (*it)->CheckConsistency();
00274             blockArea |= (*it)->Stones();
00275         }
00276         SG_ASSERT(blockArea.Disjoint(regionArea));
00277         SG_ASSERT((blockArea | regionArea) == Board().AllPoints());
00278 
00279         // check m_region array
00280         for (SgPoint p = SgPointUtil::Pt(1, 1);
00281              p <= SgPointUtil::Pt(SG_MAX_SIZE, SG_MAX_SIZE);
00282              ++p)
00283         {
00284             SG_ASSERT((m_region[color][p] == 0) != regionArea.Contains(p));
00285         }
00286 
00287     }
00288     // check block array
00289     for (SgPoint p = SgPointUtil::Pt(1, 1);
00290          p <= SgPointUtil::Pt(SG_MAX_SIZE, SG_MAX_SIZE); ++p)
00291     {
00292         GoBlock* block = m_block[p];
00293         SG_DEBUG_ONLY(block);
00294         SG_ASSERT((block != 0) == Board().Occupied().Contains(p));
00295     }
00296 }
00297 
00298 void GoRegionBoard::PushRegion(int type, GoRegion* r)
00299 {
00300     m_stack.PushPtrEvent(type, r);
00301 }
00302 
00303 void GoRegionBoard::PushBlock(int type, GoBlock* b)
00304 {
00305     m_stack.PushPtrEvent(type, b);
00306 }
00307 
00308 void GoRegionBoard::PushStone(GoRegion* r, SgPoint move)
00309 {
00310     m_stack.PushInt(move);
00311     m_stack.PushPtrEvent(REGION_ADD_STONE, r);
00312     m_region[r->Color()][move] = 0;
00313 }
00314 
00315 void GoRegionBoard::RemoveRegion(GoRegion* r, bool isExecute)
00316 {
00317     SgBlackWhite color = r->Color();
00318 
00319     for (SgSetIterator reg(r->Points()); reg; ++reg)
00320     {
00321         m_region[color][*reg] = 0; // remove link of region.
00322     }
00323 
00324     bool found = m_allRegions[r->Color()].Exclude(r);
00325     SG_UNUSED(found);
00326     SG_ASSERT(found);
00327 
00328     // remove from blocks.
00329     for (SgVectorIteratorOf<GoBlock> it(r->Blocks()); it; ++it)
00330         (*it)->RemoveRegion(r);
00331 
00332     if (isExecute)
00333         PushRegion(REGION_REMOVE, r);
00334     else // undo
00335         delete r;
00336 }
00337 
00338 void GoRegionBoard::SetRegionArrays(GoRegion* r)
00339 {
00340     SgBlackWhite color = r->Color();
00341 
00342     for (SgSetIterator reg(r->Points()); reg; ++reg)
00343     {
00344         m_region[color][*reg] = r;
00345     }
00346 }
00347 
00348 void GoRegionBoard::RemoveBlock(GoBlock* b, bool isExecute,
00349                                      bool removeFromRegions)
00350 {
00351     SgBlackWhite color = b->Color();
00352     for (SgSetIterator it(b->Stones()); it; ++it)
00353         m_block[*it] = 0;
00354 
00355     bool found = m_allBlocks[color].Exclude(b);
00356     SG_UNUSED(found);
00357     SG_ASSERT(found);
00358     const int size = Board().Size();
00359     // remove from regions.
00360     SgPointSet area(b->Stones().Border(size));
00361     SgVectorOf<GoRegion> regions;
00362     if (removeFromRegions)
00363     {
00364         RegionsAt(area, color, &regions);
00365         for (SgVectorIteratorOf<GoRegion> it(regions); it; ++it)
00366         {
00367             (*it)->RemoveBlock(b);
00368             if (isExecute)
00369                 m_stack.PushPtr(*it);
00370         }
00371     }
00372     if (isExecute)
00373     {
00374         m_stack.PushInt(regions.Length()); // 0 if ! removeFromRegions
00375         PushBlock(REGION_REMOVE_BLOCK, b);
00376     }
00377     else
00378         delete b;
00379 }
00380 
00381 void GoRegionBoard::AddBlock(GoBlock* b, bool isExecute)
00382 {
00383     SgBlackWhite color = b->Color();
00384     AllBlocks(color).PushBack(b);
00385     for (GoBoard::StoneIterator it(Board(), b->Anchor()); it; ++it)
00386         m_block[*it] = b;
00387     if (isExecute)
00388         PushBlock(REGION_ADD_BLOCK, b);
00389 }
00390 
00391 GoBlock* GoRegionBoard::GenBlock(SgPoint anchor, SgBlackWhite color)
00392 {
00393     GoBlock* b = new GoBlock(color, anchor, Board());
00394     AddBlock(b);
00395     return b;
00396 }
00397 
00398 void
00399 GoRegionBoard::PreviousBlocksAt(const SgVector<SgPoint>& area,
00400                                 SgBlackWhite color,
00401                                 SgVectorOf<GoBlock>* captures) const
00402 {
00403     SG_UNUSED(color);
00404 
00405     for (SgVectorIterator<SgPoint> it(area); it; ++it)
00406     {
00407         GoBlock* b = m_block[*it];
00408         if (b)
00409             captures->Include(b);
00410     }
00411 }
00412 
00413 #if UNUSED
00414 void GoRegionBoard::BlockToRegion(GoBlock* b)
00415 // convert a captured block into an opponent region.
00416 {
00417     GoRegion* r = new GoRegion(Board(), b->Stones(), OppBW(b->Color()));
00418     SetRegionArrays(r);
00419     // AR anchor array should still be OK, don't need to set it.
00420 }
00421 
00422 void GoRegionBoard::FindNewNeighborRegions(SgPoint move,
00423                                                 BlackWhite moveColor)
00424 { // move was capture -> new region for each captured block.
00425 
00426     SgVector<SgPoint> nb;
00427     for (Nb4Iterator it(move); it; ++it)
00428         if (Board().IsEmpty(*it))
00429             nb.PushBack(*it);
00430 
00431     SgVectorOf<GoBlock> captures;
00432     PreviousBlocksAt(nb, OppBW(moveColor), &captures);
00433     SG_ASSERT(captures.NonEmpty());
00434 
00435     for (SgVectorIteratorOf<GoBlock> it(captures); it; ++it)
00436         BlockToRegion(*it);
00437 }
00438 #endif
00439 
00440 
00441 void GoRegionBoard::RegionsAt(const SgPointSet& area, SgBlackWhite color,
00442                                    SgVectorOf<GoRegion>* regions) const
00443 {
00444     for (SgVectorIteratorOf<GoRegion> it(AllRegions(color)); it; ++it)
00445         if ((*it)->Points().Overlaps(area))
00446             regions->PushBack(*it);
00447 }
00448 
00449 void GoRegionBoard::AdjacentRegions(const SgVector<SgPoint>& anchors,
00450                                          SgBlackWhite color,
00451                                          SgVectorOf<GoRegion>* regions) const
00452 {
00453     for (SgVectorIteratorOf<GoRegion> it(AllRegions(color)); it; ++it)
00454         if ((*it)->AdjacentToSomeBlock(anchors))
00455             regions->PushBack(*it);
00456 }
00457 
00458 GoRegion* GoRegionBoard::MergeAll(const SgVectorOf<GoRegion>& regions,
00459                                        const SgPointSet& captured,
00460                                        SgBlackWhite color)
00461 {
00462     SgPointSet area(captured);
00463     for (SgVectorIteratorOf<GoRegion> it(regions); it; ++it)
00464         area |= (*it)->Points();
00465     {for (SgVectorIteratorOf<GoRegion> it(regions); it; ++it)
00466         RemoveRegion(*it);
00467     }
00468     GoRegion* r = GenRegion(area, color);
00469 
00470     return r;
00471 }
00472 
00473 void GoRegionBoard::MergeAdjacentAndAddBlock(SgPoint move,
00474                                                   SgBlackWhite capturedColor)
00475 {
00476     SgVector<SgPoint> nb;
00477     for (SgNb4Iterator it(move); it; ++it)
00478         if (Board().IsEmpty(*it))
00479             nb.PushBack(*it);
00480 
00481     SgVectorOf<GoBlock> captures;
00482     PreviousBlocksAt(nb, capturedColor, &captures);
00483     SG_ASSERT(captures.NonEmpty());
00484 
00485     SgPointSet captured;
00486     {for (SgVectorIteratorOf<GoBlock> it(captures); it; ++it)
00487         captured |= (*it)->Stones();
00488     }
00489     SgVectorOf<GoRegion> adj;
00490     const int size = Board().Size();
00491     RegionsAt(captured.Border(size), capturedColor, &adj);
00492     SG_ASSERT(adj.NonEmpty());
00493     GoRegion* r = MergeAll(adj, captured, capturedColor);
00494     SG_UNUSED(r);
00495 
00496     for (SgVectorIteratorOf<GoBlock> it(captures); it; ++it)
00497         RemoveBlock(*it, true, false);
00498         // don't remove from regions; already gone.
00499 }
00500 
00501 void GoRegionBoard::OnUndoneMove()
00502 // Called after a move has been undone. The board is guaranteed to be in
00503 // a legal state.
00504 {
00505     //SG_ASSERT(false); // incremental code is incomplete, do not call
00506     if (DEBUG_REGION_BOARD)
00507         SgDebug() << "OnUndoneMove " << '\n';
00508 
00509     const bool IS_UNDO = false;
00510     SgVectorOf<GoRegion> changed;
00511 
00512     for (int val = m_stack.PopEvent(); val != SG_NEXTMOVE;
00513          val = m_stack.PopEvent())
00514     {
00515 
00516         switch (val)
00517         {
00518             case REGION_REMOVE:
00519             {   GoRegion* r = static_cast<GoRegion*>(m_stack.PopPtr());
00520                 AddRegion(r, IS_UNDO);
00521                 changed.Insert(r);
00522             }
00523             break;
00524             case REGION_ADD:
00525             {   GoRegion* r = static_cast<GoRegion*>(m_stack.PopPtr());
00526                 RemoveRegion(r, IS_UNDO);
00527             }
00528             break;
00529             case REGION_REMOVE_BLOCK:
00530             {   GoBlock* b = static_cast<GoBlock*>(m_stack.PopPtr());
00531                 AddBlock(b, IS_UNDO);
00532                 for (int nu = m_stack.PopInt(); nu > 0; --nu)
00533                 {
00534                     GoRegion* r = static_cast<GoRegion*>(m_stack.PopPtr());
00535                     if (CHECK)
00536                         SG_ASSERT(! r->Blocks().Contains(b));
00537                     r->BlocksNonConst().PushBack(b);
00538                     changed.Insert(r);
00539                 }
00540             }
00541             break;
00542             case REGION_ADD_BLOCK:
00543             {   GoBlock* b = static_cast<GoBlock*>(m_stack.PopPtr());
00544                 RemoveBlock(b, IS_UNDO, true);
00545             }
00546             break;
00547             case REGION_ADD_STONE:
00548             {   GoRegion* r = static_cast<GoRegion*>(m_stack.PopPtr());
00549                 SgPoint p = m_stack.PopInt();
00550                 r->OnRemoveStone(p);
00551                 m_region[r->Color()][p] = r;
00552                 changed.Insert(r);
00553             }
00554             break;
00555             case REGION_ADD_STONE_TO_BLOCK:
00556             {   GoBlock* b = static_cast<GoBlock*>(m_stack.PopPtr());
00557                 SgPoint p = m_stack.PopInt();
00558                 b->RemoveStone(p);
00559                 m_block[p] = 0;
00560             }
00561             break;
00562             default:
00563                 SG_ASSERT(false);
00564         }
00565     }
00566 
00567     for (SgVectorIteratorOf<GoRegion> it(changed); it; ++it)
00568     {
00569         (*it)->ResetNonBlockFlags();
00570         (*it)->ComputeBasicFlags();
00571     }
00572 
00573     if (HEAVYCHECK)
00574     {
00575         for (SgBWIterator it; it; ++it)
00576         {
00577             SgBlackWhite color(*it);
00578             for (SgVectorIteratorOf<GoRegion> it(AllRegions(color)); it; ++it)
00579             {
00580                 const GoRegion* r = *it;
00581                 SG_UNUSED(r);
00582                 SG_ASSERT(r->IsValid());
00583             }
00584         }
00585     }
00586 
00587     m_code = Board().GetHashCode();
00588     if (HEAVYCHECK)
00589         CheckConsistency();
00590 }
00591 
00592 void GoRegionBoard::ReInitializeBlocksRegions()
00593 {
00594     SG_ASSERT(UpToDate());
00595 
00596     for (SgBWIterator it; it; ++it)
00597     {
00598         SgBlackWhite color(*it);
00599         for (SgVectorIteratorOf<GoBlock> it(AllBlocks(color)); it; ++it)
00600             (*it)->ReInitialize();
00601         for (SgVectorIteratorOf<GoRegion> it2(AllRegions(color)); it2; ++it2)
00602             (*it2)->ReInitialize();
00603     }
00604 }
00605 
00606 GoRegion* GoRegionBoard::GenRegion(const SgPointSet& area,
00607                                         SgBlackWhite color)
00608 {
00609     GoRegion* r = new GoRegion(Board(), area, color);
00610     AddRegion(r);
00611     return r;
00612 }
00613 
00614 void GoRegionBoard::AddRegion(GoRegion* r, bool isExecute)
00615 {
00616     SetRegionArrays(r);
00617 
00618     if (isExecute) // not needed if restoring during undo.
00619     {
00620         r->FindBlocks(*this);
00621         r->ComputeBasicFlags();
00622     }
00623 
00624     SgBlackWhite color = r->Color();
00625     if (HEAVYCHECK)
00626         SG_ASSERT(! AllRegions(color).Contains(r));
00627     AllRegions(color).PushBack(r);
00628 
00629     if (isExecute)
00630         PushRegion(REGION_ADD, r);
00631 }
00632 
00633 void GoRegionBoard::FindBlocksWithEye()
00634 {
00635     for (SgBWIterator it; it; ++it)
00636     {
00637         SgBlackWhite color(*it);
00638         for (SgVectorIteratorOf<GoRegion> it(AllRegions(color)); it; ++it)
00639             if ((*it)->Blocks().IsLength(1))
00640             {
00641                 GoBlock* b = (*it)->Blocks().Front();
00642                 (b)->TestFor1Eye(*it);
00643             }
00644     }
00645 }
00646 
00647 void GoRegionBoard::GenBlocksRegions()
00648 {
00649     if (UpToDate())
00650         return;
00651 
00652     Clear();
00653     GenBlocks();
00654 
00655     for (SgBWIterator it; it; ++it)
00656     {
00657         SgBlackWhite color(*it);
00658         for (SgConnCompIterator it(AllPoints() - All(color), Board().Size());
00659              it; ++it)
00660             GenRegion(*it, color);
00661     }
00662 
00663     FindBlocksWithEye();
00664 
00665     m_code = Board().GetHashCode();
00666     m_invalid = false;
00667     if (HEAVYCHECK)
00668         CheckConsistency();
00669 }
00670 
00671 void GoRegionBoard::GenChains()
00672 {
00673     if (ChainsUpToDate())
00674         return;
00675 
00676     for (SgBWIterator it; it; ++it)
00677     {
00678         SgBlackWhite color(*it);
00679         SG_ASSERT(AllChains(color).IsEmpty());
00680 
00681         for (SgVectorIteratorOf<GoBlock> it(AllBlocks(color)); it; ++it)
00682             AllChains(color).PushBack(new GoChain(*it, Board()));
00683         for (SgVectorIteratorOf<GoRegion> it(AllRegions(color)); it; ++it)
00684             (*it)->FindChains(*this);
00685     }
00686     m_chainsCode = Board().GetHashCode();
00687 }
00688 
00689 void GoRegionBoard::WriteBlocks(std::ostream& stream) const
00690 {
00691     for (SgBWIterator it; it; ++it)
00692     {
00693         SgBlackWhite color(*it);
00694         for (SgVectorIteratorOf<GoBlock> it(AllBlocks(color)); it; ++it)
00695             stream << **it;
00696     }
00697 }
00698 
00699 void GoRegionBoard::WriteRegions(std::ostream& stream) const
00700 {
00701     for (SgBWIterator it; it; ++it)
00702     {
00703         SgBlackWhite color(*it);
00704         for (SgVectorIteratorOf<GoRegion> it(AllRegions(color)); it; ++it)
00705             (*it)->Write(stream);
00706     }
00707 }
00708 
00709 GoBlock* GoRegionBoard::GetBlock(const SgPointSet& boundary,
00710                                  SgBlackWhite color) const
00711 {
00712     SG_ASSERT(UpToDate());
00713 
00714     for (SgVectorIteratorOf<GoBlock> it(AllBlocks(color)); it; ++it)
00715     {   if (boundary.SubsetOf((*it)->Stones()))
00716         /* */ return *it; /* */
00717     }
00718 
00719     SgDebug() << "ERROR: no block on set";
00720     const int size = Board().Size();
00721     boundary.Write(SgDebug(), size);
00722     SgDebug() << "blocks:";
00723     for (SgVectorIteratorOf<GoBlock> it(AllBlocks(color));it; ++it)
00724         (*it)->Stones().Write(SgDebug(), size);
00725 
00726     SG_ASSERT(false);
00727     return 0;
00728 }
00729 
00730 GoChain* GoRegionBoard::ChainAt(SgPoint p) const
00731 {
00732     SG_ASSERT(ChainsUpToDate());
00733     const SgBlackWhite color = Board().GetStone(p);
00734 
00735     for (SgVectorIteratorOf<GoChain> it(AllChains(color));it; ++it)
00736         if ((*it)->Stones().Contains(p))
00737             /* */ return *it; /* */
00738 
00739     SG_ASSERT(false);
00740     return 0;
00741 }
00742 
00743 void GoRegionBoard::GenBlocks()
00744 {
00745     for (GoBlockIterator it(Board()); it; ++it)
00746         GenBlock(*it, Board().GetStone(*it));
00747 }
00748 
00749 void GoRegionBoard::SetComputedFlagForAll(GoRegionFlag flag)
00750 {
00751     // mark all regions that their safety has been computed.
00752     for (SgBWIterator it; it; ++it)
00753     {
00754         SgBlackWhite color(*it);
00755         for (SgVectorIteratorOf<GoRegion> it(AllRegions(color)); it; ++it)
00756             (*it)->SetComputedFlag(flag);
00757     }
00758 }
00759 
00760 void GoRegionBoard::SetComputedHealthy()
00761 {
00762     m_computedHealthy = true;
00763 }
00764 
00765 //----------------------------------------------------------------------------
00766 
00767 int GoRegionBoard::s_alloc = 0;
00768 int GoRegionBoard::s_free = 0;


Sun Mar 13 2011 Doxygen 1.7.1