Example #1
0
        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);
        }