示例#1
0
        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();
        }
示例#2
0
        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);
        }
示例#3
0
        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);
示例#4
0
        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();
        }
示例#5
0
        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();
        }
示例#6
0
        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);
        }
示例#7
0
        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();
        }
示例#8
0
        // .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();
        }
示例#9
0
        /// <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);
        }
示例#10
0
        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());
        }
示例#11
0
        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());
        }
示例#12
0
        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());
        }
示例#13
0
        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());
        }
示例#14
0
        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());
        }
示例#15
0
        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());
        }
示例#16
0
        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());
        }
示例#17
0
        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());
        }
示例#18
0
        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);
        }
示例#19
0
        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();
        }
示例#20
0
        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);
        }
示例#21
0
        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();
        }
示例#22
0
        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);
        }
示例#23
0
        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);
        }
示例#24
0
        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();
                }
            }
        }
示例#25
0
        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));
        }
示例#26
0
        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();
        }
示例#27
0
        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);
        }
示例#28
0
        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);
        }
示例#29
0
        // ..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();
        }