bool GoSafetySolver::FindSurroundedSingleRegion(SgBWSet* safe, SgBlackWhite color) { SgPointSet anySafe(safe->Both()); for (SgVectorIteratorOf<GoRegion> it(Regions()->AllRegions(color)); it; ++it) { GoRegion* r = *it; if ( ! r->GetFlag(GO_REGION_SAFE) && r->SomeBlockIsSafe() && ! r->Points().Overlaps(anySafe) && GoSafetyUtil::ExtendedIsTerritory(Board(), Regions(), r->PointsPlusInteriorBlocks(), (*safe)[color], color) ) { GoSafetyUtil::AddToSafe(Board(), r->Points(), color, safe, "surr-safe-1", 0, true); Regions()->SetSafeFlags(*safe); return true; } } return false; }
void GoRegionBoard::OnExecutedUncodedMove(int move, SgBlackWhite moveColor) { if (DEBUG_REGION_BOARD) SgDebug() << "OnExecutedUncodedMove " << SgWritePoint(move) << '\n'; { m_stack.StartMoveInfo(); if (move != SG_PASS) { SG_ASSERT(! Board().LastMoveInfo(GO_MOVEFLAG_SUICIDE)); // can't handle yet, // should be forbidden anyway. @todo allowed in Chinese rules. bool fWasCapture = Board().LastMoveInfo(GO_MOVEFLAG_CAPTURING); UpdateBlock(move, moveColor); { GoRegion* r = PreviousRegionAt(move, moveColor); bool split = GoEyeUtil::IsSplitPt(move, r->Points()); r->OnAddStone(move); PushStone(r, move); SgPointSet points = r->Points(); // needed even after RemoveRegion(r). if (split || points.IsEmpty()) // must remove old region before generating new ones, // because removing clears m_anchor[] RemoveRegion(r); if (split) // find new regions { for (SgConnCompIterator it(points, Board().Size()); it; ++it) GenRegion(*it, moveColor); } } if (fWasCapture) { // FindNewNeighborRegions(move, moveColor); MergeAdjacentAndAddBlock(move, SgOppBW(moveColor)); } m_code = Board().GetHashCode(); if (HEAVYCHECK) CheckConsistency(); } } { for (SgBWIterator it; it; ++it) { SgBlackWhite color(*it); for (SgVectorIteratorOf<GoRegion> it(AllRegions(color)); it; ++it) { GoRegion* r1 = *it; if (! r1->IsValid()) r1->ComputeBasicFlags(); } } } }