Example #1
0
        public void SpreadingPositionStopCondition()
        {
            var markMatrix = new int[10, 5];
            Action <int, int, int> neighbourProcessor =
                (x, y, mark) => Console.WriteLine($"Processing {x}, {y} as a neighbour with {mark} mark.");
            Action <int, int> positionVisitor =
                (x, y) => Console.WriteLine($"Visiting {x}, {y}");
            Predicate <int, int> spreadingPositionStopCondition = (x, y) =>
            {
                if (x > 1)
                {
                    Console.WriteLine($"{x}, {y} causing stop!");
                    return(true);
                }
                return(false);
            };
            var floodParameters = new FloodParameters(0, 0)
            {
                NeighbourProcessor             = neighbourProcessor,
                SpreadingPositionVisitor       = positionVisitor,
                SpreadingPositionStopCondition = spreadingPositionStopCondition
            };

            new FloodSpiller().SpillFlood(floodParameters, markMatrix);

            string representation = MarkMatrixVisualiser.Visualise(markMatrix);

            Console.WriteLine(representation);
        }
Example #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
        }
        public void FloodSpill_LakeSituationWithPriorityQueue_CorrectlySpillsLake()
        {
            string heightInput = "98999" + Environment.NewLine + //.....
                                 "95799" + Environment.NewLine + //.l...	   l - expected lake
/*start position is at 2 --> */ "92789" + Environment.NewLine +  //.l...	   . - expected land
                                 "93499" + Environment.NewLine + //.ll..
                                 "96999" + Environment.NewLine + //.l...
                                 "94999";                        //.L...       L - last lake position which will become a new river

            //		       bottom-left corner is 0,0
            // water should spill to lowest positions adjacent to flood: 2, 3, 4, 5, 6, 4
            float[,] heightMap = CreateHeightMapFromString(heightInput);

            var      markMatrix       = new int[5, 6];
            Position startingPosition = new Position(1, 3);

            float lakeSurfaceHeight = heightMap[startingPosition.X, startingPosition.Y];
            Predicate <int, int> stopConditionForVisited = (x, y) => heightMap[x, y] < lakeSurfaceHeight;
            var lakePositions = new List <Position>();
            Action <int, int> positionVisitorWithSurfaceAdjustmentAndListBuilding = (currentX, currentY) =>
            {
                float positionHeight = heightMap[currentX, currentY];
                if (positionHeight > lakeSurfaceHeight)
                {
                    lakeSurfaceHeight = positionHeight;
                }

                lakePositions.Add(new Position(currentX, currentY));
            };

            Func <Position, Position, int> positionComparerByHeight =
                (first, second) => heightMap[first.X, first.Y].CompareTo(heightMap[second.X, second.Y]);

            var parameters = new FloodParameters(new PriorityPositionQueue(positionComparerByHeight), startingPosition.X, startingPosition.Y)
            {
                SpreadingPositionVisitor       = positionVisitorWithSurfaceAdjustmentAndListBuilding,
                SpreadingPositionStopCondition = stopConditionForVisited
            };

            // act
            new FloodSpiller().SpillFlood(parameters, markMatrix);

            // assert lakePositions are calculated correctly and have proper marks
            Position[] expectedLakePositions =
            {
                new Position(1, 0),
                new Position(1, 1),
                new Position(1, 2),
                new Position(2, 2),
                new Position(1, 3),
                new Position(1, 4),
            };
            lakePositions.Should().BeEquivalentTo(expectedLakePositions);
            Console.WriteLine(MarkMatrixVisualiser.Visualise(markMatrix));
        }
Example #4
0
        public void Scanline_NoWalls_Fifo()
        {
            var markMatrix      = new int[8, 10];
            var floodParameters = new FloodParameters(4, 2);

            new FloodScanlineSpiller().SpillFlood(floodParameters, markMatrix);

            string representation = MarkMatrixVisualiser.Visualise(markMatrix);

            Console.WriteLine(representation);
        }
Example #5
0
        public void NoWalls_Lifo()
        {
            var markMatrix      = new int[10, 5];
            var floodParameters = new FloodParameters(new LifoPositionQueue(), 1, 1);

            new FloodSpiller().SpillFlood(floodParameters, markMatrix);

            string representation = MarkMatrixVisualiser.Visualise(markMatrix);

            Console.WriteLine(representation);
        }
Example #6
0
        public void NoWalls_Fifo()
        {
            var markMatrix      = new int[10, 5];
            var floodParameters = new FloodParameters(startX: 1, startY: 1);

            new FloodSpiller().SpillFlood(floodParameters, markMatrix);

            string representation = MarkMatrixVisualiser.Visualise(markMatrix);

            Console.WriteLine(representation);
        }
Example #7
0
        public void DisallowDiagonalNeighbourhood()
        {
            var markMatrix      = new int[10, 5];
            var floodParameters = new FloodParameters(1, 1)
            {
                NeighbourhoodType = NeighbourhoodType.Four
            };

            new FloodSpiller().SpillFlood(floodParameters, markMatrix);

            string representation = MarkMatrixVisualiser.Visualise(markMatrix);

            Console.WriteLine(representation);
        }
Example #8
0
        public void NegativeBounds()
        {
            var markMatrix      = new int[10, 5];
            var floodParameters = new FloodParameters(-99, -99)
            {
                BoundsRestriction = new FloodBounds(minX: -100, minY: -100, sizeX: 10, sizeY: 5)
            };

            new FloodSpiller().SpillFlood(floodParameters, markMatrix);

            string representation = MarkMatrixVisualiser.Visualise(markMatrix);

            Console.WriteLine(representation);
        }
Example #9
0
        public void SpillFlood_FloodDoesNotReachPositionsThatAreValidButBlockedByUnreachablePositions(FloodSpiller spiller)
        {
            float seaLevel = 0.5f;
            var   heights  = new float[4, 4];
            var   positionsToSetUnderThreshold = new[]
            {
                new Position(0, 0), new Position(1, 0),
                new Position(0, 1), new Position(3, 1),
                new Position(0, 2),
                new Position(0, 3), new Position(1, 3), new Position(2, 0), new Position(3, 3)
            };
            var positionsToSetAboveThreshold = new[]
            {
                new Position(2, 0), new Position(3, 0),
                new Position(1, 1), new Position(2, 1),
                new Position(1, 2), new Position(2, 2), new Position(3, 2)
            };

            foreach (Position positionUnder in positionsToSetUnderThreshold)
            {
                heights[positionUnder.X, positionUnder.Y] = 0f;
            }
            foreach (Position positionAbove in positionsToSetAboveThreshold)
            {
                heights[positionAbove.X, positionAbove.Y] = 1f;
            }

            Predicate <int, int> isBelowSeaLevel = (x, y) => heights[x, y] < seaLevel;

            var result     = new int[4, 4];
            var parameters = new FloodParameters(0, 0)
            {
                Qualifier = isBelowSeaLevel
            };

            spiller.SpillFlood(parameters, result);
            Console.WriteLine(MarkMatrixVisualiser.Visualise(result));

            result[0, 0].Should().Be(0);             // starting position
            result[1, 0].Should().BeLessThan(int.MaxValue);
            result[0, 1].Should().BeLessThan(int.MaxValue);
            result[0, 2].Should().BeLessThan(int.MaxValue);
            result[0, 3].Should().BeLessThan(int.MaxValue);
            result[1, 3].Should().BeLessThan(int.MaxValue);
            result[2, 3].Should().BeLessThan(int.MaxValue);
            result[3, 3].Should().BeLessThan(int.MaxValue);
            result[1, 1].Should().Be(int.MaxValue);             // above threshold
            result[2, 2].Should().Be(int.MaxValue);             // above threshold
            result[3, 1].Should().Be(int.MaxValue);             // under threshold, unreachable
        }
Example #10
0
        public void Bounds()
        {
            var markMatrix      = new int[10, 5];
            var floodParameters = new FloodParameters(7, 7)
            {
                BoundsRestriction = new FloodBounds(minX: 5, minY: 5, sizeX: 5, sizeY: 3)
                                    // markMatrix will be accessed with offset, so that we don't have IndexOutOfRangeExceptions
            };

            new FloodSpiller().SpillFlood(floodParameters, markMatrix);

            string representation = MarkMatrixVisualiser.Visualise(markMatrix);

            Console.WriteLine(representation);
        }
Example #11
0
        public void NoWalls_PriorityQueue()
        {
            var      markMatrix = new int[10, 10];
            Position center     = new Position(5, 5);
            Func <Position, Position, int> distanceToCenterComparer =            // favours positions closer to center
                                                                      (first, second) => Position.Distance(center, first).CompareTo(Position.Distance(center, second));
            var priorityQueue   = new PriorityPositionQueue(distanceToCenterComparer);
            var floodParameters = new FloodParameters(priorityQueue, 1, 1);

            new FloodSpiller().SpillFlood(floodParameters, markMatrix);

            string representation = MarkMatrixVisualiser.Visualise(markMatrix);

            Console.WriteLine(representation);
        }
Example #12
0
        public void Scanline_CallbacksForProcessingNeighboursAndVisitingPositions()
        {
            var markMatrix = new int[3, 5];
            Action <int, int, int> neighbourProcessor =
                (x, y, mark) => Console.WriteLine($"Processing {x}, {y} as a neighbour with {mark} mark.");
            Action <int, int> positionVisitor =
                (x, y) => Console.WriteLine($"Visiting {x}, {y}");
            var floodParameters = new FloodParameters(1, 1)
            {
                NeighbourProcessor       = neighbourProcessor,
                SpreadingPositionVisitor = positionVisitor
            };

            new FloodScanlineSpiller().SpillFlood(floodParameters, markMatrix);

            string representation = MarkMatrixVisualiser.Visualise(markMatrix);

            Console.WriteLine(representation);
        }
Example #13
0
        public void SomeWalls()
        {
            var wallMatrix = new bool[6, 5];

            wallMatrix[2, 0] = wallMatrix[2, 1] = wallMatrix[2, 2]
                                                      = wallMatrix[3, 0] = wallMatrix[3, 1] = wallMatrix[3, 2] = true;

            Predicate <int, int> positionQualifier = (x, y) => wallMatrix[x, y] == false;

            var floodParameters = new FloodParameters(startX: 0, startY: 0)
            {
                Qualifier = positionQualifier
            };
            var markMatrix = new int[6, 5];

            new FloodSpiller().SpillFlood(floodParameters, markMatrix);

            string representation = MarkMatrixVisualiser.Visualise(markMatrix);

            Console.WriteLine(representation);
        }