/// <summary> /// Walk backwards from TargetNode and set parents' IsPartOfTheSolution. /// </summary> private void SetSolution(CancellationToken cancellationToken) { Node node = grid.TargetNode; List <Node> solution = new List <Node>(); while (node != grid.StartingNode) { solution.Add(node); node = node.Parent; } solution.Reverse(); foreach (var n in solution) { if (cancellationToken.IsCancellationRequested) { ClearPath(); PathfindingFinished?.Invoke(this, null); return; } n.IsPartOfTheSolution = true; //n = n.Parent; Thread.Sleep(VisualizationTime * 2); } }
public async Task FindPathAsync(CancellationToken cancellationToken) { await Task.Factory.StartNew(() => { if (grid.Algorithm == null) { throw new NullReferenceException("Scenario grid does not have an assigned pathfinding algorithim!"); } while (true) { if (OpenNodes.Count == 1 && OpenNodes[0] == grid.StartingNode) { CurrentNode = OpenNodes[0]; } else { CurrentNode = GetNodeWithLowestFCost(OpenNodes); } Thread.Sleep(VisualizationTime); OpenNodes.Remove(CurrentNode); ClosedNodes.Add(CurrentNode); Thread.Sleep(VisualizationTime); if (CurrentNode == grid.TargetNode) { SetSolution(cancellationToken); PathfindingFinished?.Invoke(this, null); return; } neighbouringNodes = GetNeighbouringNodes(CurrentNode, allowDiagonals: AllowDiagonalMovement); foreach (Node n in neighbouringNodes) { if (cancellationToken.IsCancellationRequested) { ClearPath(); PathfindingFinished?.Invoke(this, null); return; } if (!n.IsTraversable || ClosedNodes.Contains(n)) { continue; } if (IsNewPathShorter(CurrentNode, n) || !OpenNodes.Contains(n)) { n.GCost = CurrentNode.GCost + GetDistance(CurrentNode, n); n.HCost = GetDistance(n, grid.TargetNode); n.Parent = CurrentNode; if (!OpenNodes.Contains(n)) { OpenNodes.Add(n); } } Thread.Sleep(VisualizationTime / 3); } } }); }