/// <summary> /// Adds a node to the graph /// </summary> /// <param name="node">The node to be added</param> public void AddNavNode(NavNode node) { Nodes.Add(node); //set the bounds of the grid if (node.Indexes.Item1 > maxX) { maxX = node.Indexes.Item1; } if (node.Indexes.Item2 > maxY) { maxY = node.Indexes.Item2; } }
/// <summary> /// Uses a modification of Dijkstra Shortest Path Algorithm to find /// the farthest path away from the target node, relative to the /// "from" node /// </summary> /// <param name="from">The starting node</param> /// <param name="target">The target node to run way from</param> /// /// <param name="exclude">Nodes of the types in the list won't be considered</param> /// <returns>A list containing the shortest path between the given nodes</returns> public List <NavNode> FarthestPath(NavNode from, NavNode target, List <NodeType> exclude = null) { List <NavNode> result = new List <NavNode>(); //limits the path size for performance const int maxSize = 10; int greatestDistance = 0; //mark all nodes as unvisited //set the distance to "- infinity" //and clear the path foreach (var node in Nodes) { node.Visited = false; node.Distance = int.MinValue; node.PreviousNodeInPath = null; } //set the from node distance to 0 from.Distance = 0; //the current node, set it to "from" NavNode currentNode = from; //number of nodes yet to be visited - target int nodesToBeVisited = Nodes.Count - 1; //iterate trhough the nodes until the //"to" node is visited while (nodesToBeVisited > 0 || greatestDistance < maxSize) { //mark current node as visited //and remove a node to be visited currentNode.Visited = true; nodesToBeVisited--; //calc the distance to the neighbors foreach (var neighbor in currentNode.Neighbors) { //if the neighbor is already visited, ignore it if (neighbor == null || neighbor.Visited) { continue; } //ignore target if (neighbor == target) { continue; } //ignore neighbor if it matches any exluded type if (exclude != null && exclude.Contains(neighbor.NodeType)) { continue; } //cumulative distance from the starting node int distance = currentNode.Distance + 1; if (distance > neighbor.Distance) { neighbor.Distance = distance; neighbor.PreviousNodeInPath = currentNode; if (distance > greatestDistance) { greatestDistance = distance; } } } //change the current node to the non-visited //node with the greatest distance currentNode = Nodes.Where(n => !n.Visited && n != target).OrderByDescending(n => n.Distance).FirstOrDefault(); } //fill the result starting from the node with greatest distance currentNode = Nodes.Where(n => n != target).OrderByDescending(n => n.Distance).FirstOrDefault(); while (greatestDistance > 0) { greatestDistance--; result.Add(currentNode.PreviousNodeInPath); currentNode = currentNode.PreviousNodeInPath; } result.Reverse(); return(result.ToList()); }
/// <summary> /// Uses Dijkstra Shortest Path Algorithm to find the shortest path /// between the given nodes, using adjacency matrix representation /// and fixing the distance between neighbor nodes as 1 /// </summary> /// <param name="from">The starting node</param> /// <param name="to">The target node</param> /// /// <param name="exclude">Nodes of the types in the list won't be considered</param> /// <returns>A list containing the shortest path between the given nodes</returns> public List <NavNode> ShortestPath(NavNode from, NavNode to, List <NodeType> exclude = null) { List <NavNode> result = new List <NavNode>(); //mark all nodes as unvisited //set the distance to "infinity" //and clear the path foreach (var node in Nodes) { node.Visited = false; node.Distance = int.MaxValue; node.PreviousNodeInPath = null; } //set the from node distance to 0 from.Distance = 0; //the current node, set it to "from" NavNode currentNode = from; //iterate trhough the nodes until the //"to" node is visited while (!to.Visited) { //mark current node as visited //and remove a node to be visited currentNode.Visited = true; //calc the distance to the neighbors foreach (var neighbor in currentNode.Neighbors) { //if the neighbor is already visited, ignore it if (neighbor == null || neighbor.Visited) { continue; } //ignore neighbor if it matches any exluded type if (exclude != null && exclude.Contains(neighbor.NodeType)) { continue; } //cumulative distance from the starting node int distance = currentNode.Distance + 1; if (distance < neighbor.Distance) { neighbor.Distance = distance; neighbor.PreviousNodeInPath = currentNode; } } //change the current node to the non-visited //node with the shortest distance currentNode = Nodes.Where(n => !n.Visited).OrderBy(n => n.Distance).FirstOrDefault(); } //fill the result result.Add(to); currentNode = to; while (currentNode != from) { result.Add(currentNode.PreviousNodeInPath); currentNode = currentNode.PreviousNodeInPath; } result.Reverse(); return(result.ToList()); }