void GoSafetySolver::GenBlocksRegions() { if (UpToDate()) /* */ return; /* */ GoStaticSafetySolver::GenBlocksRegions(); Regions()->GenChains(); // merge blocks adjacent to 1-vital with 2 conn. points for (SgBWIterator it; it; ++it) { SgBlackWhite color(*it); for (SgVectorIteratorOf<GoRegion> it(Regions()->AllRegions(color)); it; ++it) { GoRegion* r = *it; r->ComputeFlag(GO_REGION_STATIC_1VITAL); } bool changed = true; while (changed) { changed = false; for (SgVectorIteratorOf<GoRegion> it(Regions()->AllRegions(color)); it; ++it) { GoRegion* r = *it; if ( r->GetFlag(GO_REGION_STATIC_1VC) && r->Chains().IsLength(2) && r->Has2Conn() // || r->Safe2Cuts(Board()) changed from && to || // @todo does not work if blocks are already chains??? // must explicitly keep chain libs info. ) // easy case of only 2 chains { GoChain* c1 = r->Chains().Front(); GoChain* c2 = r->Chains().Back(); Merge(c1, c2, r, false); // false = not by search changed = true; break; // to leave iteration } else if ( r->GetFlag(GO_REGION_STATIC_1VITAL) && r->GetFlag(GO_REGION_CORRIDOR) && ! r->GetFlag(GO_REGION_USED_FOR_MERGE) ) { GoChain* c1 = 0; GoChain* c2 = 0; if (r->Find2Mergable(&c1, &c2)) { Merge(c1, c2, r, false); changed = true; break; // to leave iteration } } } } } m_code = Board().GetHashCode(); }
void GoSafetySolver::FindHealthy() { for (SgBWIterator it; it; ++it) { SgBlackWhite color(*it); for (SgVectorIteratorOf<GoRegion> it(Regions()->AllRegions(color)); it; ++it) (*it)->ComputeFlag(GO_REGION_STATIC_1VITAL); } // used to just call GoStaticSafetySolver::FindHealthy() here, // but that works with GoBlock's and now we use GoChain's. // Code is duplicated though. Can maybe use a template function. for (SgBWIterator it; it; ++it) { SgBlackWhite color(*it); for (SgVectorIteratorOf<GoRegion> it(Regions()->AllRegions(color)); it; ++it) { GoRegion* r = *it; for (SgVectorIteratorOf<GoChain> it2(r->Chains()); it2; ++it2) { if (RegionHealthyForBlock(*r, **it2)) // virtual call (*it2)->AddHealthy(r); } } } }
void GoSafetySolver::FindClosure(SgVectorOf<GoBlock>* blocks) const { SgVectorOf<GoBlock> toTest(*blocks); while (toTest.NonEmpty()) { const GoBlock* b = toTest.Back(); toTest.PopBack(); for (SgVectorIteratorOf<GoRegion> it(b->Healthy()); it; ++it) { GoRegion* r = *it; for (SgVectorIteratorOf<GoChain> it(r->Chains()); it; ++it) { GoBlock* b2 = *it; if (! blocks->Contains(b2) && b2->ContainsHealthy(r)) { blocks->PushBack(b2); toTest.PushBack(b2); } } } } }