public PathParse(PathParse pp) { distance = pp.distance; currentSystemID = pp.currentSystemID; // Save the distance reference. distanceMap = pp.distanceMap; // Copy the current path. path = new List <int>(pp.path); }
/// <summary> /// Find the path from this system to destination system. /// </summary> /// <param name="destinationID">solarSystemID of destination system.</param> /// <param name="highSec">True if high sec path prefered.</param> /// <returns>The path or null if not found.</returns> public List <int> FindPath(int destinationID, bool highSec = false) { // Initialize the found path. PathParse pp = new PathParse() { // Get the distance map. distanceMap = GetDistanceMap(highSec) }; if (!pp.distanceMap.ContainsKey(destinationID)) { // Unreachable system! return(null); } pp.path = new List <int>(); if (destinationID == solarSystemID) { // We are already there! return(pp.path); } // Init path finding. pp.distance = pp.distanceMap[destinationID]; pp.currentSystemID = destinationID; // Add destination system. pp.path.Add(pp.currentSystemID); // Find the shortest path. pp = FindShortest(pp, highSec); // Check results. if (pp == null) { // No path found. if (highSec) { // Cannot find path with current restrictions, try none. return(FindPath(destinationID)); } return(null); } // Reverse the list so the first system begins the list. pp.path.Reverse(); return(pp.path); }
private PathParse FindShortest(PathParse pp, bool highSec) { // Find starting system. while (pp.distance > 0) { // Check that the system has jumps. if (!systemDestinations.ContainsKey(pp.currentSystemID)) { // Error, system not found. return(null); } // Get the distances for each jump. Dictionary <int, int> jumpDistances = new Dictionary <int, int>(); int lowestDistance = pp.distance; foreach (int destinationSystemID in systemDestinations[pp.currentSystemID]) { // Does the system exist in the map? if (pp.distanceMap.ContainsKey(destinationSystemID)) { int dist = pp.distanceMap[destinationSystemID]; jumpDistances[destinationSystemID] = dist; lowestDistance = Math.Min(lowestDistance, dist); } } // Set distance to lowest. pp.distance = lowestDistance; // Remove longer jumps. var longer = jumpDistances.Where(g => g.Value > lowestDistance).ToArray(); foreach (var dest in longer) { jumpDistances.Remove(dest.Key); } if (jumpDistances.Count == 0) { // Error, jumps not found. return(null); } else if (jumpDistances.Count == 1) { // Save this as currently shortest path. int dest = jumpDistances.ElementAt(0).Key; if (dest != pp.currentSystemID) { // Add next point in path. pp.currentSystemID = dest; if (pp.path.Contains(pp.currentSystemID)) { // We have somehow looped back on ourself. return(null); } pp.path.Add(pp.currentSystemID); } else { return(null); } } else { PathParse spp = null; // 2 or more systems of same distance but not necessarily equal paths. foreach (int dest in jumpDistances.Keys) { // Create a copy of the path. PathParse npp = new PathParse(pp) { // Add this point in path. currentSystemID = dest }; if (npp.path.Contains(npp.currentSystemID)) { // We have somehow looped back on ourself. continue; } npp.path.Add(npp.currentSystemID); // Find the shortest distance if this option is taken. npp = FindShortest(npp, highSec); if (spp == null) { // First successful path, keep it. spp = npp; } else { if (npp != null) { // Another successful path, is it shorter? if (npp.path.Count < spp.path.Count) { // Yes! Keep it. spp = npp; } } } } return(spp); } } return(pp); }