public void Setup()
        {
            _markMatrix = new int[AreaSize, AreaSize];

            switch (ChosenAreaType)
            {
            case AreaType.Open:
                _wallMatrix = new bool[AreaSize, AreaSize]; break;

            case AreaType.WithUnwalkableCircles:
                _wallMatrix = CreateMatrixWithCircles(AreaSize); break;

            case AreaType.WithSparseUnwalkablePillars:
            default:
                _wallMatrix = CreateMatrixWithPillars(AreaSize); break;
            }

            _boundsRestriction = new FloodBounds(AreaSize, AreaSize);
            _qualifier         = (x, y) => !_wallMatrix[x, y];

            int startX = AreaSize == 20 ? 0 : AreaSize / 2;             // gives a non-wall position for area sizes 20, 200 and 2000.
            int startY = startX;

            if (_wallMatrix[startX, startY])
            {
                throw new InvalidOperationException($"{startX}, {startY} is a wall. You shouldn't start benchmark from a wall.");
            }
            _parameters = new FloodParameters(startX, startY)
            {
                BoundsRestriction = _boundsRestriction,
                Qualifier         = _qualifier,
            };

            _floodSpiller = UsingScanline ? (FloodSpiller) new FloodScanlineSpiller() : new FloodSpiller();
        }
示例#2
0
        public void SpillFlood_BoundsDoNotStartFromZero_GivesCorrectMarksRespectingBounds(FloodSpiller floodSpiller)
        {
            // arrange
            int resultArraySize = 4;
            var startingPoint   = new Position(-5, -5);
            var bounds          = new FloodBounds(-5, -5, 2, 2);

            int[,] markMatrix = new int[resultArraySize, resultArraySize];
            var parameters = new FloodParameters(startingPoint.X, startingPoint.Y)
            {
                Qualifier         = (x, y) => y == -5,
                BoundsRestriction = bounds
            };

            // act
            floodSpiller.SpillFlood(parameters, markMatrix);

            Console.WriteLine(MarkMatrixVisualiser.Visualise(markMatrix));

            // assert that reached positions got correct numbers
            markMatrix[0, 0].Should().Be(0);
            markMatrix[1, 0].Should().Be(1);
            markMatrix[2, 0].Should().Be(int.MaxValue);             // out of bounds
            markMatrix[0, 1].Should().Be(int.MaxValue);             // unreachable
            markMatrix[1, 1].Should().Be(int.MaxValue);             // unreachable
        }
示例#3
0
        public void SpillFlood_ExplicitBoundsDoNotContainStartingPosition_ThrowsArgumentException(FloodSpiller floodSpiller)
        {
            var startingPoint = new Position(5, 5);
            var bounds        = new FloodBounds(2, 2, 2, 2);

            int[,] markMatrix = new int[100, 100];
            Action action = () =>
            {
                var parameters = new FloodParameters(startingPoint.X, startingPoint.Y)
                {
                    BoundsRestriction = bounds
                };
                floodSpiller.SpillFlood(parameters, markMatrix);
            };

            action.Should().Throw <ArgumentException>();
        }
        public override IEnumerator Recalculating()
        {
            Position                middle = new Position(Values.XSize / 2, Values.YSize / 2);
            float                   furthestDistanceToMiddle = Position.Distance(Position.MinValue, middle);
            float                   noiseScale            = _config.Scale;
            AnimationCurve          toCenterFalloffCurve  = _config.MaxFactorDistanceFromCenterToFalloff;
            Dictionary <int, float> afterNoiseAdjustments = InitializeAfterNoiseAdjustments(_config.Octaves);

            foreach (Position position in Values.AllCellMiddles())
            {
                Position probedPositionForNoise = position + _noiseOffset;

                float persistence01 = 0.5f;

                float heightValue = Perlin.Noise(probedPositionForNoise.x * noiseScale, probedPositionForNoise.y * noiseScale,
                                                 _config.Octaves, persistence01);
                int adjustmentKey = (int)Math.Round(persistence01 * 10);
                heightValue *= afterNoiseAdjustments[adjustmentKey];

                float distanceToMiddle         = Position.Distance(position, middle);
                float relativeDistanceToMiddle = distanceToMiddle / furthestDistanceToMiddle;
                heightValue *= toCenterFalloffCurve.Evaluate(relativeDistanceToMiddle);
                Values.Set(position, heightValue);
            }

            float cutOffValue = CalculateSeaLevelToMatchGroundPercentage();

            GameContext.SeaLevel = cutOffValue;

            bool Qualifier(int x, int y) => Values.Get(x, y) < cutOffValue;

            var bounds     = new FloodBounds(Values.XSize, Values.YSize);
            var parameters = new FloodParameters(0, 0)
            {
                Qualifier         = Qualifier,
                BoundsRestriction = bounds,
                NeighbourhoodType = NeighbourhoodType.Four
            };

            int[,] closedSeaPositions = new int[bounds.SizeX, bounds.SizeY];
            new FloodSpiller().SpillFlood(parameters, closedSeaPositions);

            BuryDepressions(cutOffValue, closedSeaPositions);

            yield return(new WaitForSeconds(0.1f));
        }
示例#5
0
        public void SpillFlood_ResultArrayIsSmallerThanGivenBounds_ThrowsArgumentException(FloodSpiller floodSpiller)
        {
            int boundsSize = 4;
            var bounds     = new FloodBounds(-10, -10, boundsSize, boundsSize);

            int[,] result = new int[boundsSize - 1, boundsSize];

            Action action = () =>
            {
                var parameters = new FloodParameters(0, 0)
                {
                    BoundsRestriction = bounds
                };
                floodSpiller.SpillFlood(parameters, result);
            };

            action.Should().Throw <ArgumentException>();
        }
示例#6
0
        public void SpillFlood_BoundsDoNotStartFromZero_LambdasAreCalledForCorrectPosition(FloodSpiller floodSpiller)
        {
            int startX = -5;
            int startY = 5;
            var bounds = new FloodBounds(startX, startY, 1, 1);

            int[,] markMatrix = new int[1, 1];
            bool qualifierCalled = false;
            bool neighbourStopConditionCalled         = false;
            bool neighbourProcessorCalled             = false;
            bool spreadingPositionStopConditionCalled = false;
            bool spreadingPositionVisitorCalled       = false;
            var  parametersCheckingIfLambdasAreExecutedForStartingPosition = new FloodParameters(startX, startY)
            {
                BoundsRestriction            = bounds,
                ProcessStartAsFirstNeighbour = true,                 // make first position be both processed as a neighbour and as a visited spreading position.
                Qualifier = (x, y) =>
                {
                    if (x == startX && y == startY)
                    {
                        qualifierCalled = true;
                    }
                    return(true);
                },
                NeighbourStopCondition = (x, y) =>
                {
                    if (x == startX && y == startY)
                    {
                        neighbourStopConditionCalled = true;
                    }
                    return(false);
                },
                NeighbourProcessor = (x, y, mark) =>
                {
                    if (x == startX && y == startY)
                    {
                        neighbourProcessorCalled = true;
                    }
                },
                SpreadingPositionStopCondition = (x, y) =>
                {
                    if (x == startX && y == startY)
                    {
                        spreadingPositionStopConditionCalled = true;
                    }
                    return(false);
                },
                SpreadingPositionVisitor = (x, y) =>
                {
                    if (x == startX && y == startY)
                    {
                        spreadingPositionVisitorCalled = true;
                    }
                }
            };

            floodSpiller.SpillFlood(parametersCheckingIfLambdasAreExecutedForStartingPosition, markMatrix);

            qualifierCalled.Should().BeTrue();
            neighbourStopConditionCalled.Should().BeTrue();
            neighbourProcessorCalled.Should().BeTrue();
            spreadingPositionStopConditionCalled.Should().BeTrue();
            spreadingPositionVisitorCalled.Should().BeTrue();
        }