private static void PollingExample() { Console.WriteLine(nameof(PollingExample)); //Setup the nodegrid and pathfinder. var pathfindaxManager = new PathfindaxManager(); var factory = new DefinitionNodeGridFactory(); var nodeGrid = factory.GeneratePreFilledArray(GenerateNodeGridConnections.All, 3, 3); var nodeNetwork = new DefinitionNodeGrid(nodeGrid, new Vector2(1, 1)); var pathfinder = pathfindaxManager.CreateAstarPathfinder(nodeNetwork, new ManhattanDistance()); //Request a path. var pathRequest = pathfinder.RequestPath(nodeNetwork.NodeGrid.ToIndex(0, 0), nodeNetwork.NodeGrid.ToIndex(2, 0)); Console.WriteLine($"Solving path from {pathRequest.PathStart} to {pathRequest.PathEnd}..."); //Poll the status to check when the pathfinder is finished. while (pathRequest.Status == PathRequestStatus.Solving) { } switch (pathRequest.Status) { case PathRequestStatus.Solved: Console.WriteLine($"Solved path! {pathRequest.CompletedPath}"); break; case PathRequestStatus.NoPathFound: Console.WriteLine("Could not find a path"); break; } Console.WriteLine($"{nameof(PollingExample)} completed. Press any key to continue with the next example."); Console.ReadKey(); }
public void FindPath_InitializedNodegrid_ValuesPotentialFieldAreCorrect() { var potentialFieldAlgorithm = new PotentialFieldAlgorithm(0); var definitionNodeGrid = new DefinitionNodeGrid(GenerateNodeGridConnections.All, 3, 3, new Vector2(1, 1)); var start = definitionNodeGrid.NodeGrid[0, 0]; var end = definitionNodeGrid.NodeGrid[2, 2]; var pathfindingNetwork = new DijkstraNodeGrid(definitionNodeGrid); var pathRequest = new PathRequest <IPath>(start, end); var potentialField = potentialFieldAlgorithm.FindPath(pathfindingNetwork, pathRequest, out var _); const float tolerance = 0.001f; Assert.AreEqual(Math.Abs(Math.Abs(potentialField.PotentialArray[0, 0]) - 4f) < tolerance, true); Assert.AreEqual(Math.Abs(Math.Abs(potentialField.PotentialArray[1, 0]) - 3f) < tolerance, true); Assert.AreEqual(Math.Abs(Math.Abs(potentialField.PotentialArray[2, 0]) - 2f) < tolerance, true); Assert.AreEqual(Math.Abs(Math.Abs(potentialField.PotentialArray[0, 1]) - 3f) < tolerance, true); Assert.AreEqual(Math.Abs(Math.Abs(potentialField.PotentialArray[1, 1]) - 2f) < tolerance, true); Assert.AreEqual(Math.Abs(Math.Abs(potentialField.PotentialArray[2, 1]) - 1f) < tolerance, true); Assert.AreEqual(Math.Abs(Math.Abs(potentialField.PotentialArray[0, 2]) - 2f) < tolerance, true); Assert.AreEqual(Math.Abs(Math.Abs(potentialField.PotentialArray[1, 2]) - 1f) < tolerance, true); Assert.AreEqual(Math.Abs(Math.Abs(potentialField.PotentialArray[2, 2]) - 0f) < tolerance, true); }
private static void CallbackExample() { Console.WriteLine(nameof(CallbackExample)); //Setup the nodegrid and pathfinder. var pathfindaxManager = new PathfindaxManager(); var factory = new DefinitionNodeGridFactory(); var nodeGrid = factory.GeneratePreFilledArray(GenerateNodeGridConnections.All, 3, 3); var nodeNetwork = new DefinitionNodeGrid(nodeGrid, new Vector2(1, 1)); var pathfinder = pathfindaxManager.CreateAstarPathfinder(nodeNetwork, new ManhattanDistance()); //Request a path. var pathRequest = pathfinder.RequestPath(nodeNetwork.NodeGrid.ToIndex(0, 0), nodeNetwork.NodeGrid.ToIndex(2, 0)); Console.WriteLine($"Solving path from {pathRequest.PathStart} to {pathRequest.PathEnd}..."); //Add a callback to the request that will be called then the pathfinder is done. var callbackCalled = false; pathRequest.AddCallback(request => { Console.WriteLine($"Solved path! {request.CompletedPath}"); callbackCalled = true; }); //Wait till callback is called. while (!callbackCalled) { } Console.WriteLine($"{nameof(CallbackExample)} completed. Press any key to continue with the next example."); Console.ReadKey(); }
private static void CallbackExample() { Console.WriteLine(nameof(CallbackExample)); //Setup the nodegrid and pathfinder. var pathfindaxManager = new PathfindaxManager(); var nodeNetwork = new DefinitionNodeGrid(GenerateNodeGridConnections.All, 3, 3, new Vector2(1, 1)); var pathfinder = pathfindaxManager.CreateAstarPathfinder(nodeNetwork); //Request a path. var pathRequest = pathfinder.RequestPath(nodeNetwork.NodeGrid[0, 0], nodeNetwork.NodeGrid[2, 0]); Console.WriteLine($"Solving path from {pathRequest.PathStart.Position} to {pathRequest.PathEnd.Position}..."); //Add a callback to the request that will be called then the pathfinder is done. var callbackCalled = false; pathRequest.AddCallback(request => { Console.WriteLine($"Solved path! {request.CompletedPath}"); callbackCalled = true; }); //Start calling update on the manager. Update will call the callbacks of any completed paths. Note that the callback is called from the thread that calls update. //Normally when using pathfindax in a game engine you would wire this up in your game loop. while (!callbackCalled) { pathfindaxManager.Update(1f); } Console.WriteLine($"{nameof(CallbackExample)} completed. Press any key to continue with the next example."); Console.ReadKey(); }
public void FindPath_InitializedNodegrid_PathIsOptimal(DefinitionNodeGrid definitionNodeGrid, Point2 gridStart, Point2 gridEnd, float expectedPathLength) { var path = RunAstar(definitionNodeGrid, gridStart, gridEnd); Assert.NotNull(path); var pathLength = path.GetPathLength(); Assert.Equal(expectedPathLength, pathLength, 1); }
public void FindPath_InitializedNodegrid_PathIsOptimal(DefinitionNodeGrid definitionNodeGrid, Point2 gridStart, Point2 gridEnd, float expectedPathLength) { var path = RunDijkstra(definitionNodeGrid, gridStart, gridEnd, out var succes); Assert.AreEqual(true, succes); var pathLength = path.GetPathLength(); Assert.AreEqual(expectedPathLength, pathLength, 0.1f); }
private NodePath RunAstar(DefinitionNodeGrid definitionNodeGrid, Point2 gridStart, Point2 gridEnd, out bool succes) { var aStarAlgorithm = new AStarAlgorithm(definitionNodeGrid.NodeCount, new EuclideanDistance()); var start = definitionNodeGrid.NodeGrid.ToIndex(gridStart.X, gridStart.Y); var end = definitionNodeGrid.NodeGrid.ToIndex(gridEnd.X, gridEnd.Y); var pathfindingNetwork = new AstarNodeNetwork(definitionNodeGrid, new BrushfireClearanceGenerator(definitionNodeGrid, 5)); var pathRequest = PathRequest.Create(Substitute.For <IPathfinder <IPath> >(), start, end, PathfindaxCollisionCategory.Cat1); return(aStarAlgorithm.FindPath(pathfindingNetwork, pathRequest, out succes)); }
public void Setup() { var factory = new DefinitionNodeGridFactory(); var nodeGrid = factory.GeneratePreFilledArray(GenerateNodeGridConnections.All, 320, 200); _definitionNodeGrid = new DefinitionNodeGrid(nodeGrid, new Vector2(1, 1)); _dijkstraNodeGrid = new DijkstraNodeGrid(_definitionNodeGrid, 1); _algorithm = new DijkstraAlgorithm(_definitionNodeGrid.NodeCount); _pathRequest = PathRequest.Create(Substitute.For <IPathfinder <NodePath> >(), _definitionNodeGrid.NodeGrid.ToIndex(0, 0), _definitionNodeGrid.NodeGrid.ToIndex(319, 199)); _nodeNetwork = _dijkstraNodeGrid.GetCollisionLayerNetwork(_pathRequest.CollisionCategory); }
private PotentialField RunPotentialField(DefinitionNodeGrid definitionNodeGrid, Point2 gridStart, Point2 gridEnd, out bool succes) { var potentialFieldAlgorithm = new PotentialFieldAlgorithm(0, definitionNodeGrid.NodeCount); var start = definitionNodeGrid.NodeGrid.ToIndex(gridStart.X, gridStart.Y); var end = definitionNodeGrid.NodeGrid.ToIndex(gridEnd.X, gridEnd.Y); var pathfindingNetwork = new DijkstraNodeGrid(definitionNodeGrid, 5); var pathRequest = PathRequest.Create(Substitute.For <IPathfinder <IPath> >(), start, end, PathfindaxCollisionCategory.Cat1); return(potentialFieldAlgorithm.FindPath(pathfindingNetwork, pathRequest, out succes)); }
private WaypointPath RunDijkstra(DefinitionNodeGrid definitionNodeGrid, Point2 gridStart, Point2 gridEnd) { var dijkstraAlgorithm = new DijkstraAlgorithm(definitionNodeGrid.NodeCount); var start = definitionNodeGrid.NodeGrid.ToIndex(gridStart.X, gridStart.Y); var end = definitionNodeGrid.NodeGrid.ToIndex(gridEnd.X, gridEnd.Y); var pathfindingNetwork = new DijkstraNodeGrid(definitionNodeGrid, 5); var pathRequest = PathRequest.Create(Substitute.For <IPathfinder <IPath> >(), start, end, PathfindaxCollisionCategory.Cat1); var path = dijkstraAlgorithm.FindPath(pathfindingNetwork, pathRequest); return(path); }
public void Setup() { var factory = new DefinitionNodeGridFactory(); var nodeGrid = factory.GeneratePreFilledArray(GenerateNodeGridConnections.All, 320, 200); _definitionNodeGrid = new DefinitionNodeGrid(nodeGrid, new Vector2(1, 1)); _astarNodeNetwork = new AstarNodeNetwork(_definitionNodeGrid, new BrushfireClearanceGenerator(_definitionNodeGrid, 1)); _algorithm = new AStarAlgorithm(_definitionNodeGrid.NodeCount, new ManhattanDistance()); _longPathRequest = PathRequest.Create(Substitute.For <IPathfinder <IPath> >(), _definitionNodeGrid.NodeGrid.ToIndex(0, 0), _definitionNodeGrid.NodeGrid.ToIndex(319, 199)); _shortPathRequest = PathRequest.Create(Substitute.For <IPathfinder <IPath> >(), _definitionNodeGrid.NodeGrid.ToIndex(0, 0), _definitionNodeGrid.NodeGrid.ToIndex(20, 20)); _veryShortPathRequest = PathRequest.Create(Substitute.For <IPathfinder <IPath> >(), _definitionNodeGrid.NodeGrid.ToIndex(0, 0), _definitionNodeGrid.NodeGrid.ToIndex(1, 0)); _zeroLengthPathRequest = PathRequest.Create(Substitute.For <IPathfinder <IPath> >(), _definitionNodeGrid.NodeGrid.ToIndex(0, 0), _definitionNodeGrid.NodeGrid.ToIndex(0, 0)); }
public void FindPath_InitializedNodegrid_PathLengthIsNot0(DefinitionNodeGrid definitionNodeGrid, int x1, int y1, int x2, int y2) { var aStarAlgorithm = new AStarAlgorithm(); var start = definitionNodeGrid.NodeGrid[x1, y1]; var end = definitionNodeGrid.NodeGrid[x1, y1]; var pathfindingNetwork = new AstarNodeNetwork(definitionNodeGrid, new GridClearanceGenerator(definitionNodeGrid, 5)); var pathRequest = new PathRequest <IPath>(start, end); var path = aStarAlgorithm.FindPath(pathfindingNetwork, pathRequest, out var _); Assert.AreEqual(path.Path.Length > 0, true); }
public void CalculateGridNodeClearances_FilledNodeGrid_Passes() { const int width = 4; const int height = 4; var sourceNodeGrid = new DefinitionNodeGrid(GenerateNodeGridConnections.All, width, height, new Vector2(1, 1)); var astarNodeNetwork = new AstarNodeNetwork(sourceNodeGrid, new GridClearanceGenerator(sourceNodeGrid, 5)); var sourceNodeNetworkCat1 = new Array2D <AstarNode>(astarNodeNetwork.GetCollisionLayerNetwork(PathfindaxCollisionCategory.Cat1), width, height); Assert.AreEqual(4, sourceNodeNetworkCat1[0, 0].Clearance); Assert.AreEqual(3, sourceNodeNetworkCat1[1, 0].Clearance); Assert.AreEqual(2, sourceNodeNetworkCat1[2, 0].Clearance); Assert.AreEqual(1, sourceNodeNetworkCat1[3, 0].Clearance); Assert.AreEqual(3, sourceNodeNetworkCat1[0, 1].Clearance); Assert.AreEqual(3, sourceNodeNetworkCat1[1, 1].Clearance); Assert.AreEqual(2, sourceNodeNetworkCat1[2, 1].Clearance); Assert.AreEqual(1, sourceNodeNetworkCat1[3, 1].Clearance); }
private static void AsyncExample() { Console.WriteLine(nameof(AsyncExample)); //Setup the nodegrid and pathfinder. var pathfindaxManager = new PathfindaxManager(); var factory = new DefinitionNodeGridFactory(); var nodeGrid = factory.GeneratePreFilledArray(GenerateNodeGridConnections.All, 3, 3); var definitionNodeGrid = new DefinitionNodeGrid(nodeGrid, new Vector2(1, 1)); var pathfinder = pathfindaxManager.CreateAstarPathfinder(definitionNodeGrid, new ManhattanDistance()); var exampleGameObject = new ExampleAsyncGameObject(pathfinder); //Wait till callback is called. while (!exampleGameObject.CallBackCalled) { exampleGameObject.Update(); } Console.ReadKey(); }
public IDefinitionNodeGrid GenerateGrid2D() { if (_definitionNodeGrid == null) { var nodeGrid = new DefinitionNodeGrid(GenerateNodeGridConnections.All, 16, 16, new Vector2(32, 32)); /*definitionNodeGrid.PotentialArray[5, 4].CollisionCategory = PathfindaxCollisionCategory.Cat1; * definitionNodeGrid.PotentialArray[5, 5].CollisionCategory = PathfindaxCollisionCategory.Cat1; * definitionNodeGrid.PotentialArray[5, 6].CollisionCategory = PathfindaxCollisionCategory.Cat1; * definitionNodeGrid.PotentialArray[5, 7].CollisionCategory = PathfindaxCollisionCategory.Cat1; * definitionNodeGrid.PotentialArray[5, 8].CollisionCategory = PathfindaxCollisionCategory.Cat1; * * definitionNodeGrid.PotentialArray[5, 10].CollisionCategory = PathfindaxCollisionCategory.Cat1; * definitionNodeGrid.PotentialArray[6, 10].CollisionCategory = PathfindaxCollisionCategory.Cat1; * definitionNodeGrid.PotentialArray[7, 10].CollisionCategory = PathfindaxCollisionCategory.Cat1; * definitionNodeGrid.PotentialArray[8, 10].CollisionCategory = PathfindaxCollisionCategory.Cat1; * definitionNodeGrid.PotentialArray[9, 10].CollisionCategory = PathfindaxCollisionCategory.Cat1;*/ _definitionNodeGrid = nodeGrid; } return(_definitionNodeGrid); }
private static TestCaseData GeneratePathTestCase(int width, int height, Point2 start, Point2 end, Point2[] blockedNodes = null) { var factory = new DefinitionNodeGridFactory(); var collisionMask = new NodeGridCollisionMask(PathfindaxCollisionCategory.Cat1, width, height); if (blockedNodes != null) { foreach (var blockedNode in blockedNodes) { collisionMask.Layers[0].CollisionDirections[blockedNode.X, blockedNode.Y] = CollisionDirection.Solid; } } var nodeGrid = factory.GeneratePreFilledArray(GenerateNodeGridConnections.All, collisionMask, true); var grid = new DefinitionNodeGrid(nodeGrid, new Vector2(1, 1)); var description = blockedNodes != null ? $"Path from {start} to {end} on a {width} by {height} grid with blocked nodes {string.Join(", ", blockedNodes)}" : $"Path from {start} to {end} on a {width} by {height} grid"; return(new TestCaseData(grid, start, end).SetName(description)); }
public IDefinitionNodeGrid GenerateGrid2D() { if (_definitionNodeGrid == null) { var factory = new DefinitionNodeGridFactory(); var nodeGrid = factory.GeneratePreFilledArray(GenerateNodeGridConnections.All, 320, 200); var definitionNodeGrid = new DefinitionNodeGrid(nodeGrid, new Vector2(32, 32)); /*definitionNodeGrid.PotentialArray[5, 4].CollisionCategory = PathfindaxCollisionCategory.Cat1; * definitionNodeGrid.PotentialArray[5, 5].CollisionCategory = PathfindaxCollisionCategory.Cat1; * definitionNodeGrid.PotentialArray[5, 6].CollisionCategory = PathfindaxCollisionCategory.Cat1; * definitionNodeGrid.PotentialArray[5, 7].CollisionCategory = PathfindaxCollisionCategory.Cat1; * definitionNodeGrid.PotentialArray[5, 8].CollisionCategory = PathfindaxCollisionCategory.Cat1; * * definitionNodeGrid.PotentialArray[5, 10].CollisionCategory = PathfindaxCollisionCategory.Cat1; * definitionNodeGrid.PotentialArray[6, 10].CollisionCategory = PathfindaxCollisionCategory.Cat1; * definitionNodeGrid.PotentialArray[7, 10].CollisionCategory = PathfindaxCollisionCategory.Cat1; * definitionNodeGrid.PotentialArray[8, 10].CollisionCategory = PathfindaxCollisionCategory.Cat1; * definitionNodeGrid.PotentialArray[9, 10].CollisionCategory = PathfindaxCollisionCategory.Cat1;*/ _definitionNodeGrid = definitionNodeGrid; } return(_definitionNodeGrid); }
/// <summary> /// Calculates the <see cref="NodeConnection"/>s for the <paramref name="definitionNode"/> /// </summary> /// <param name="tilemapColliderWithBodies"></param> /// <param name="definitionNode"></param> /// <param name="definitionNodeGrid"></param> public void CalculateGridNodeCollision(TilemapColliderWithBody[] tilemapColliderWithBodies, DefinitionNode definitionNode, DefinitionNodeGrid definitionNodeGrid) { var nodeGridCoordinates = new Point2((int)definitionNode.Position.X, (int)definitionNode.Position.Y); CalculateNodeCollisionCategories(nodeGridCoordinates.X, nodeGridCoordinates.Y, tilemapColliderWithBodies); if (nodeGridCoordinates.X == 0 || nodeGridCoordinates.Y == 0 || nodeGridCoordinates.X == definitionNodeGrid.NodeGrid.Width - 1 || nodeGridCoordinates.Y == definitionNodeGrid.NodeGrid.Height - 1) { for (var index = 1; index < _nodeCollisions.Length; index++) { var collisionCategory = _nodeCollisions[index]; if (collisionCategory.X >= 0 && collisionCategory.Y >= 0 && collisionCategory.X < definitionNodeGrid.NodeGrid.Width && collisionCategory.Y < definitionNodeGrid.NodeGrid.Height) { //TODO provide option to exclude diagonal neighbours. var toNode = definitionNodeGrid.NodeGrid[collisionCategory.X, collisionCategory.Y]; definitionNode.Connections.Add(new NodeConnection(toNode.Index, collisionCategory.PathfindaxCollisionCategory | _nodeCollisions[0].PathfindaxCollisionCategory)); } } } else { for (var index = 1; index < _nodeCollisions.Length; index++) { var collisionCategory = _nodeCollisions[index]; //TODO provide option to exclude diagonal neighbours. var toNode = definitionNodeGrid.NodeGrid[collisionCategory.X, collisionCategory.Y]; definitionNode.Connections.Add(new NodeConnection(toNode.Index, collisionCategory.PathfindaxCollisionCategory | _nodeCollisions[0].PathfindaxCollisionCategory)); } } }
public void FindPath_InitializedNodegrid_NoPathFound(DefinitionNodeGrid definitionNodeGrid, Point2 gridStart, Point2 gridEnd) { var path = RunAstar(definitionNodeGrid, gridStart, gridEnd); Assert.Null(path); }
public static IPathfinder <DefinitionNodeGrid, DijkstraNodeGrid, PotentialField> CreatePotentialFieldPathfinder(this IPathfindaxManager pathfindaxManager, DefinitionNodeGrid nodeGrid, int maxClearance, int maxCachedFlowFields, int amountOfThreads = 1) { var pathfinder = pathfindaxManager.CreatePathfinder(nodeGrid, new PotentialFieldAlgorithm(maxCachedFlowFields, nodeGrid.NodeCount), (definitionNodeGrid, algorithm) => { var dijkstraNodeGrid = new DijkstraNodeGrid(definitionNodeGrid, maxClearance); return(CreateRequestProcesser(dijkstraNodeGrid, algorithm)); }, amountOfThreads); pathfinder.Start(); return(pathfinder); }
public void FindPath_InitializedNodegrid_NoPathFound(DefinitionNodeGrid definitionNodeGrid, Point2 gridStart, Point2 gridEnd) { var potentialField = RunPotentialField(definitionNodeGrid, gridStart, gridEnd, out var succes); Assert.AreEqual(false, succes); }
public static IPathfinder <DefinitionNodeGrid, DijkstraNodeGrid, PotentialField> CreatePotentialFieldPathfinder(this IPathfindaxManager pathfindaxManager, DefinitionNodeGrid nodeGrid, int maxClearance, int maxCachedFlowFields, int amountOfThreads = 1) { var pathfinder = pathfindaxManager.CreatePathfinder(nodeGrid, new PotentialFieldAlgorithm(nodeGrid.NodeCount), (definitionNodeGrid, algorithm, cache) => { var dijkstraNodeGrid = new DijkstraNodeGrid(definitionNodeGrid, maxClearance); return(CreateRequestProcesser(dijkstraNodeGrid, algorithm, cache)); }, maxCachedFlowFields > 0 ? new ConcurrentCache <IPathRequest, PotentialField>(maxCachedFlowFields, new SingleSourcePathRequestComparer()) : null, amountOfThreads); pathfinder.Start(); return(pathfinder); }
public void FindPath_InitializedNodegrid_PathFound(DefinitionNodeGrid definitionNodeGrid, Point2 gridStart, Point2 gridEnd) { var path = RunDijkstra(definitionNodeGrid, gridStart, gridEnd, out var succes); Assert.AreEqual(true, succes); }
public void FindPath_InitializedNodegrid_NoPathFound(DefinitionNodeGrid definitionNodeGrid, Point2 gridStart, Point2 gridEnd) { var runFlowField = RunFlowField(definitionNodeGrid, gridStart, gridEnd, out var succes); Assert.False(succes); }