Exemple #1
0
 public GoChain(GoBlock goBlock, Region AccessibleLiberties)
 {
     Blocks = new List<GoBlock>();
     Blocks.Add(goBlock);
     Liberities = new Region(goBlock.Liberties, AccessibleLiberties, Region.MergeType.And);
     UsedLiberities = new List<int>();
 }
Exemple #2
0
 public Region(Region region)
 {
     Width = region.Width;
     Count = region.Count;
     Grid = new bool[Width * Width];
     region.Grid.CopyTo(Grid, 0);
 }
Exemple #3
0
        public Region(Region region1, Region region2, MergeType mergeType)
        {
            Width = region1.Width;
            Count = region1.Count;
            Grid = new bool[Width * Width];

            if (region1.Width != region2.Width)
                return;	// error: can't merge unlike regions

            if (mergeType == MergeType.And)
            {
                for (int i = 0; i < Width * Width; i++)
                    if ((region1.Grid[i]) && (region2.Grid[i]))
                        Add(i);
            }
            else
                if (mergeType == MergeType.Or)
                {
                    for (int i = 0; i < Width * Width; i++)
                        if ((region1.Grid[i]) || (region2.Grid[i]))
                            Add(i);
                }
                else
                    if (mergeType == MergeType.NAnd)
                    {
                        for (int i = 0; i < Width * Width; i++)
                            if ((region1.Grid[i]) && (!region2.Grid[i]))
                                Add(i);
                    }
        }
Exemple #4
0
        public void AddBlock(GoBlock goBlock)
        {
            Blocks.Add(goBlock);

            if (Liberities != null)
                Liberities.Add(goBlock.Liberties);
            else
                Liberities = new Region(goBlock.Liberties);
        }
Exemple #5
0
        protected static int BlockNbrCounter = 0; // used for debugging

        #endregion Fields

        #region Constructors

        public GoBlockBase(GoBoard goBoard, Color blockColor)
        {
            Board = goBoard;
            BlockColor = blockColor;
            AdjacentBlocks = new GoBlocksAdjacentCollection(this);

            Members = new Region(Board.BoardSize);
            MemberList = new List<int>();

            BlockNbr = ++BlockNbrCounter;
        }
Exemple #6
0
        public void Remove(Region region)
        {
            if (region.Width != Width)
                return;	// error: can't merge unlike regions

            if ((Count == 0) || (region.Count == 0))
                return;

            for (int i = 0; i < Width * Width; i++)
                if (region.Contains(i))
                    Remove(i);
        }
Exemple #7
0
        public void Or(Region region)
        {
            if ((Count == 0) && (region.Count == 0))
                return;

            if (region.Width != Width)
                return;	// error: can't merge unlike regions

            for (int i = 0; i < Width * Width; i++)
                if (region.Contains(i))
                    Add(i);
        }
Exemple #8
0
        public bool IsSame(Region region)
        {
            if (Count != region.Count)
                return false;

            for (int i = 0; i < Width * Width; i++)
                if (region.Contains(i) != Contains(i))
                    return false;

            return true;
        }
Exemple #9
0
 public GoEmptyBlock(GoEmptyBlock goEmptyBlock, int pCutPoint, int direction)
     : base(goEmptyBlock.Board, Color.Empty)
 {
     Members = new Region(goEmptyBlock.Members, pCutPoint, direction);
     MemberList = Members.ToList();
 }
Exemple #10
0
 /// <summary>
 /// Initializes a new instance of the <see cref="GoBlock"/> class.
 /// </summary>
 /// <param name="goBoard">The board.</param>
 /// <param name="color">The color of the block.</param>
 public GoBlock(GoBoard goBoard, Color color)
     : base(goBoard, color)
 {
     Liberties = new Region(goBoard.BoardSize);
 }
        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 #12
0
        public Region GetEdges()
        {
            Region lRegion = new Region(this.Width);

            for (int i = 0; i < Width * Width; i++)
                if (!IsInterior(i))
                    lRegion.Add(i);

            return lRegion;
        }
Exemple #13
0
        public void Add(Region region)
        {
            if (region.Width != Width)
                return;	// error: can't merge unlike regions

            for (int i = 0; i < Width * Width; i++)
                if (region.Grid[i] == true)
                    Add(i);
        }
Exemple #14
0
        public Region(Region region, int cutPoint, int start)
        {
            Width = region.Width;
            Count = 0;
            Grid = new bool[Width * Width];

            CoordinateSystem lCoord = CoordinateSystem.GetCoordinateSystem(Width);

            if (!lCoord.OnBoard(start))
                return;

            Stack<int> lFill = new Stack<int>();
            lFill.Push(start);

            while (lFill.Count > 0)
            {
                int lAt = lFill.Pop();
                Add(lAt);

                foreach (int lNeighbor in lCoord.GetNeighbors(lAt))
                    if ((lNeighbor != cutPoint)
                        && (region.Contains(lNeighbor))
                        && (!Contains(lNeighbor)))
                        lFill.Push(lNeighbor);
            }
        }
Exemple #15
0
        public List<int> SharedLibertyPoints(GoChain goChain)
        {
            List<int> lSharedLibertyPoints = new List<int>();

            if ((Liberities.Count <= 1) || (goChain.Liberities.Count <= 1))
                return lSharedLibertyPoints;

            Region lShared = new Region(Liberities, goChain.Liberities, Region.MergeType.And);

            foreach (int lPoint in UsedLiberities)
                lShared.Remove(lPoint);

            foreach (int lPoint in goChain.UsedLiberities)
                lShared.Remove(lPoint);

            lSharedLibertyPoints = lShared.ToList();

            return lSharedLibertyPoints;
        }
        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;
        }
Exemple #17
0
        public Region GetInterior()
        {
            Region lRegion = new Region(this.Width);

            if (Count != 0)
                for (int i = 0; i < Width * Width; i++)
                    if (IsInterior(i))
                        lRegion.Add(i);

            return lRegion;
        }
        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();
        }
Exemple #19
0
        public bool Intersects(Region region)
        {
            if ((Count == 0) || (region.Count == 0))
                return false;

            for (int i = 0; i < Width * Width; i++)
                if (region.Contains(i) && Contains(i))
                    return true;

            return false;
        }
Exemple #20
0
        public bool IsOnlyAdjacent(Region region)
        {
            if ((Count == 0) || (region.Count == 0))
                return false;

            for (int i = 0; i < Width * Width; i++)
                if (region.Contains(i))
                    if (!IsAdjacent(i))
                        return false;

            return true;
        }
Exemple #21
0
 public GoEmptyBlock(GoBlock goBlock)
     : base(goBlock.Board, Color.Empty)
 {
     Members = new Region(goBlock.Members);
     MemberList = Members.ToList();	// slow might be a faster way
 }