private void FloodFill()
        {
            // we use byte.MaxValue as an 'unset' state value
            for (int i = 0; i < _cellStack.Length; i++)
            {
                _cellStack[i] = GridStateConstants.UNSET;
            }

            for (int i = 0; i < _floodState.Length; i++)
            {
                _floodState[i] = GridStateConstants.UNSET;
            }

            // Add starting cell - must be free
            Push(_startIndex);

            do
            {
                var index = Pop();
                if (index == GridStateConstants.UNSET)
                {
                    break;
                }

                _floodState[index] = GridStateConstants.FLOODED;

                var(x, y) = GridUtils.GetCoordinates(index, _rows);
                if (GridUtils.HasOutOfBoundsNeighbour(x, y, _rows, _cols))
                {
                    continue;
                }

                // Left
                var left = GridUtils.GetIndex(x - 1, y, _rows);
                if (_gridState[left] == GridStateConstants.FREE && _floodState[left] != GridStateConstants.FLOODED)
                {
                    Push(left);
                }

                // Right
                var right = GridUtils.GetIndex(x + 1, y, _rows);
                if (_gridState[right] == GridStateConstants.FREE && _floodState[right] != GridStateConstants.FLOODED)
                {
                    Push(right);
                }

                var up = GridUtils.GetIndex(x, y + 1, _rows);
                if (_gridState[up] == GridStateConstants.FREE && _floodState[up] != GridStateConstants.FLOODED)
                {
                    Push(up);
                }

                var down = GridUtils.GetIndex(x, y - 1, _rows);
                if (_gridState[down] == GridStateConstants.FREE && _floodState[down] != GridStateConstants.FLOODED)
                {
                    Push(down);
                }
            } while (_stackCount > 0);
        }
Exemplo n.º 2
0
 public void Execute(int index)
 {
     var(x, y) = GridUtils.GetCoordinates(index, _rows);
     if (GridUtils.HasOutOfBoundsNeighbour(x, y, _rows, _cols))
     {
         _gridState[index] = GridStateConstants.BLOCKED;
     }
 }
        private void FloodGate()
        {
            for (var index = _cols; index < _gridState.Length - _cols; index++)
            {
                if (_floodState[index] != GridStateConstants.FLOODED)
                {
                    continue;
                }

                var(x, y) = GridUtils.GetCoordinates(index, _rows);
                var topLeft  = GridUtils.GetIndex(x - 1, y + 1, _rows);
                var topRight = GridUtils.GetIndex(x + 1, y - 1, _rows);
                var botLeft  = GridUtils.GetIndex(x - 1, y - 1, _rows);
                var botRight = GridUtils.GetIndex(x + 1, y - 1, _rows);

                int targetIndex;
                if (_gridState[topLeft] == GridStateConstants.FREE || _gridState[botLeft] == GridStateConstants.FREE)
                {
                    targetIndex = x - 1; // left cell
                }
                else if (_gridState[topRight] == GridStateConstants.FREE || _gridState[botRight] == GridStateConstants.FREE)
                {
                    targetIndex = x + 1; // right cell
                }
                else
                {
                    continue;
                }

                var(targetX, targetY) = GridUtils.GetCoordinates(targetIndex, _rows);
                if (GridUtils.HasOutOfBoundsNeighbour(targetX, targetY, _rows, _cols))
                {
                    continue;
                }

                //UnityEngine.Debug.Log($"index: {index} has {freeNeighbours} free neighbours, delta: {freeNeighbourIdx - index}");
                _gridState[targetIndex] = GridStateConstants.FREE;
            }
        }