/// <summary> /// Gets the best possible path (approximate solution) using a A* alogrithm. /// </summary> /// <param name="start"></param> /// <param name="target"></param> /// <param name="minSecurityLevel">The mininmum, inclusive, security level.</param> /// <returns></returns> private static PathFinder FindBestPathCore(SolarSystem start, SolarSystem target, float minSecurityLevel) { var bestDepthes = new Dictionary<SolarSystem, int>(); var paths = new SortedList<float, PathFinder>(); PathFinder root = new PathFinder(start); bestDepthes.Add(start, -1); paths.Add(0, root); while (true) { if (paths.Count == 0) return null; PathFinder best = null; int depth = 0; // Pick the best candidate path, but ensures it matches the best depth found so far while (true) { // Picks the best one, returns if we found our target best = paths.Values[0]; if (best.m_system == target) return best; // Removes it from the list paths.RemoveAt(0); int bestDepth; depth = best.Depth; bestDepthes.TryGetValue(best.m_system, out bestDepth); if (bestDepth == depth || best.m_system == start) break; } // Gets the subpaths for the best path so far. depth++; foreach (var child in best.GetChildren(depth, bestDepthes)) { // Gets the heuristic key: the shorter, the better the candidate. var key = child.m_system.GetSquareDistanceWith(target) * (float)(depth * depth); if (child.m_system.SecurityLevel < minSecurityLevel) key *= 100.0f; while (paths.ContainsKey(key)) key++; // Stores it in the sorted list. paths.Add(key, child); } } }
/// <summary> /// Constructor for a child. /// </summary> /// <param name="parent"></param> /// <param name="system"></param> private PathFinder(PathFinder parent, SolarSystem system) { m_parent = parent; m_system = system; }
/// <summary> /// Constructor for a starting point /// </summary> /// <param name="system"></param> private PathFinder(SolarSystem system) { m_parent = null; m_system = system; }
/// <summary> /// Find the guessed shortest path using a A* (heuristic) algorithm. /// </summary> /// <param name="target">The target system.</param> /// <param name="minSecurityLevel">The mininmum, inclusive, real security level. Systems have levels between -1 and +1.</param> /// <returns>The list of systems, beginning with this one and ending with the provided target.</returns> public List <SolarSystem> GetFastestPathTo(SolarSystem target, float minSecurityLevel) { return(PathFinder.FindBestPath(this, target, minSecurityLevel)); }