Exemple #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);
        }
        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;
        }
Exemple #3
0
        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 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;
        }