From 71277362be44ff23cbbed2b182cdc929c8b5a273 Mon Sep 17 00:00:00 2001 From: ORelio Date: Thu, 17 Dec 2015 17:40:26 +0100 Subject: [PATCH] Add timeout when calculating unreachable path 5s timeout, assuming destination is unreachable otherwise. --- MinecraftClient/Mapping/Movement.cs | 89 +++++++++++++++-------------- 1 file changed, 47 insertions(+), 42 deletions(-) diff --git a/MinecraftClient/Mapping/Movement.cs b/MinecraftClient/Mapping/Movement.cs index b85852db..a12af234 100644 --- a/MinecraftClient/Mapping/Movement.cs +++ b/MinecraftClient/Mapping/Movement.cs @@ -98,54 +98,59 @@ namespace MinecraftClient.Mapping /// A list of locations, or null if calculation failed public static Queue CalculatePath(World world, Location start, Location goal, bool allowUnsafe = false) { - HashSet ClosedSet = new HashSet(); // The set of locations already evaluated. - HashSet OpenSet = new HashSet(new []{ start }); // The set of tentative nodes to be evaluated, initially containing the start node - Dictionary Came_From = new Dictionary(); // The map of navigated nodes. + Queue result = null; - Dictionary g_score = new Dictionary(); //:= map with default value of Infinity - g_score[start] = 0; // Cost from start along best known path. - // Estimated total cost from start to goal through y. - Dictionary f_score = new Dictionary(); //:= map with default value of Infinity - f_score[start] = (int)start.DistanceSquared(goal); //heuristic_cost_estimate(start, goal) - - while (OpenSet.Count > 0) + AutoTimeout.Perform(() => { - Location current = //the node in OpenSet having the lowest f_score[] value - OpenSet.Select(location => f_score.ContainsKey(location) - ? new KeyValuePair(location, f_score[location]) - : new KeyValuePair(location, int.MaxValue)) - .OrderBy(pair => pair.Value).First().Key; - if (current == goal) - { //reconstruct_path(Came_From, goal) - List total_path = new List(new[] { current }); - while (Came_From.ContainsKey(current)) - { - current = Came_From[current]; - total_path.Add(current); - } - total_path.Reverse(); - return new Queue(total_path); - } - OpenSet.Remove(current); - ClosedSet.Add(current); - foreach (Location neighbor in GetAvailableMoves(world, current, allowUnsafe)) + HashSet ClosedSet = new HashSet(); // The set of locations already evaluated. + HashSet OpenSet = new HashSet(new[] { start }); // The set of tentative nodes to be evaluated, initially containing the start node + Dictionary Came_From = new Dictionary(); // The map of navigated nodes. + + Dictionary g_score = new Dictionary(); //:= map with default value of Infinity + g_score[start] = 0; // Cost from start along best known path. + // Estimated total cost from start to goal through y. + Dictionary f_score = new Dictionary(); //:= map with default value of Infinity + f_score[start] = (int)start.DistanceSquared(goal); //heuristic_cost_estimate(start, goal) + + while (OpenSet.Count > 0) { - if (ClosedSet.Contains(neighbor)) - continue; // Ignore the neighbor which is already evaluated. - int tentative_g_score = g_score[current] + (int)current.DistanceSquared(neighbor); //dist_between(current,neighbor) // length of this path. - if (!OpenSet.Contains(neighbor)) // Discover a new node - OpenSet.Add(neighbor); - else if (tentative_g_score >= g_score[neighbor]) - continue; // This is not a better path. + Location current = //the node in OpenSet having the lowest f_score[] value + OpenSet.Select(location => f_score.ContainsKey(location) + ? new KeyValuePair(location, f_score[location]) + : new KeyValuePair(location, int.MaxValue)) + .OrderBy(pair => pair.Value).First().Key; + if (current == goal) + { //reconstruct_path(Came_From, goal) + List total_path = new List(new[] { current }); + while (Came_From.ContainsKey(current)) + { + current = Came_From[current]; + total_path.Add(current); + } + total_path.Reverse(); + result = new Queue(total_path); + } + OpenSet.Remove(current); + ClosedSet.Add(current); + foreach (Location neighbor in GetAvailableMoves(world, current, allowUnsafe)) + { + if (ClosedSet.Contains(neighbor)) + continue; // Ignore the neighbor which is already evaluated. + int tentative_g_score = g_score[current] + (int)current.DistanceSquared(neighbor); //dist_between(current,neighbor) // length of this path. + if (!OpenSet.Contains(neighbor)) // Discover a new node + OpenSet.Add(neighbor); + else if (tentative_g_score >= g_score[neighbor]) + continue; // This is not a better path. - // This path is the best until now. Record it! - Came_From[neighbor] = current; - g_score[neighbor] = tentative_g_score; - f_score[neighbor] = g_score[neighbor] + (int)neighbor.DistanceSquared(goal); //heuristic_cost_estimate(neighbor, goal) + // This path is the best until now. Record it! + Came_From[neighbor] = current; + g_score[neighbor] = tentative_g_score; + f_score[neighbor] = g_score[neighbor] + (int)neighbor.DistanceSquared(goal); //heuristic_cost_estimate(neighbor, goal) + } } - } + }, TimeSpan.FromSeconds(5)); - return null; + return result; } /* ========= LOCATION PROPERTIES ========= */