1
2
Fork 0
mirror of https://github.com/mat-1/azalea.git synced 2025-08-02 06:16:04 +00:00

don't save Movement type while pathfinding as an optimization, recalculate it later in reconstruct_path

This commit is contained in:
mat 2024-12-27 06:27:16 +00:00
parent 3c3952bb0b
commit 185ed84dbb

View file

@ -66,11 +66,10 @@ where
f_score: 0., f_score: 0.,
index: 0, index: 0,
}); });
let mut nodes: FxIndexMap<P, Node<M>> = IndexMap::default(); let mut nodes: FxIndexMap<P, Node> = IndexMap::default();
nodes.insert( nodes.insert(
start, start,
Node { Node {
movement_data: None,
came_from: usize::MAX, came_from: usize::MAX,
g_score: 0., g_score: 0.,
}, },
@ -89,7 +88,7 @@ where
debug!("Nodes considered: {num_nodes}"); debug!("Nodes considered: {num_nodes}");
return Path { return Path {
movements: reconstruct_path(nodes, index), movements: reconstruct_path(nodes, index, successors),
is_partial: false, is_partial: false,
}; };
} }
@ -115,7 +114,6 @@ where
neighbor_heuristic = heuristic(*e.key()); neighbor_heuristic = heuristic(*e.key());
neighbor_index = e.index(); neighbor_index = e.index();
e.insert(Node { e.insert(Node {
movement_data: Some(neighbor.movement.data),
came_from: index, came_from: index,
g_score: tentative_g_score, g_score: tentative_g_score,
}); });
@ -127,7 +125,6 @@ where
neighbor_heuristic = heuristic(*e.key()); neighbor_heuristic = heuristic(*e.key());
neighbor_index = e.index(); neighbor_index = e.index();
e.insert(Node { e.insert(Node {
movement_data: Some(neighbor.movement.data),
came_from: index, came_from: index,
g_score: tentative_g_score, g_score: tentative_g_score,
}); });
@ -189,7 +186,7 @@ where
); );
Path { Path {
movements: reconstruct_path(nodes, best_path), movements: reconstruct_path(nodes, best_path, successors),
is_partial: true, is_partial: true,
} }
} }
@ -206,32 +203,46 @@ fn determine_best_path(best_paths: [usize; 7], start: usize) -> usize {
best_paths[0] best_paths[0]
} }
fn reconstruct_path<P, M>( fn reconstruct_path<P, M, SuccessorsFn>(
mut nodes: FxIndexMap<P, Node<M>>, nodes: FxIndexMap<P, Node>,
mut current_index: usize, mut current_index: usize,
mut successors: SuccessorsFn,
) -> Vec<Movement<P, M>> ) -> Vec<Movement<P, M>>
where where
P: Eq + Hash + Copy + Debug, P: Eq + Hash + Copy + Debug,
SuccessorsFn: FnMut(P) -> Vec<Edge<P, M>>,
{ {
let mut path = Vec::new(); let mut path = Vec::new();
while let Some((&node_position, node)) = nodes.get_index_mut(current_index) { while let Some((&node_position, node)) = nodes.get_index(current_index) {
if node.came_from == usize::MAX { if node.came_from == usize::MAX {
break; break;
} }
let came_from_position = *nodes.get_index(node.came_from).unwrap().0;
current_index = node.came_from; // find the movement data for this successor, we have to do this again because
// we don't include the movement data in the Node (as an optimization)
let mut best_successor = None;
let mut best_successor_cost = f32::INFINITY;
for successor in successors(came_from_position) {
if successor.movement.target == node_position && successor.cost < best_successor_cost {
best_successor_cost = successor.cost;
best_successor = Some(successor);
}
}
let found_successor = best_successor.expect("No successor found");
path.push(Movement { path.push(Movement {
target: node_position, target: node_position,
data: node.movement_data.take().unwrap(), data: found_successor.movement.data,
}); });
current_index = node.came_from;
} }
path.reverse(); path.reverse();
path path
} }
pub struct Node<M> { pub struct Node {
pub movement_data: Option<M>,
pub came_from: usize, pub came_from: usize,
pub g_score: f32, pub g_score: f32,
} }