Index   Main   Namespaces   Classes   Hierarchy   Annotated   Files   Compound   Global   Pages  

GoStaticSafetySolver.cpp

Go to the documentation of this file.
00001 //----------------------------------------------------------------------------
00002 /** @file GoStaticSafetySolver.cpp
00003     See GoStaticSafetySolver.h. */
00004 //----------------------------------------------------------------------------
00005 
00006 #include "SgSystem.h"
00007 #include "GoStaticSafetySolver.h"
00008 
00009 #include "GoBlock.h"
00010 #include "GoChain.h"
00011 #include "GoSafetyUtil.h"
00012 #include "SgDebug.h"
00013 
00014 using GoSafetyUtil::AddToSafe;
00015 
00016 //----------------------------------------------------------------------------
00017 
00018 GoStaticSafetySolver::GoStaticSafetySolver(const GoBoard& board,
00019                                            GoRegionBoard* regions)
00020     : m_board(board),
00021       m_allocRegion(! regions)
00022 {
00023     if (regions)
00024         m_regions = regions;
00025     else
00026         m_regions = new GoRegionBoard(board);
00027 }
00028 
00029 GoStaticSafetySolver::~GoStaticSafetySolver()
00030 {
00031     if (m_allocRegion)
00032         delete m_regions;
00033     // else m_regions belongs to the user, so leave it.
00034 }
00035 
00036 bool GoStaticSafetySolver::RegionHealthyForBlock(const GoRegion& r,
00037                                           const GoBlock& b) const
00038 {
00039     return b.AllEmptyAreLiberties(r.Points());
00040 }
00041 
00042 bool GoStaticSafetySolver::UpToDate() const
00043 {
00044     return Regions()->UpToDate();
00045 }
00046 
00047 void GoStaticSafetySolver::GenBlocksRegions()
00048 {
00049     if (UpToDate())
00050         Regions()->ReInitializeBlocksRegions();
00051     else
00052     {
00053         Regions()->GenBlocksRegions();
00054     }
00055 }
00056 
00057 
00058 void GoStaticSafetySolver::FindHealthy()
00059 {
00060     if (Regions()->ComputedHealthy())
00061         return;
00062     for (SgBWIterator it; it; ++it)
00063     {
00064         SgBlackWhite color(*it);
00065         for (SgVectorIteratorOf<GoRegion>
00066              it(Regions()->AllRegions(color)); it; ++it)
00067         {
00068             GoRegion* r = *it;
00069             for (SgVectorIteratorOf<GoBlock> it2(r->Blocks()); it2; ++it2)
00070             {
00071                 if (RegionHealthyForBlock(*r, **it2)) // virtual call
00072                 {
00073                     (*it2)->AddHealthy(r);
00074                 }
00075             }
00076         }
00077     }
00078     Regions()->SetComputedHealthy();
00079 }
00080 
00081 void GoStaticSafetySolver::TestAdjacent(SgVectorOf<GoRegion>* regions,
00082                                const SgVectorOf<GoBlock>& blocks) const
00083 {
00084     SgVectorOf<GoRegion> newregions;
00085     for (SgVectorIteratorOf<GoRegion> it(*regions); it; ++it)
00086         if ((*it)->IsSurrounded(blocks))
00087             newregions.PushBack(*it);
00088     *regions = newregions;
00089 }
00090 
00091 void GoStaticSafetySolver::TestAlive(SgVectorOf<GoBlock>* blocks,
00092                               SgBWSet* safe,
00093                               SgBlackWhite color)
00094 {
00095     SgVectorOf<GoRegion> regions(Regions()->AllRegions(color));
00096     SgVectorOf<GoBlock> toDelete;
00097 
00098     bool changed = true;
00099     while (changed)
00100     {
00101         TestAdjacent(&regions, *blocks);
00102         toDelete.Clear();
00103         for (SgVectorIteratorOf<GoBlock> it(*blocks); it; ++it)
00104         {
00105             const SgVectorOf<GoRegion>& br = (*it)->Healthy();
00106 
00107             bool has2 = br.MinLength(2);
00108             if (has2)
00109             {
00110                 int nuRegions = 0;
00111                 for (SgVectorIteratorOf<GoRegion> it(br); it; ++it)
00112                 {
00113                     if (regions.Contains(*it))
00114                     {
00115                         ++nuRegions;
00116                         if (nuRegions >= 2)
00117                             break;
00118                     }
00119                 }
00120                 has2 = (nuRegions >= 2);
00121             }
00122             if (! has2)
00123                 toDelete.PushBack(*it);
00124         }
00125 
00126         changed = toDelete.NonEmpty();
00127         if (changed)
00128         {
00129             for (SgVectorIteratorOf<GoBlock> it(toDelete); it; ++it)
00130             {
00131                 bool found = blocks->Exclude(*it);
00132                 SG_DEBUG_ONLY(found);
00133                 SG_ASSERT(found);
00134             }
00135         }
00136     }
00137 
00138     if (blocks->NonEmpty()) // found safe blocks
00139     {
00140         SgPointSet blockPoints;
00141         for (SgVectorIteratorOf<GoBlock> it(*blocks); it; ++it)
00142         {
00143             blockPoints |= (*it)->Stones();
00144             (*it)->SetToSafe();
00145         }
00146 
00147         color = blocks->Front()->Color();
00148         AddToSafe(m_board, blockPoints, color, safe,
00149                   "TestAlive-Blocks", 0, false);
00150 
00151         for (SgVectorIteratorOf<GoRegion> it(regions); it; ++it)
00152             if ((*it)->HealthyForSomeBlock(*blocks))
00153             {
00154                 (*it)->SetToSafe();
00155                 AddToSafe(m_board, (*it)->Points(), color, safe,
00156                           "TestAlive-Region", 0, false);
00157             }
00158     }
00159 }
00160 
00161 void GoStaticSafetySolver::FindClosure(SgVectorOf<GoBlock>* blocks) const
00162 {
00163     SgVectorOf<GoBlock> toTest(*blocks);
00164     while (toTest.NonEmpty())
00165     {
00166         const GoBlock* b = toTest.Back();
00167         toTest.PopBack();
00168         for (SgVectorIteratorOf<GoRegion> it(b->Healthy()); it; ++it)
00169         {
00170             const GoRegion* r = *it;
00171             for (SgVectorIteratorOf<GoBlock> it(r->Blocks()); it; ++it)
00172             {
00173                 const GoBlock* b2 = *it;
00174                 if (! blocks->Contains(b2))
00175                 {
00176                     blocks->PushBack(b2);
00177                     toTest.PushBack(b2);
00178                 }
00179             }
00180         }
00181     }
00182 }
00183 
00184 void GoStaticSafetySolver::FindTestSets(
00185                                      SgVectorOf<SgVectorOf<GoBlock> >* sets,
00186                                      SgBlackWhite color) const
00187 {
00188     SG_ASSERT(sets->IsEmpty());
00189     SgVectorOf<GoBlock> doneSoFar;
00190     for (SgVectorIteratorOf<GoBlock>
00191          it(Regions()->AllBlocks(color)); it; ++it)
00192     {
00193         GoBlock* block = *it;
00194         if (! doneSoFar.Contains(block))
00195         {
00196             SgVectorOf<GoBlock>* blocks = new SgVectorOf<GoBlock>;
00197             blocks->PushBack(block);
00198 
00199             FindClosure(blocks);
00200             doneSoFar.PushBackList(*blocks);
00201             sets->PushBack(blocks);
00202         }
00203     }
00204 }
00205 
00206 void GoStaticSafetySolver::FindSafePoints(SgBWSet* safe)
00207 {
00208     GenBlocksRegions(); // find all blocks and regions on whole board
00209     FindHealthy(); // find healthy regions of blocks
00210 
00211     for (SgBWIterator it; it; ++it)
00212     {
00213         SgBlackWhite color(*it);
00214         SgVectorOf<SgVectorOf<GoBlock> > sets;
00215         // find maximal sets for aliveness testing
00216         FindTestSets(&sets, color);
00217 
00218         for (SgVectorIteratorOf<SgVectorOf<GoBlock> > it(sets); it; ++it)
00219         {   TestAlive(*it, safe, color);
00220             // find safe subset within each maximal set
00221             delete *it;
00222         }
00223     }
00224 
00225     Regions()->SetComputedFlagForAll(GO_REGION_SAFE);
00226 }
00227 


Sun Mar 13 2011 Doxygen 1.7.1