Go to the documentation of this file.00001
00002
00003
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
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))
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(®ions, *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())
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();
00209 FindHealthy();
00210
00211 for (SgBWIterator it; it; ++it)
00212 {
00213 SgBlackWhite color(*it);
00214 SgVectorOf<SgVectorOf<GoBlock> > sets;
00215
00216 FindTestSets(&sets, color);
00217
00218 for (SgVectorIteratorOf<SgVectorOf<GoBlock> > it(sets); it; ++it)
00219 { TestAlive(*it, safe, color);
00220
00221 delete *it;
00222 }
00223 }
00224
00225 Regions()->SetComputedFlagForAll(GO_REGION_SAFE);
00226 }
00227