Example #1
0
 public FloodVisitor4(NativeArray2D <T> array, TVisitAction action)
 {
     this.array  = array;
     this.action = action;
 }
Example #2
0
        public void FloodVisit8(int startX, int startY, IEqualityComparer <T> comparer = null)
        {
            if (startX < 0 || startX >= array.LengthX)
            {
                throw new ArgumentOutOfRangeException(nameof(startX));
            }
            if (startY < 0 || startY >= array.LengthY)
            {
                throw new ArgumentOutOfRangeException(nameof(startY));
            }

            if (comparer == null)
            {
                comparer = EqualityComparer <T> .Default;
            }

            var processed = new NativeArray2D <bool>(array.LengthX, array.LengthY, Allocator.Temp);
            T   value     = array[startX, startY];

            var queue = new Queue <Vector2Int>();

            queue.Enqueue(new Vector2Int(startX, startY));
            processed[startX, startY] = true;

            void process(ref NativeArray2D <T> array, int x, int y)
            {
                if (!processed[x, y])
                {
                    if (comparer.Equals(array[x, y], value))
                    {
                        queue.Enqueue(new Vector2Int(x, y));
                    }
                    processed[x, y] = true;
                }
            }

            while (queue.Count > 0)
            {
                Vector2Int cell = queue.Dequeue();

                bool xGreaterThanZero = cell.x > 0;
                bool xLessThanWidth   = cell.x + 1 < array.LengthX;

                bool yGreaterThanZero = cell.y > 0;
                bool yLessThanHeight  = cell.y + 1 < array.LengthY;

                if (yGreaterThanZero)
                {
                    if (xGreaterThanZero)
                    {
                        process(ref array, cell.x - 1, cell.y - 1);
                    }

                    process(ref array, cell.x, cell.y - 1);

                    if (xLessThanWidth)
                    {
                        process(ref array, cell.x + 1, cell.y - 1);
                    }
                }

                if (xGreaterThanZero)
                {
                    process(ref array, cell.x - 1, cell.y);
                }
                if (xLessThanWidth)
                {
                    process(ref array, cell.x + 1, cell.y);
                }

                if (yLessThanHeight)
                {
                    if (xGreaterThanZero)
                    {
                        process(ref array, cell.x - 1, cell.y + 1);
                    }

                    process(ref array, cell.x, cell.y + 1);

                    if (xLessThanWidth)
                    {
                        process(ref array, cell.x + 1, cell.y + 1);
                    }
                }

                action.Visit(cell.x, cell.y);
            }
        }