protected bool CreateBlocksConnectionStrategy(Region accessibleLibertiesAvailable, MiaiStrategy miaiStrategy) { List <int> lUsedLiberties = new List <int>((EnclosingBlocks.Count + InteriorDefenderBlocks.Count) * 2); List <GoChain> lGoChains = new List <GoChain>(EnclosingBlocks.Count + InteriorDefenderBlocks.Count); List <GoChain> lCheckList = new List <GoChain>(lGoChains.Count); // future, if any the of the blocks only have one liberty in Accessible, then no strategy foreach (GoBlock lBlock in EnclosingBlocks) { GoChain lGoBlocks = new GoChain(lBlock, accessibleLibertiesAvailable); lGoChains.Add(lGoBlocks); lCheckList.Add(lGoBlocks); } foreach (GoBlock lBlock in InteriorDefenderBlocks) { GoChain lGoBlocks = new GoChain(lBlock, accessibleLibertiesAvailable); lGoChains.Add(lGoBlocks); lCheckList.Add(lGoBlocks); } List <int> lProtectedLiberties = GetProtectedLiberties(); // merge chains based on shared points while (lGoChains.Count != 1) { List <GoChain> lRemoved = new List <GoChain>(lGoChains.Count); List <GoChain> lChanged = new List <GoChain>(lGoChains.Count); if (Version >= 2004) { // merge chains based on protected liberty chaining if (lGoChains.Count > 1) { foreach (int lProtected in lProtectedLiberties) { int lCaptureMove = Board.AnyEmptyLibertyAround(lProtected); // Console.Error.WriteLine("Protected: " + GoBoard.Coord.ToString(lProtected) + " Stop: " + (GoBoard.Coord.ToString(lCaptureMove))); if (!lUsedLiberties.Contains(lCaptureMove)) { List <GoChain> lChains = new List <GoChain>(); foreach (GoChain lGoChain in lGoChains) { if (lGoChain.IsLiberty(lProtected)) { if (!lRemoved.Contains(lGoChain)) { lChains.Add(lGoChain); } } } if (lChains.Count >= 2) { //Console.Error.WriteLine("Merging: " + lChains[0].ToString()); //Console.Error.WriteLine(" with: " + lChains[1].ToString()); lChains[0].MergeGoChain(lChains[1]); lChanged.Add(lChains[0]); lRemoved.Add(lChains[1]); if (lChains.Count == 3) { // Console.Error.WriteLine(" and: " + lChains[1].ToString()); lChains[0].MergeGoChain(lChains[2]); lRemoved.Add(lChains[2]); } miaiStrategy.Add(lProtected, lCaptureMove); lUsedLiberties.Remove(lProtected); lUsedLiberties.Remove(lCaptureMove); } } } } foreach (GoChain lGoChain in lGoChains) { if (!lRemoved.Contains(lGoChain)) { foreach (GoChain lGoChain2 in lCheckList) { if (lGoChain != lGoChain2) { if (!lRemoved.Contains(lGoChain2)) { List <int> lSharedPoints = lGoChain.SharedLibertyPoints(lGoChain2); // sort list by best (near optimal) shared points to use if (lSharedPoints.Count >= 2) { List <int> lBestSharedPoints = new List <int>(2); // find best share points to use for the Miai Stragety // a. find points which only have one empty neightbor foreach (int lIndex in lSharedPoints) { int lEmptyNeighborCount = 0; foreach (int lNieghbor in Board.Coord.GetNeighbors(lIndex)) { if (accessibleLibertiesAvailable.Contains(lNieghbor)) { lEmptyNeighborCount++; } } if (lEmptyNeighborCount == 1) { lBestSharedPoints.Add(lIndex); if (lBestSharedPoints.Count == 2) { break; } } } // b. find point near the last use shared point (from previous step), if any if (lBestSharedPoints.Count == 1) { int lBestSharedPoint = lBestSharedPoints[0]; foreach (int lNieghbor in Board.Coord.GetNeighbors(lBestSharedPoint)) { if (lSharedPoints.Contains(lNieghbor)) { lBestSharedPoints.Add(lNieghbor); break; } } } // c. use any remaining shared points (not always optimal, but okay) if (lBestSharedPoints.Count < 2) { foreach (int lIndex in lSharedPoints) { if (!lBestSharedPoints.Contains(lIndex)) { lBestSharedPoints.Add(lIndex); if (lBestSharedPoints.Count == 2) { break; } } } } lSharedPoints = lBestSharedPoints; lGoChain.MergeGoChain(lGoChain2, lSharedPoints); lChanged.Add(lGoChain); lRemoved.Add(lGoChain2); miaiStrategy.Add(lSharedPoints[0], lSharedPoints[1]); lUsedLiberties.Remove(lSharedPoints[0]); lUsedLiberties.Remove(lSharedPoints[1]); } } } } } } } if (lChanged.Count == 0) { break; } foreach (GoChain lGoChain in lRemoved) { lGoChains.Remove(lGoChain); } lCheckList = lChanged; } if (lGoChains.Count > 1) { return(false); } foreach (int lPoint in lUsedLiberties) { accessibleLibertiesAvailable.Remove(lPoint); } return(true); }