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); }
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)); }
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); }
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); }
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); }
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); }
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); }
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 }
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); }
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); }
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); }
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); }