public void ResolveNextStep_ActorWasDisplacedToPositionNeighboringLastStepAndNextStep_ReturnsInProgressWithMovementToNextStepAndStackIsEmpty() { var currentPosition = new Position(1, 1); var lastStepPosition = new Position(1, 0); var nextPosition = new Position(2, 0); IPathfinder pathfinder = Mock.Of <IPathfinder>(); IGridInfoProvider gridInfoProvider = Mock.Of <IGridInfoProvider>(p => p.IsWalkable(It.IsAny <Position>()) == true); var bresenham = new BresenhamLineCreator(); var navigator = new Navigator(pathfinder, gridInfoProvider, new NaturalLineCalculator(bresenham), bresenham, Mock.Of <IUiFacade>()); var navigationData = new NavigationData { RemainingStepsInCurrentSegment = new Stack <Position>(new[] { nextPosition }), Destination = nextPosition, RemainingNodes = new[] { nextPosition }.ToList(), LastStep = lastStepPosition }; Position nextStep; NavigationResult result = navigator.ResolveNextStep(navigationData, currentPosition, out nextStep); result.Should().Be(NavigationResult.InProgress); nextStep.Should().Be(nextPosition); navigationData.RemainingStepsInCurrentSegment. Should().BeEmpty(); }
public void GetJumpPoints_IntegrationTest_WallIsBlockingWayToTarget_ReturnsCorrectPath() { /* Illustration: * ...... * .#.... * s#t... * .j....*/ int unityGridXSize = 20; int unityGridYSize = 20; var startPosition = new Position(0, 1); var targetPosition = new Position(2, 1); var expectedMiddleJumpPoint = new Position(1, 0); IRasterLineCreator bresenham = new BresenhamLineCreator(); IOsnowaContextManager contextManager = CreateContextManager(unityGridXSize, unityGridYSize); contextManager.Current.PathfindingData.UpdateWalkability(new Position(1, 1), false); contextManager.Current.PathfindingData.UpdateWalkability(new Position(1, 2), false); var pathfinder = new Pathfinder(contextManager, new NaturalLineCalculator(bresenham), bresenham); IList <Position> jumpPoints = pathfinder.FindJumpPointsWithJps(startPosition, targetPosition).Positions; IList <Position> jumpPointsFromSpatialAstar = pathfinder.FindJumpPointsWithSpatialAstar(startPosition, targetPosition).Positions; jumpPoints.Count.Should().Be(3); jumpPoints[0].Should().Be(startPosition); jumpPoints[1].Should().Be(expectedMiddleJumpPoint); jumpPoints[2].Should().Be(targetPosition); jumpPointsFromSpatialAstar.Count.Should().Be(3); jumpPointsFromSpatialAstar[0].Should().Be(startPosition); jumpPointsFromSpatialAstar[1].Should().Be(expectedMiddleJumpPoint); jumpPointsFromSpatialAstar[2].Should().Be(targetPosition); }
public void GetJumpPoints_IntegrationTest_WallIsBlockingWayToTarget_ReturnsCorrectPath() { /* Illustration: * ........ * ...#.... * ..s#t... * ...j....*/ Position minPositionInUnityGrid = new Position(-10, -10); int unityGridXSize = 20; int unityGridYSize = 20; var startPosition = new Position(0, 0); var targetPosition = new Position(2, 0); var expectedMiddleJumpPoint = new Position(1, -1); Func <Position, bool> isWalkable = position => { if (position == new Position(1, 0) || position == new Position(1, 1)) { return(false); } return(true); }; var grid = Mock.Of <IGrid>( f => f.IsWalkable(It.Is <Position>(v => isWalkable(v))) == true && f.IsWalkable(It.Is <Position>(v => !isWalkable(v))) == false && f.MinPosition == minPositionInUnityGrid && f.XSize == unityGridXSize && f.YSize == unityGridYSize); IRasterLineCreator bresenham = new BresenhamLineCreator(); var pathfinder = new Pathfinder(default, new NaturalLineCalculator(bresenham), bresenham);
public void GetJumpPoints_IntegrationTest_ThereIsNoPathToTarget_ReturnsTargetUnreachable() { /* Illustration: * ....... ###.... #s#t... ###....*/ int unityGridXSize = 20; int unityGridYSize = 20; var startPosition = new Position(1, 1); var targetPosition = new Position(3, 1); IRasterLineCreator bresenham = new BresenhamLineCreator(); IOsnowaContextManager contextManager = CreateContextManager(unityGridXSize, unityGridYSize); contextManager.Current.PathfindingData.UpdateWalkability(new Position(0, 0), false); contextManager.Current.PathfindingData.UpdateWalkability(new Position(0, 1), false); contextManager.Current.PathfindingData.UpdateWalkability(new Position(0, 2), false); contextManager.Current.PathfindingData.UpdateWalkability(new Position(1, 0), false); contextManager.Current.PathfindingData.UpdateWalkability(new Position(1, 2), false); contextManager.Current.PathfindingData.UpdateWalkability(new Position(2, 0), false); contextManager.Current.PathfindingData.UpdateWalkability(new Position(2, 1), false); contextManager.Current.PathfindingData.UpdateWalkability(new Position(2, 2), false); var pathfinder = new Pathfinder(contextManager, new NaturalLineCalculator(bresenham), bresenham); PathfindingResponse jpsResult = pathfinder.FindJumpPointsWithJps(startPosition, targetPosition); jpsResult.Result.Should().Be(PathfindingResult.FailureTargetUnreachable); jpsResult.Positions.Should().BeNull(); PathfindingResponse aStarResult = pathfinder.FindJumpPointsWithSpatialAstar(startPosition, targetPosition); aStarResult.Result.Should().Be(PathfindingResult.FailureTargetUnreachable); aStarResult.Positions.Should().BeNull(); }
public void GetJumpPoints_TargetNotInBounds_ReturnsTargetUnreachable() { /* Illustration: * * ...... t * s..... * */ int unityGridXSize = 6; int unityGridYSize = 2; var startPosition = new Position(0, 0); var targetPosition = new Position(7, 1); IRasterLineCreator bresenham = new BresenhamLineCreator(); var pathfinder = new Pathfinder(CreateContextManager(unityGridXSize, unityGridYSize), new NaturalLineCalculator(bresenham), bresenham); PathfindingResponse jpsResult = pathfinder.FindJumpPointsWithJps(startPosition, targetPosition); jpsResult.Result.Should().Be(PathfindingResult.FailureTargetUnreachable); jpsResult.Positions.Should().BeNull(); PathfindingResponse aStarResult = pathfinder.FindJumpPointsWithSpatialAstar(startPosition, targetPosition); aStarResult.Result.Should().Be(PathfindingResult.FailureTargetUnreachable); aStarResult.Positions.Should().BeNull(); }
public void FindJumpPointsWithJps_IntegrationTest_AllGridIsWalkable_ReturnsCorrectPath() { /* Illustration: * ...... * .jt... - either of the j's should be used * sj.... * ......*/ int unityGridXSize = 20; int unityGridYSize = 20; var startPosition = new Position(0, 1); var targetPosition = new Position(2, 2); var expectedMiddleJumpPoint = new Position(1, 1); var expectedAlternativeMiddleJumpPoint = new Position(1, 2); var contextManager = CreateContextManager(unityGridXSize, unityGridYSize); IRasterLineCreator bresenham = new BresenhamLineCreator(); var pathfinder = new Pathfinder(contextManager, new NaturalLineCalculator(bresenham), bresenham); IList <Position> jumpPoints = pathfinder.FindJumpPointsWithJps(startPosition, targetPosition).Positions; IList <Position> jumpPointsFromSpatialAstar = pathfinder.FindJumpPointsWithSpatialAstar(startPosition, targetPosition).Positions; jumpPoints.Count.Should().Be(3); jumpPoints[0].Should().Be(startPosition); (jumpPoints[1] == expectedMiddleJumpPoint || jumpPoints[1] == expectedAlternativeMiddleJumpPoint).Should().BeTrue(); jumpPoints[2].Should().Be(targetPosition); jumpPointsFromSpatialAstar.Count.Should().Be(3); jumpPointsFromSpatialAstar[0].Should().Be(startPosition); (jumpPointsFromSpatialAstar[1] == expectedMiddleJumpPoint || jumpPointsFromSpatialAstar[1] == expectedAlternativeMiddleJumpPoint).Should().BeTrue(); jumpPointsFromSpatialAstar[2].Should().Be(targetPosition); }
public void GetJumpPoints_TargetNotInBounds_ReturnsNull() { /* Illustration: * * ...... t * s..... * */ Position minPositionInUnityGrid = new Position(0, 0); int unityGridXSize = 6; int unityGridYSize = 2; var startPosition = new Position(0, 0); var targetPosition = new Position(7, 1); Func <Position, bool> isWalkable = position => { return(true); }; var gridInfoProvider = Mock.Of <IGridInfoProvider>( f => f.IsWalkable(It.Is <Position>(v => isWalkable(v))) == true && f.IsWalkable(It.Is <Position>(v => !isWalkable(v))) == false && f.MinPosition == minPositionInUnityGrid && f.XSize == unityGridXSize && f.YSize == unityGridYSize && f.Bounds == new BoundsInt(0, 0, 0, unityGridXSize, unityGridYSize, 1)); IRasterLineCreator bresenham = new BresenhamLineCreator(); var pathfinder = new Pathfinder(gridInfoProvider, new NaturalLineCalculator(bresenham), bresenham); IList <Position> jumpPoints = pathfinder.FindJumpPointsWithJps(startPosition, targetPosition).Positions; IList <Position> jumpPointsFromSpatialAstar = pathfinder.FindJumpPointsWithSpatialAstar(startPosition, targetPosition).Positions; jumpPoints.Should().BeNull(); jumpPointsFromSpatialAstar.Should().BeNull(); }
// .j.t // j#.. // j#.. // s... public void GetNavigationData_TargetIsNotReachableByStraightLineButReachableByPathfinding_PathfinderIsUsedAndReturnsCorrectResult() { var start = new Position(0, 0); var target = new Position(3, 3); var pathfinderMock = new Mock <IPathfinder>(); IGridInfoProvider gridInfoProvider = Mock.Of <IGridInfoProvider>(gip => gip.IsWalkable(It.IsAny <Position>()) == true && gip.IsWalkable(new Position(1, 1)) == false && gip.IsWalkable(new Position(1, 2)) == false); var jumpPointsFromPathfinder = new List <Position> { new Position(0, 0), new Position(0, 1), new Position(0, 2), new Position(1, 3), new Position(3, 3) }; pathfinderMock.Setup(p => p.FindJumpPointsWithJps(It.IsAny <Position>(), It.IsAny <Position>(), It.IsAny <JpsMode>())) .Returns(new PathfindingResult(jumpPointsFromPathfinder)); var bresenham = new BresenhamLineCreator(); var navigator = new Navigator(pathfinderMock.Object, gridInfoProvider, new NaturalLineCalculator(bresenham), bresenham, Mock.Of <IUiFacade>()); NavigationData result = navigator.GetNavigationData(start, target); pathfinderMock.Verify(p => p.FindJumpPointsWithJps(It.IsAny <Position>(), It.IsAny <Position>(), It.IsAny <JpsMode>()), Times.Once); result.Destination.Should().Be(target); result.RemainingNodes[0].Should().Be(new Position(0, 2)); IList <Position> expectedNodes // (0,1) is redundant (because of specific of current JPS implementation) and should be pruned. = new List <Position>(new[] { new Position(0, 2), new Position(1, 3), new Position(3, 3) }); result.RemainingNodes.Should().BeEquivalentTo(expectedNodes, options => options.WithStrictOrderingFor(position => position)); result.RemainingStepsInCurrentSegment.Should().BeEmpty(); }
/// <summary> /// Should be used only in object trees that are not created by dependency injection (e.g. map generation). /// </summary> public static Pathfinder Create(IOsnowaContextManager contextManager) { var bresenhamLineCreator = new BresenhamLineCreator(); //Grid gridForMapGeneration = new Grid(contextManager, pathfindingDataHolder, true); var pathfinder = new Pathfinder(contextManager, new NaturalLineCalculator(bresenhamLineCreator), bresenhamLineCreator); //pathfinder.InitializeAlgorithms(); return(pathfinder); }
public void NoConstraints_ReturnsCorrectFullLine() { Position start = new Position(1, 1); Position end = new Position(4, 3); var creator = new BresenhamLineCreator(); IList <Position> result = creator.GetRasterLine(start.x, start.y, end.x, end.y); result.Should().BeEquivalentTo(new[] { new Position(1, 1), new Position(2, 2), new Position(3, 2), new Position(4, 3) }, options => options.WithStrictOrdering()); }
public void Permissive_WallCanBeAvoidedBySecondaryChoicesButLeadsToFailure_ReturnsCorrectLine() { Position start = new Position(1, 1); Position end = new Position(5, 3); var creator = new BresenhamLineCreator(); var blockers = new[] { new Position(2, 2), new Position(3, 2), new Position(4, 2) }.ToList(); IList <Position> result = creator.GetRasterLinePermissive(start.x, start.y, end.x, end.y, position => !blockers.Contains(position), -1); result.Should().BeEquivalentTo(new[] { new Position(1, 1), new Position(2, 1), new Position(3, 1), new Position(4, 2) }, options => options.WithStrictOrdering()); }
public void Permissive_VerticalLineBlocked_ReturnsCorrectLine() { Position start = new Position(1, 1); Position end = new Position(1, 3); var creator = new BresenhamLineCreator(); var blockers = new[] { new Position(1, 2) }.ToList(); IList <Position> result = creator.GetRasterLinePermissive(start.x, start.y, end.x, end.y, position => !blockers.Contains(position), -1); result.Should().BeEquivalentTo(new[] { new Position(1, 1), new Position(1, 2) }, options => options.WithStrictOrdering()); }
public void LineWithPositiveLimit_ReturnsLineWithProperLength() { Position start = new Position(1, 1); Position end = new Position(4, 3); var creator = new BresenhamLineCreator(); int limit = 3; IList <Position> result = creator.GetRasterLine(start.x, start.y, end.x, end.y, limit); result.Should().BeEquivalentTo(new[] { new Position(1, 1), new Position(2, 2), new Position(3, 2) }, options => options.WithStrictOrdering()); }
public void Permissive_WallCanBeAvoidedBySecondaryChoices_ReturnsCorrectFullLine() { Position start = new Position(1, 1); Position end = new Position(4, 3); var creator = new BresenhamLineCreator(); Position blocker = new Position(2, 2); IList <Position> result = creator.GetRasterLinePermissive(start.x, start.y, end.x, end.y, position => position != blocker, -1); result.Should().BeEquivalentTo(new[] { new Position(1, 1), new Position(2, 1), new Position(3, 2), new Position(4, 3) }, options => options.WithStrictOrdering()); }
public void LineWithObstacleAndDoesNotAllowFinishOnBlocker_ReturnsLineFinishingBeforeBlocker() { Position start = new Position(1, 1); Position end = new Position(4, 3); var creator = new BresenhamLineCreator(); Position blocker = new Position(2, 2); IList <Position> result = creator.GetRasterLine(start.x, start.y, end.x, end.y, position => position != blocker, false); result.Should().BeEquivalentTo(new[] { new Position(1, 1) }, options => options.WithStrictOrdering()); }
public void LineWithObstacleAndLimitAndLimitIsAfterObstacle_ReturnsLineTerminatedOnObstacle() { Position start = new Position(1, 1); Position end = new Position(4, 3); var creator = new BresenhamLineCreator(); Position blocker = new Position(2, 2); IList <Position> result = creator.GetRasterLine(start.x, start.y, end.x, end.y, 500, position => position != blocker, true); result.Should().BeEquivalentTo(new[] { new Position(1, 1), new Position(2, 2) }, options => options.WithStrictOrdering()); }
public void LineWithLimitZero_ReturnsEmptyLine() { Position start = new Position(1, 1); Position end = new Position(4, 3); var creator = new BresenhamLineCreator(); int limit = 0; IList <Position> result = creator.GetRasterLine(start.x, start.y, end.x, end.y, limit); result.Should().BeEquivalentTo(new Position[] {}, options => options.WithStrictOrdering()); }
public void TwoLinesThereAndBackAreDifferent() { var bresenham = new BresenhamLineCreator(); var from = new Vector2Int(0, 0); var to = new Vector2Int(2, 1); IList <Vector2Int> there = bresenham.GetBresenhamLine(from.x, from.y, to.x, to.y); IList <Vector2Int> back = bresenham.GetBresenhamLine(to.x, to.y, from.x, from.y); there.Should().NotBeEquivalentTo(back); }
public void GetNavigationData_TargetIsReachableByStraightLine_PathfinderIsNotUsedAndReturnsCorrectResult() { var start = new Position(0, 0); var target = new Position(3, 3); var pathfinder = new Mock <IPathfinder>(); IGridInfoProvider gridInfoProvider = Mock.Of <IGridInfoProvider>(gip => gip.IsWalkable(It.IsAny <Position>()) == true); var bresenham = new BresenhamLineCreator(); var navigator = new Navigator(pathfinder.Object, gridInfoProvider, Mock.Of <INaturalLineCalculator>(), bresenham, Mock.Of <IUiFacade>()); NavigationData result = navigator.GetNavigationData(start, target); pathfinder.Verify(p => p.FindJumpPointsWithJps(It.IsAny <Position>(), It.IsAny <Position>(), It.IsAny <JpsMode>()), Times.Never); result.Destination.Should().Be(target); result.RemainingNodes.Should().BeEquivalentTo(new[] { target }); result.RemainingStepsInCurrentSegment.Should().BeEmpty(); }
public void ResolveNextStep_NextStepIsUnwalkable_RecalculatesNavigationDataAndReturnsResultForNewPath() { var currentPosition = new Position(2, 2); var nextStepOnStack = new Position(3, 2); var alternativeNextStep = new Position(3, 3); var destination = new Position(4, 2); IPathfinder pathfinder = Mock.Of <IPathfinder>(); IGridInfoProvider gridInfoProvider = Mock.Of <IGridInfoProvider>(p => p.IsWalkable(It.IsAny <Position>()) == true && p.IsWalkable(nextStepOnStack) == false ); var bresenham = new BresenhamLineCreator(); var navigatorMockReal = new Mock <Navigator>(pathfinder, gridInfoProvider, new NaturalLineCalculator(bresenham), bresenham, Mock.Of <IUiFacade>()) { CallBase = true }; var currentNavigationData = new NavigationData { Destination = destination, RemainingStepsInCurrentSegment = new Stack <Position>(new[] { destination, nextStepOnStack }) }; var recalculatedNavigationData = new NavigationData { Destination = destination, RemainingNodes = new[] { alternativeNextStep, destination }.ToList(), RemainingStepsInCurrentSegment = new Stack <Position>(new [] { alternativeNextStep }), LastStep = currentPosition }; navigatorMockReal.Setup(n => n.GetNavigationData(currentPosition, destination)).Returns(recalculatedNavigationData); Position nextStep; NavigationResult result = navigatorMockReal.Object.ResolveNextStep(currentNavigationData, currentPosition, out nextStep); result.Should().Be(NavigationResult.InProgressWithRecalculation); var expectedNavigationData = new NavigationData { Destination = destination, RemainingNodes = new[] { destination }.ToList(), RemainingStepsInCurrentSegment = new Stack <Position>(), LastStep = alternativeNextStep }; currentNavigationData.Should().BeEquivalentTo(expectedNavigationData); nextStep.Should().Be(alternativeNextStep); }
public void GetNavigationData_TargetIsNotReachableByStraightLineNorByPathfinding_ReturnsNull() { var start = new Position(0, 0); var target = new Position(3, 3); var pathfinderMock = new Mock <IPathfinder>(); IGridInfoProvider gridInfoProvider = Mock.Of <IGridInfoProvider>(gip => gip.IsWalkable(It.IsAny <Position>()) == true && gip.IsWalkable(new Position(1, 1)) == false && gip.IsWalkable(new Position(1, 2)) == false); var bresenham = new BresenhamLineCreator(); var navigator = new Navigator(pathfinderMock.Object, gridInfoProvider, new NaturalLineCalculator(bresenham), bresenham, Mock.Of <IUiFacade>()); NavigationData result = navigator.GetNavigationData(start, target); pathfinderMock.Verify(p => p.FindJumpPointsWithJps(It.IsAny <Position>(), It.IsAny <Position>(), It.IsAny <JpsMode>()), Times.Once); result.Should().BeNull(); }
public void GetJumpPoints_IntegrationTest_WallIsBlockingWayToTarget_ReturnsCorrectPath() { /* Illustration: * ........ * ...#.... * ..s#t... * ...j....*/ Position minPositionInUnityGrid = new Position(-10, -10); int unityGridXSize = 20; int unityGridYSize = 20; var startPosition = new Position(0, 0); var targetPosition = new Position(2, 0); var expectedMiddleJumpPoint = new Position(1, -1); Func <Position, bool> isWalkable = position => { if (position == new Position(1, 0) || position == new Position(1, 1)) { return(false); } return(true); }; var gridInfoProvider = Mock.Of <IGridInfoProvider>( f => f.IsWalkable(It.Is <Position>(v => isWalkable(v))) == true && f.IsWalkable(It.Is <Position>(v => !isWalkable(v))) == false && f.MinPosition == minPositionInUnityGrid && f.XSize == unityGridXSize && f.YSize == unityGridYSize && f.Bounds == new BoundsInt(0, 0, 0, unityGridXSize, unityGridYSize, 1)); IRasterLineCreator bresenham = new BresenhamLineCreator(); var pathfinder = new Pathfinder(gridInfoProvider, new NaturalLineCalculator(bresenham), bresenham); IList <Position> jumpPoints = pathfinder.FindJumpPointsWithJps(startPosition, targetPosition).Positions; IList <Position> jumpPointsFromSpatialAstar = pathfinder.FindJumpPointsWithSpatialAstar(startPosition, targetPosition).Positions; jumpPoints.Count.Should().Be(3); jumpPoints[0].Should().Be(startPosition); jumpPoints[1].Should().Be(expectedMiddleJumpPoint); jumpPoints[2].Should().Be(targetPosition); jumpPointsFromSpatialAstar.Count.Should().Be(3); jumpPointsFromSpatialAstar[0].Should().Be(startPosition); jumpPointsFromSpatialAstar[1].Should().Be(expectedMiddleJumpPoint); jumpPointsFromSpatialAstar[2].Should().Be(targetPosition); }
public void FindJumpPointsWithJps_IntegrationTest_AllGridIsWalkable_ReturnsCorrectPath(int xOffset, int yOffset) { /* Illustration: * ........ * ...jt... * ..sj.... * ........*/ Position minPositionInUnityGrid = new Position(-10, -10); int unityGridXSize = 20; int unityGridYSize = 20; Position offset = new Position(xOffset, yOffset); var startPosition = new Position(0, 0) + offset; var targetPosition = new Position(2, 1) + offset; var expectedMiddleJumpPoint = new Position(1, 1) + offset; var expectedAlternativeMiddleJumpPoint = new Position(1, 0) + offset; PathfindingDataHolder pathfindingData = new PathfindingDataHolder(unityGridXSize, unityGridYSize); for (int x = 0; x < unityGridXSize; x++) { for (int y = 0; y < unityGridYSize; y++) { var position = new Position(x, y); pathfindingData.UpdateWalkability(position, true); } } var contextManager = Mock.Of <IOsnowaContextManager>(m => m.Current.PathfindingData == pathfindingData); IRasterLineCreator bresenham = new BresenhamLineCreator(); var pathfinder = new Pathfinder(contextManager, new NaturalLineCalculator(bresenham), bresenham); IList <Position> jumpPoints = pathfinder.FindJumpPointsWithJps(startPosition, targetPosition).Positions; IList <Position> jumpPointsFromSpatialAstar = pathfinder.FindJumpPointsWithSpatialAstar(startPosition, targetPosition).Positions; jumpPoints.Count.Should().Be(3); jumpPoints[0].Should().Be(startPosition); (jumpPoints[1] == expectedMiddleJumpPoint || jumpPoints[1] == expectedAlternativeMiddleJumpPoint).Should().BeTrue(); jumpPoints[2].Should().Be(targetPosition); jumpPointsFromSpatialAstar.Count.Should().Be(3); jumpPointsFromSpatialAstar[0].Should().Be(startPosition); (jumpPointsFromSpatialAstar[1] == expectedMiddleJumpPoint || jumpPointsFromSpatialAstar[1] == expectedAlternativeMiddleJumpPoint).Should().BeTrue(); jumpPointsFromSpatialAstar[2].Should().Be(targetPosition); }
public void LoadTest_PathfindingPerformanceAndMemoryOverhead() { int xSize = 500; int ySize = 500; var density = TestGridInfoProvider.GridDensity.Medium; bool hasWalls = true; int rngSeed = 333; int trailsCount = 100; var gip = new TestGridInfoProvider(xSize, ySize, density, hasWalls, rngSeed); var rng = new RandomNumberGenerator(rngSeed); IRasterLineCreator bresenham = new BresenhamLineCreator(); var pathfinder = new Pathfinder(gip, new NaturalLineCalculator(bresenham), bresenham); var stopwatch = new Stopwatch(); var trailsToTest = new Dictionary <Position, Position>(); for (int i = 0; i < trailsCount; i++) { Position first = GetRandomWalkablePosition(rng, gip); Position second = GetRandomWalkablePosition(rng, gip); trailsToTest[first] = second; } Func <Position, Position, PathfindingResult>[] findersToTest = { pathfinder.FindJumpPointsWithJps, pathfinder.FindJumpPointsWithSpatialAstar, }; MemoryCheckPoint lastCheckPoint = new MemoryCheckPoint(); // = dotMemory.Check(); if (GC.TryStartNoGCRegion(240111000)) { lastCheckPoint = RunPathfindingAndPrintResults(xSize, ySize, density, hasWalls, trailsCount, rngSeed, findersToTest, stopwatch, trailsToTest, lastCheckPoint); if (GCSettings.LatencyMode == GCLatencyMode.NoGCRegion) { GC.EndNoGCRegion(); } } }
public void ResolveNextStep_NavigationDataIsCorrupted_RecalculationIsUsed(NavigationData inputNavigationData) { IPathfinder pathfinder = Mock.Of <IPathfinder>(); IGridInfoProvider gridInfoProvider = Mock.Of <IGridInfoProvider>(p => p.IsWalkable(It.IsAny <Position>()) == true && p.IsWalkable(new Position(2, 2)) == false && p.IsWalkable(new Position(3, 2)) == false // two walls, so that no recalculated nodes are skipped ); var bresenham = new BresenhamLineCreator(); var navigatorMockReal = new Mock <Navigator>(pathfinder, gridInfoProvider, new NaturalLineCalculator(bresenham), bresenham, Mock.Of <IUiFacade>()) { CallBase = true }; Position currentPosition = new Position(1, 1); List <Position> recalculatedRemainingNodes = new[] { new Position(3, 1), new Position(4, 3) }.ToList(); var recalculatedNavigationData = new NavigationData { Destination = recalculatedRemainingNodes[1], RemainingNodes = recalculatedRemainingNodes, RemainingStepsInCurrentSegment = new Stack <Position>(), LastStep = currentPosition }; navigatorMockReal.Setup(n => n.GetNavigationData(currentPosition, recalculatedRemainingNodes[1])) .Returns(recalculatedNavigationData); Position nextStep; NavigationResult result = navigatorMockReal.Object.ResolveNextStep(inputNavigationData, currentPosition, out nextStep); result.Should().Be(NavigationResult.InProgressWithRecalculation); var expectedNavigationData = new NavigationData { Destination = recalculatedRemainingNodes[1], RemainingNodes = recalculatedRemainingNodes, RemainingStepsInCurrentSegment = new Stack <Position>(new[] { recalculatedRemainingNodes[0] }), LastStep = new Position(2, 1) }; inputNavigationData.Should().BeEquivalentTo(expectedNavigationData); nextStep.Should().Be(new Position(2, 1)); }
public void GetJumpPoints_IntegrationTest_ThereIsNoPathToTarget_ReturnsNull() { /* Illustration: * ........ * .###.... * .#s#t... * .###....*/ Position minPositionInUnityGrid = new Position(-10, -10); int unityGridXSize = 20; int unityGridYSize = 20; var startPosition = new Position(0, 0); var targetPosition = new Position(2, 0); Func <Position, bool> isWalkable = position => { if ( // surrounding start point with walls position == new Position(-1, 1) || position == new Position(0, 1) || position == new Position(1, 1) || position == new Position(-1, 0) || position == new Position(1, 0) || position == new Position(-1, -1) || position == new Position(0, -1) || position == new Position(1, -1)) { return(false); } return(true); }; var gridInfoProvider = Mock.Of <IGridInfoProvider>( f => f.IsWalkable(It.Is <Position>(v => isWalkable(v))) == true && f.IsWalkable(It.Is <Position>(v => !isWalkable(v))) == false && f.MinPosition == minPositionInUnityGrid && f.XSize == unityGridXSize && f.YSize == unityGridYSize && f.Bounds == new BoundsInt(0, 0, 0, unityGridXSize, unityGridYSize, 1)); IRasterLineCreator bresenham = new BresenhamLineCreator(); var pathfinder = new Pathfinder(gridInfoProvider, new NaturalLineCalculator(bresenham), bresenham); IList <Position> jumpPoints = pathfinder.FindJumpPointsWithJps(startPosition, targetPosition).Positions; IList <Position> jumpPointsFromSpatialAstar = pathfinder.FindJumpPointsWithSpatialAstar(startPosition, targetPosition).Positions; jumpPoints.Should().BeNull(); jumpPointsFromSpatialAstar.Should().BeNull(); }
public void ResolveNextStep_NextStepIsUnwalkableAndRecalculatingFails_ReturnsUnreachable(bool nextStepIsDestination) { var currentPosition = new Position(2, 2); var destination = new Position(4, 2); Position plannedNextStep = nextStepIsDestination ? destination : new Position(3, 2); IPathfinder pathfinder = Mock.Of <IPathfinder>(); var bresenham = new BresenhamLineCreator(); IGridInfoProvider gridInfoProvider = Mock.Of <IGridInfoProvider>(p => p.IsWalkable(plannedNextStep) == false); var navigator = new Navigator(pathfinder, gridInfoProvider, new NaturalLineCalculator(bresenham), bresenham, Mock.Of <IUiFacade>()); var navigationData = new NavigationData { Destination = destination, RemainingStepsInCurrentSegment = new Stack <Position>(new[] { plannedNextStep, currentPosition }) }; Position nextStep; NavigationResult result = navigator.ResolveNextStep(navigationData, currentPosition, out nextStep); result.Should().Be(NavigationResult.Unreachable); }
public void GetJumpPoints_IntegrationTest_AllGridIsWalkable_ReturnsCorrectPath(int xOffset, int yOffset) { /* Illustration: * ........ * ...jt... * ..sj.... * ........*/ Position minPositionInUnityGrid = new Position(-10, -10); int unityGridXSize = 20; int unityGridYSize = 20; Position offset = new Position(xOffset, yOffset); var startPosition = new Position(0, 0) + offset; var targetPosition = new Position(2, 1) + offset; var expectedMiddleJumpPoint = new Position(1, 1) + offset; var expectedAlternativeMiddleJumpPoint = new Position(1, 0) + offset; var gridInfoProvider = Mock.Of <IGridInfoProvider>( f => f.IsWalkable(It.IsAny <Position>()) == true && f.MinPosition == minPositionInUnityGrid && f.XSize == unityGridXSize && f.YSize == unityGridYSize && f.Bounds == new BoundsInt(xOffset, yOffset, 0, unityGridXSize, unityGridYSize, 1)); IRasterLineCreator bresenham = new BresenhamLineCreator(); var pathfinder = new Pathfinder(gridInfoProvider, new NaturalLineCalculator(bresenham), bresenham); IList <Position> jumpPoints = pathfinder.FindJumpPointsWithJps(startPosition, targetPosition).Positions; IList <Position> jumpPointsFromSpatialAstar = pathfinder.FindJumpPointsWithSpatialAstar(startPosition, targetPosition).Positions; jumpPoints.Count.Should().Be(3); jumpPoints[0].Should().Be(startPosition); (jumpPoints[1] == expectedMiddleJumpPoint || jumpPoints[1] == expectedAlternativeMiddleJumpPoint).Should().BeTrue(); jumpPoints[2].Should().Be(targetPosition); jumpPointsFromSpatialAstar.Count.Should().Be(3); jumpPointsFromSpatialAstar[0].Should().Be(startPosition); (jumpPointsFromSpatialAstar[1] == expectedMiddleJumpPoint || jumpPointsFromSpatialAstar[1] == expectedAlternativeMiddleJumpPoint).Should().BeTrue(); jumpPointsFromSpatialAstar[2].Should().Be(targetPosition); }
// ..jn.. legend: s=start, j=jump point from pathfinder, t=target, #=wall, // .j##t. n=jump point and at the same time a natural replacement for other jump point the one at (2,2) // s..#.. public void GetNavigationData_PathfinderIsUsed_RemainingNodesAreCorrectWithNaturalFirstJumpPoint() { var start = new Position(0, 0); var target = new Position(4, 1); var pathfinderMock = new Mock <IPathfinder>(); IGridInfoProvider gridInfoProvider = Mock.Of <IGridInfoProvider>(gip => gip.IsWalkable(It.IsAny <Position>()) == true && gip.IsWalkable(new Position(2, 1)) == false && gip.IsWalkable(new Position(3, 1)) == false && gip.IsWalkable(new Position(3, 0)) == false); var jumpPointsFromPathfinder = new List <Position> { new Position(0, 0), new Position(1, 1), // should be pruned because it's redundant new Position(2, 2), // when actor start navigating towards this node, it will be changed to it's natural jump point (3,2) and // next jump point will be pruned because it's the same. new Position(3, 2), new Position(4, 1) }; pathfinderMock.Setup(p => p.FindJumpPointsWithJps(It.IsAny <Position>(), It.IsAny <Position>(), It.IsAny <JpsMode>())) .Returns(new PathfindingResult(jumpPointsFromPathfinder)); var bresenham = new BresenhamLineCreator(); var navigator = new Navigator(pathfinderMock.Object, gridInfoProvider, new NaturalLineCalculator(bresenham), bresenham, Mock.Of <IUiFacade>()); NavigationData result = navigator.GetNavigationData(start, target); pathfinderMock.Verify(p => p.FindJumpPointsWithJps(It.IsAny <Position>(), It.IsAny <Position>(), It.IsAny <JpsMode>()), Times.Once); result.Destination.Should().Be(target); IList <Position> expectedNodes = new List <Position>(new[] { new Position(2, 2), new Position(3, 2), new Position(4, 1) }); result.RemainingNodes.Should().BeEquivalentTo(expectedNodes, options => options.WithStrictOrderingFor(position => position)); result.RemainingStepsInCurrentSegment.Should().BeEmpty(); }