/// <summary> /// Find all the paths avalaible between map start point and destination point. /// </summary> /// <returns>A <see cref="Path{T}"/> array containing all the paths avalaible from start to destination.</returns> /// <exception cref="ArgumentNullException">No start or destination node are given in the map.</exception> public Path <T>[] FindAllPaths() { Node <T> startNode = null; // Start node from which begin the navigation Node <T> destinationNode = null; // Destination node to be reached Node <T> actualNode = null; // Actual visited node Path <T> foundPath = null; // Path found by a search List <Path <T> > resultPathList = new List <Path <T> >(); // List of paths found by all the search cycles SearchState searchResult = SearchState.Searching; // Flag used to let the function cycle OpenClosedNodeCollection <T> nodeCollection = null; // Collection containing the nodes that can be visited or must be ignored List <Node <T> > pathNodeList = null; // List of node that defines the path double foundPathCost = 0; // Cost of the found path // Get the start node from the node map startNode = this.NodeMap.GetStartNode(); // Get the destination node from the node map destinationNode = this.NodeMap.GetDestinationNode(); // Throw an exception if there are no starting or destination node if (startNode == null) { throw new ArgumentNullException(nameof(startNode)); } if (destinationNode == null) { throw new ArgumentNullException(nameof(destinationNode)); } // Initialize che collections pathNodeList = new List <Node <T> >(); nodeCollection = new OpenClosedNodeCollection <T>(); // Begin from the start node actualNode = startNode; // Begin the search do { searchResult = this.ComputeFindPath(destinationNode, ref actualNode, nodeCollection); // Create the path if destination as been reached if (searchResult == SearchState.Found) { // Destination reached, saving the search foundPathCost = actualNode.PathCost; // Pupulate the list. Starting node must be the first in the list while (actualNode != null) { pathNodeList.Insert(0, actualNode); actualNode = actualNode.Parent; } // Populate the found path foundPath = new Path <T>(pathNodeList, foundPathCost); // Add the found path the path list resultPathList.Add(foundPath); // Reset the search actualNode = startNode; searchResult = SearchState.Searching; } }while (searchResult == SearchState.Searching); // Sort all the paths and return them as array resultPathList.Sort(); return(resultPathList.ToArray()); }
/// <summary> /// Compute a pass to find the path. It must be cycled untill the result is <see cref="SearchState.Found"/>. /// </summary> /// <param name="destinationNode">Destination <see cref="Node{T}"/>.</param> /// <param name="actualNode">Actual visited <see cref="Node{T}"/>.</param> /// <param name="nodeCollection">Collection containing the nodes that can be visited or must be ignored.</param> /// <returns>The result of the path finding.</returns> private SearchState ComputeFindPath(Node <T> destinationNode, ref Node <T> actualNode, OpenClosedNodeCollection <T> nodeCollection) { SearchState searchResult = SearchState.Searching; // Flag used to let the function cycle Node <T>[] childNodes = null; // Array of child nodes Node <T> nearestNode = null; // Node nearest to the actual node // Destination reached, stopping the search if (actualNode.Equals(destinationNode)) { searchResult = SearchState.Found; return(searchResult); } // Get the child nodes childNodes = this.NodeMap.GetChildNodes(actualNode); // Adding actual node to the closed list nodeCollection.AddClosed(actualNode); // Analizing child nodes if (childNodes.Length > 0) { for (int i = 0; i < childNodes.Length; i++) { // Add child node the the open list nodeCollection.AddOpen(childNodes[i]); } // Getting the nearest node nearestNode = nodeCollection.GetNearestNode(); if (nearestNode != null) { actualNode = nearestNode; } else { // No open nodes, going backward actualNode = actualNode.Parent; // No path avalaible, stopping the search if (actualNode == null) { searchResult = SearchState.NotFound; } } } else { // No child nodes, going backward actualNode = actualNode.Parent; // No path avalaible, stopping the search if (actualNode == null) { searchResult = SearchState.NotFound; } } return(searchResult); }