diff options
| author | metamuffin <metamuffin@disroot.org> | 2025-10-19 19:39:49 +0200 |
|---|---|---|
| committer | metamuffin <metamuffin@disroot.org> | 2025-10-19 19:39:49 +0200 |
| commit | 129f4aa7f865df9de0d09afa758f65e79038cb77 (patch) | |
| tree | ce559b6978d2e55fd43f51c48d26575636187917 /server/bot | |
| parent | 62d918e5feeaf5b3add982a5baaffb201a1f2ece (diff) | |
| download | hurrycurry-129f4aa7f865df9de0d09afa758f65e79038cb77.tar hurrycurry-129f4aa7f865df9de0d09afa758f65e79038cb77.tar.bz2 hurrycurry-129f4aa7f865df9de0d09afa758f65e79038cb77.tar.zst | |
More readable pathfinding code
Diffstat (limited to 'server/bot')
| -rw-r--r-- | server/bot/src/pathfinding.rs | 48 |
1 files changed, 36 insertions, 12 deletions
diff --git a/server/bot/src/pathfinding.rs b/server/bot/src/pathfinding.rs index f4cf36d4..a32442b1 100644 --- a/server/bot/src/pathfinding.rs +++ b/server/bot/src/pathfinding.rs @@ -16,10 +16,11 @@ */ use hurrycurry_protocol::glam::{IVec2, Vec2}; -use log::trace; +use log::{debug, trace}; use std::{ cmp::Ordering, collections::{BinaryHeap, HashMap, HashSet}, + time::Instant, }; #[derive(Debug, Clone)] @@ -67,7 +68,12 @@ pub fn find_path_to_neighbour(walkable: &HashSet<IVec2>, from: IVec2, to: IVec2) } pub fn find_path(walkable: &HashSet<IVec2>, from: IVec2, to: IVec2) -> Option<Path> { #[derive(Debug, PartialEq, Eq)] - struct Open(i32, IVec2, IVec2, i32); + struct Open { + heuristic: i32, + pos: IVec2, + prev_pos: IVec2, + distance: i32, + } impl PartialOrd for Open { fn partial_cmp(&self, other: &Self) -> Option<Ordering> { Some(self.cmp(other)) @@ -75,32 +81,44 @@ pub fn find_path(walkable: &HashSet<IVec2>, from: IVec2, to: IVec2) -> Option<Pa } impl Ord for Open { fn cmp(&self, other: &Self) -> Ordering { - self.0.cmp(&other.0) + self.heuristic.cmp(&other.heuristic) } } + debug!("planning route from {from} to {to}"); + let start = Instant::now(); let mut visited = HashMap::new(); let mut open = BinaryHeap::new(); - open.push(Open(1, from, from, 0)); + open.push(Open { + heuristic: 1, + pos: from, + prev_pos: from, + distance: 0, + }); loop { - let Open(_, pos, f, distance) = open.pop()?; + let Open { + pos, + prev_pos, + distance, + .. + } = open.pop()?; if visited.contains_key(&pos) { continue; } - visited.insert(pos, f); + visited.insert(pos, prev_pos); if pos == to { break; } for dir in [IVec2::NEG_X, IVec2::NEG_Y, IVec2::X, IVec2::Y] { let next = pos + dir; if walkable.contains(&next) { - open.push(Open( - -(distance + next.distance_squared(to).isqrt()), - next, - pos, - distance + 1, - )); + open.push(Open { + heuristic: -(distance + next.distance_squared(to).isqrt()), + pos: next, + prev_pos: pos, + distance: distance + 1, + }); } } } @@ -115,6 +133,12 @@ pub fn find_path(walkable: &HashSet<IVec2>, from: IVec2, to: IVec2) -> Option<Pa } c = cn } + + debug!( + "done in {:?} (distance={})", + start.elapsed(), + segments.len() + ); Some(Path { segments, seg_time: 0., |