public bool IsTwoVital() { // evaluation is lazy if (Is2Vital.IsKnown) { return(Is2Vital.IsTrue); } // two vital - if 1) all the enclosing blocks's empty points in the region are accessible liberties // and 2) the region has two intersection points if (!AccessibleLiberties.IsSame(EmptyArea)) { Is2Vital = TriState.False; return(false); } int lIntersectionCount = 0; foreach (GoBlockBase lGoBlockBase in EmptyBlocks) { foreach (int lPoint in lGoBlockBase.Members) { if (IsIntersection(lPoint)) // if (EnclosingBlocks.Count > 1) { bool AdjacentToAll = true; //foreach (GoBlock lGoBlock in EnclosingBlocks) foreach (GoBlock lGoBlock in Neighbors) { if (!lGoBlock.Liberties.Contains(lPoint)) { AdjacentToAll = false; break; } } if (AdjacentToAll) { lIntersectionCount++; if (lIntersectionCount >= 2) { Is2Vital = TriState.True; return(true); } } } } } Is2Vital = TriState.False; return(false); }
public bool IsSmallEnclosed() { if (IsSmall.IsKnown) { return(IsSmall.IsTrue); } if (EmptyArea.HasInterior()) { IsSmall = TriState.False; return(false); } IsSmall = TriState.True; return(true); }
public bool IsOneVital() { if (Is1Vital.IsKnown) { return(Is1Vital.IsTrue); } if (EnclosingBlocks.Count == 0) { Is1Vital = TriState.False; return(false); } // step 1 // build miai stragety MiaiStrategy = new MiaiStrategy(); Region lAccessibleLibertiesAvailable = new Region(AccessibleLiberties); if (!CreateBlocksConnectionStrategy(lAccessibleLibertiesAvailable, MiaiStrategy)) { Is1Vital = TriState.False; return(false); } // step 2 // future: add miai accessible interior empty points to the set of accessible liberties, // and also use protected liberties for the chaining. Region lNewAccessibleRegion = new Region(AccessibleLiberties); foreach (GoBlock lGoBlock in InteriorDefenderBlocks) { lNewAccessibleRegion.Add(lGoBlock.Liberties); } // step 2a - add miai accessible interior empty points to the set of accessible liberties // rough implementation Region lMiaiAccessibleInteriorRegion = new Region(Board.BoardSize); if (Version >= 2004) { foreach (int lIndex in EmptyArea) { if (!lNewAccessibleRegion.Contains(lIndex)) { List <int> llAccessibleNeighborPoints = new List <int>(4); foreach (int lNeighbor in Board.Coord.GetNeighbors(lIndex)) { if (lNewAccessibleRegion.Contains(lNeighbor)) { llAccessibleNeighborPoints.Add(lNeighbor); } } if (llAccessibleNeighborPoints.Count >= 2) { lMiaiAccessibleInteriorRegion.Add(lIndex); } } } } lNewAccessibleRegion.Add(lMiaiAccessibleInteriorRegion); // step 3 Region lEmptyAndNotAccessible = new Region(EmptyArea); lEmptyAndNotAccessible.Remove(lNewAccessibleRegion); List <int> lList = lEmptyAndNotAccessible.ToList(); int lMinAdjacent = 2; while (lList.Count != 0) { List <int> lRemove = new List <int>(); foreach (int lIndex in lList) { List <int> lAccessibleLibertiesForPoint = new List <int>(4); foreach (int lNeighbor in Board.Coord.GetNeighbors(lIndex)) { if (lNewAccessibleRegion.Contains(lNeighbor)) { lAccessibleLibertiesForPoint.Add(lNeighbor); } } if (lAccessibleLibertiesForPoint.Count < 2) { Is1Vital = TriState.False; return(false); } if ((lAccessibleLibertiesForPoint.Count == 2) || (lAccessibleLibertiesForPoint.Count == lMinAdjacent)) { lNewAccessibleRegion.Remove(lAccessibleLibertiesForPoint[0]); lNewAccessibleRegion.Remove(lAccessibleLibertiesForPoint[1]); MiaiStrategy.Add(lIndex, lAccessibleLibertiesForPoint[0], lAccessibleLibertiesForPoint[1]); lRemove.Add(lIndex); lMinAdjacent = 2; } } if (lList.Count == lRemove.Count) { lList.Clear(); } else { foreach (int lPoint in lRemove) { lList.Remove(lPoint); } } if (lRemove.Count == 0) { lMinAdjacent++; } } Is1Vital = TriState.True; return(true); }
public ColorEnclosedRegion(GoEmptyBlock goEmptyBlock, Color defender) { Board = goEmptyBlock.Board; Defender = defender; Size = 0; Version = 2004; _RegionNbr = goEmptyBlock.BlockNbr; Members = new List <GoBlockBase>(); EmptyBlocks = new List <GoEmptyBlock>(); Neighbors = new List <GoBlock>(); InteriorAttackerBlocks = new List <GoBlock>(); Is2Vital = TriState.Unknown; Is1Vital = TriState.Unknown; IsSmall = TriState.Unknown; _EnclosedArea = null; _EmptyRegion = null; Stack <GoBlockBase> lWork = new Stack <GoBlockBase>(); lWork.Push(goEmptyBlock); while (lWork.Count != 0) { GoBlockBase lGoBlockBase = lWork.Pop(); if (!Members.Contains(lGoBlockBase)) { Members.Add(lGoBlockBase); if (lGoBlockBase.IsEmptyBlock()) { EmptyBlocks.Add((GoEmptyBlock)lGoBlockBase); Size = Size + ((GoEmptyBlock)lGoBlockBase).EmptySpaceCount; } else { InteriorAttackerBlocks.Add((GoBlock)lGoBlockBase); Size = Size + ((GoBlock)lGoBlockBase).StoneCount; } foreach (GoBlockBase lGoBlockBaseAdjacent in lGoBlockBase.AdjacentBlocks.AllBlocks) { if (lGoBlockBaseAdjacent.BlockColor == Defender) { if (!Neighbors.Contains((GoBlock)lGoBlockBaseAdjacent)) { Neighbors.Add((GoBlock)lGoBlockBaseAdjacent); } } else if (!Members.Contains(lGoBlockBaseAdjacent)) { lWork.Push(lGoBlockBaseAdjacent); } } } } EnclosingBlocks = new List <GoBlock>(Neighbors.Count); InteriorDefenderBlocks = new List <GoBlock>(); foreach (GoBlock lGoBlock in Neighbors) { bool lFound = false; foreach (GoEmptyBlock lGoEmptyBlock in lGoBlock.AdjacentBlocks.EmptyBlocks) { if (!EmptyBlocks.Contains(lGoEmptyBlock)) { lFound = true; break; } } if (lFound) { EnclosingBlocks.Add(lGoBlock); } else { InteriorDefenderBlocks.Add(lGoBlock); } } if (EnclosingBlocks.Count == 0) { InteriorDefenderBlocks.Clear(); } }
protected Region _EnclosingBlocksLibertyArea; // lazy evaluation #endregion Fields #region Constructors public ColorEnclosedRegion(GoEmptyBlock goEmptyBlock, Color defender) { Board = goEmptyBlock.Board; Defender = defender; Size = 0; Version = 2004; _RegionNbr = goEmptyBlock.BlockNbr; Members = new List<GoBlockBase>(); EmptyBlocks = new List<GoEmptyBlock>(); Neighbors = new List<GoBlock>(); InteriorAttackerBlocks = new List<GoBlock>(); Is2Vital = TriState.Unknown; Is1Vital = TriState.Unknown; IsSmall = TriState.Unknown; _EnclosedArea = null; _EmptyRegion = null; Stack<GoBlockBase> lWork = new Stack<GoBlockBase>(); lWork.Push(goEmptyBlock); while (lWork.Count != 0) { GoBlockBase lGoBlockBase = lWork.Pop(); if (!Members.Contains(lGoBlockBase)) { Members.Add(lGoBlockBase); if (lGoBlockBase.IsEmptyBlock()) { EmptyBlocks.Add((GoEmptyBlock)lGoBlockBase); Size = Size + ((GoEmptyBlock)lGoBlockBase).EmptySpaceCount; } else { InteriorAttackerBlocks.Add((GoBlock)lGoBlockBase); Size = Size + ((GoBlock)lGoBlockBase).StoneCount; } foreach (GoBlockBase lGoBlockBaseAdjacent in lGoBlockBase.AdjacentBlocks.AllBlocks) if (lGoBlockBaseAdjacent.BlockColor == Defender) { if (!Neighbors.Contains((GoBlock)lGoBlockBaseAdjacent)) Neighbors.Add((GoBlock)lGoBlockBaseAdjacent); } else if (!Members.Contains(lGoBlockBaseAdjacent)) lWork.Push(lGoBlockBaseAdjacent); } } EnclosingBlocks = new List<GoBlock>(Neighbors.Count); InteriorDefenderBlocks = new List<GoBlock>(); foreach (GoBlock lGoBlock in Neighbors) { bool lFound = false; foreach (GoEmptyBlock lGoEmptyBlock in lGoBlock.AdjacentBlocks.EmptyBlocks) { if (!EmptyBlocks.Contains(lGoEmptyBlock)) { lFound = true; break; } } if (lFound) EnclosingBlocks.Add(lGoBlock); else InteriorDefenderBlocks.Add(lGoBlock); } if (EnclosingBlocks.Count == 0) InteriorDefenderBlocks.Clear(); }
public bool IsTwoVital() { // evaluation is lazy if (Is2Vital.IsKnown) return (Is2Vital.IsTrue); // two vital - if 1) all the enclosing blocks's empty points in the region are accessible liberties // and 2) the region has two intersection points if (!AccessibleLiberties.IsSame(EmptyArea)) { Is2Vital = TriState.False; return false; } int lIntersectionCount = 0; foreach (GoBlockBase lGoBlockBase in EmptyBlocks) foreach (int lPoint in lGoBlockBase.Members) if (IsIntersection(lPoint)) // if (EnclosingBlocks.Count > 1) { bool AdjacentToAll = true; //foreach (GoBlock lGoBlock in EnclosingBlocks) foreach (GoBlock lGoBlock in Neighbors) if (!lGoBlock.Liberties.Contains(lPoint)) { AdjacentToAll = false; break; } if (AdjacentToAll) { lIntersectionCount++; if (lIntersectionCount >= 2) { Is2Vital = TriState.True; return true; } } } Is2Vital = TriState.False; return false; }
public bool IsSmallEnclosed() { if (IsSmall.IsKnown) return (IsSmall.IsTrue); if (EmptyArea.HasInterior()) { IsSmall = TriState.False; return false; } IsSmall = TriState.True; return true; }
public bool IsOneVital() { if (Is1Vital.IsKnown) return (Is1Vital.IsTrue); if (EnclosingBlocks.Count == 0) { Is1Vital = TriState.False; return false; } // step 1 // build miai stragety MiaiStrategy = new MiaiStrategy(); Region lAccessibleLibertiesAvailable = new Region(AccessibleLiberties); if (!CreateBlocksConnectionStrategy(lAccessibleLibertiesAvailable, MiaiStrategy)) { Is1Vital = TriState.False; return false; } // step 2 // future: add miai accessible interior empty points to the set of accessible liberties, // and also use protected liberties for the chaining. Region lNewAccessibleRegion = new Region(AccessibleLiberties); foreach (GoBlock lGoBlock in InteriorDefenderBlocks) lNewAccessibleRegion.Add(lGoBlock.Liberties); // step 2a - add miai accessible interior empty points to the set of accessible liberties // rough implementation Region lMiaiAccessibleInteriorRegion = new Region(Board.BoardSize); if (Version >= 2004) { foreach (int lIndex in EmptyArea) if (!lNewAccessibleRegion.Contains(lIndex)) { List<int> llAccessibleNeighborPoints = new List<int>(4); foreach (int lNeighbor in Board.Coord.GetNeighbors(lIndex)) if (lNewAccessibleRegion.Contains(lNeighbor)) llAccessibleNeighborPoints.Add(lNeighbor); if (llAccessibleNeighborPoints.Count >= 2) { lMiaiAccessibleInteriorRegion.Add(lIndex); } } } lNewAccessibleRegion.Add(lMiaiAccessibleInteriorRegion); // step 3 Region lEmptyAndNotAccessible = new Region(EmptyArea); lEmptyAndNotAccessible.Remove(lNewAccessibleRegion); List<int> lList = lEmptyAndNotAccessible.ToList(); int lMinAdjacent = 2; while (lList.Count != 0) { List<int> lRemove = new List<int>(); foreach (int lIndex in lList) { List<int> lAccessibleLibertiesForPoint = new List<int>(4); foreach (int lNeighbor in Board.Coord.GetNeighbors(lIndex)) if (lNewAccessibleRegion.Contains(lNeighbor)) lAccessibleLibertiesForPoint.Add(lNeighbor); if (lAccessibleLibertiesForPoint.Count < 2) { Is1Vital = TriState.False; return false; } if ((lAccessibleLibertiesForPoint.Count == 2) || (lAccessibleLibertiesForPoint.Count == lMinAdjacent)) { lNewAccessibleRegion.Remove(lAccessibleLibertiesForPoint[0]); lNewAccessibleRegion.Remove(lAccessibleLibertiesForPoint[1]); MiaiStrategy.Add(lIndex, lAccessibleLibertiesForPoint[0], lAccessibleLibertiesForPoint[1]); lRemove.Add(lIndex); lMinAdjacent = 2; } } if (lList.Count == lRemove.Count) lList.Clear(); else foreach (int lPoint in lRemove) lList.Remove(lPoint); if (lRemove.Count == 0) lMinAdjacent++; } Is1Vital = TriState.True; return true; }