diff --git a/common/src/astar.rs b/common/src/astar.rs index 37b9b09f95..83a263fa76 100644 --- a/common/src/astar.rs +++ b/common/src/astar.rs @@ -87,7 +87,7 @@ impl fmt::Debug for Astar Astar { - pub fn new(max_iters: usize, start: S, heuristic: impl FnOnce(&S) -> f32, hasher: H) -> Self { + pub fn new(max_iters: usize, start: S, hasher: H) -> Self { Self { max_iters, iter: 0, @@ -104,7 +104,7 @@ impl Astar { }, final_scores: { let mut h = HashMap::with_capacity_and_hasher(1, hasher.clone()); - h.extend(core::iter::once((start.clone(), heuristic(&start)))); + h.extend(core::iter::once((start.clone(), 0.0))); h }, visited: { @@ -120,7 +120,7 @@ impl Astar { pub fn poll( &mut self, iters: usize, - mut heuristic: impl FnMut(&S) -> f32, + mut heuristic: impl FnMut(&S, &S) -> f32, mut neighbors: impl FnMut(&S) -> I, mut transition: impl FnMut(&S, &S) -> f32, mut satisfied: impl FnMut(&S) -> bool, @@ -143,7 +143,7 @@ impl Astar { if cost < *neighbor_cheapest { self.came_from.insert(neighbor.clone(), node.clone()); self.cheapest_scores.insert(neighbor.clone(), cost); - let h = heuristic(&neighbor); + let h = heuristic(&neighbor, &node); let neighbor_cost = cost + h; self.final_scores.insert(neighbor.clone(), neighbor_cost); diff --git a/common/src/path.rs b/common/src/path.rs index 682a9ff16c..a6dc55a5c4 100644 --- a/common/src/path.rs +++ b/common/src/path.rs @@ -534,7 +534,7 @@ where _ => return (None, false), }; - let heuristic = |pos: &Vec3| (pos.distance_squared(end) as f32).sqrt(); + let heuristic = |pos: &Vec3, _: &Vec3| (pos.distance_squared(end) as f32).sqrt(); let neighbors = |pos: &Vec3| { let pos = *pos; const DIRS: [Vec3; 17] = [ @@ -639,7 +639,7 @@ where let satisfied = |pos: &Vec3| pos == &end; let mut new_astar = match astar.take() { - None => Astar::new(25_000, start, heuristic, DefaultHashBuilder::default()), + None => Astar::new(25_000, start, DefaultHashBuilder::default()), Some(astar) => astar, }; diff --git a/common/src/states/utils.rs b/common/src/states/utils.rs index 085832b890..3aaf1177b8 100644 --- a/common/src/states/utils.rs +++ b/common/src/states/utils.rs @@ -929,13 +929,13 @@ pub fn handle_manipulate_loadout( let iters = (3.0 * (sprite_pos_f32 - data.pos.0).map(|x| x.abs()).sum()) as usize; // Heuristic compares manhattan distance of start and end pos - let heuristic = - move |pos: &Vec3| (sprite_pos - pos).map(|x| x.abs()).sum() as f32; + let heuristic = move |pos: &Vec3, _: &Vec3| { + (sprite_pos - pos).map(|x| x.abs()).sum() as f32 + }; let mut astar = Astar::new( iters, data.pos.0.map(|x| x.floor() as i32), - heuristic, BuildHasherDefault::::default(), ); diff --git a/rtsim/src/rule/npc_ai.rs b/rtsim/src/rule/npc_ai.rs index 27bed72b37..380423c5ff 100644 --- a/rtsim/src/rule/npc_ai.rs +++ b/rtsim/src/rule/npc_ai.rs @@ -43,13 +43,8 @@ const CARDINALS: &[Vec2] = &[ ]; fn path_in_site(start: Vec2, end: Vec2, site: &site2::Site) -> PathResult> { - let heuristic = |tile: &Vec2| tile.as_::().distance(end.as_()); - let mut astar = Astar::new( - 1000, - start, - heuristic, - BuildHasherDefault::::default(), - ); + let heuristic = |tile: &Vec2, _: &Vec2| tile.as_::().distance(end.as_()); + let mut astar = Astar::new(1000, start, BuildHasherDefault::::default()); let transition = |a: &Vec2, b: &Vec2| { let distance = a.as_::().distance(b.as_()); @@ -128,14 +123,10 @@ fn path_between_sites( let get_site = |site: &Id| world.civs().sites.get(*site); let end_pos = get_site(&end).center.as_::(); - let heuristic = |site: &Id| get_site(site).center.as_().distance(end_pos); + let heuristic = + |site: &Id, _: &Id| get_site(site).center.as_().distance(end_pos); - let mut astar = Astar::new( - 250, - start, - heuristic, - BuildHasherDefault::::default(), - ); + let mut astar = Astar::new(250, start, BuildHasherDefault::::default()); let neighbors = |site: &Id| world.civs().neighbors(*site); @@ -734,14 +725,10 @@ fn chunk_path( to: Vec2, chunk_height: impl Fn(Vec2) -> Option, ) -> Box { - let heuristics = |(p, _): &(Vec2, i32)| p.distance_squared(to) as f32; + let heuristics = + |(p, _): &(Vec2, i32), _: &(Vec2, i32)| p.distance_squared(to) as f32; let start = (from, chunk_height(from).unwrap()); - let mut astar = Astar::new( - 1000, - start, - heuristics, - BuildHasherDefault::::default(), - ); + let mut astar = Astar::new(1000, start, BuildHasherDefault::::default()); let path = astar.poll( 1000, diff --git a/world/src/civ/mod.rs b/world/src/civ/mod.rs index c456da2f17..e482d844c6 100644 --- a/world/src/civ/mod.rs +++ b/world/src/civ/mod.rs @@ -659,7 +659,7 @@ impl Civs { /// Find the cheapest route between two places fn route_between(&self, a: Id, b: Id) -> Option<(Path>, f32)> { - let heuristic = move |p: &Id| { + let heuristic = move |p: &Id, _: &Id| { (self .sites .get(*p) @@ -676,12 +676,7 @@ impl Civs { // (1) we don't care about DDOS attacks (ruling out SipHash); // (2) we care about determinism across computers (ruling out AAHash); // (3) we have 8-byte keys (for which FxHash is fastest). - let mut astar = Astar::new( - 100, - a, - heuristic, - BuildHasherDefault::::default(), - ); + let mut astar = Astar::new(100, a, BuildHasherDefault::::default()); astar .poll(100, heuristic, neighbors, transition, satisfied) .into_path() @@ -1306,7 +1301,7 @@ fn find_path( ) -> Option<(Path>, f32)> { const MAX_PATH_ITERS: usize = 100_000; let sim = &ctx.sim; - let heuristic = move |l: &Vec2| (l.distance_squared(b) as f32).sqrt(); + let heuristic = move |l: &Vec2, _: &Vec2| (l.distance_squared(b) as f32).sqrt(); let get_bridge = &get_bridge; let neighbors = |l: &Vec2| { let l = *l; @@ -1327,7 +1322,6 @@ fn find_path( let mut astar = Astar::new( MAX_PATH_ITERS, a, - heuristic, BuildHasherDefault::::default(), ); astar diff --git a/world/src/site/settlement/mod.rs b/world/src/site/settlement/mod.rs index 1c2b16178f..c7d394f4d8 100644 --- a/world/src/site/settlement/mod.rs +++ b/world/src/site/settlement/mod.rs @@ -1349,7 +1349,7 @@ impl Land { dest: Vec2, mut path_cost_fn: impl FnMut(Option<&Tile>, Option<&Tile>) -> f32, ) -> Option>> { - let heuristic = |pos: &Vec2| (pos - dest).map(|e| e as f32).magnitude(); + let heuristic = |pos: &Vec2, _: &Vec2| (pos - dest).map(|e| e as f32).magnitude(); let neighbors = |pos: &Vec2| { let pos = *pos; CARDINALS.iter().map(move |dir| pos + *dir) @@ -1362,14 +1362,9 @@ impl Land { // (1) we don't care about DDOS attacks (ruling out SipHash); // (2) we don't care about determinism across computers (we could use AAHash); // (3) we have 8-byte keys (for which FxHash is fastest). - Astar::new( - 250, - origin, - heuristic, - BuildHasherDefault::::default(), - ) - .poll(250, heuristic, neighbors, transition, satisfied) - .into_path() + Astar::new(250, origin, BuildHasherDefault::::default()) + .poll(250, heuristic, neighbors, transition, satisfied) + .into_path() } /// We use this hasher (FxHasher64) because diff --git a/world/src/site2/mod.rs b/world/src/site2/mod.rs index 3d4f557047..8d8964ab5f 100644 --- a/world/src/site2/mod.rs +++ b/world/src/site2/mod.rs @@ -146,7 +146,8 @@ impl Site { ) -> Option> { const MAX_ITERS: usize = 4096; let range = -(w as i32) / 2..w as i32 - (w as i32 + 1) / 2; - let heuristic = |tile: &Vec2| { + let heuristic = |(tile, dir): &(Vec2, Vec2), + (_, old_dir): &(Vec2, Vec2)| { let mut max_cost = (tile.distance_squared(b) as f32).sqrt(); for y in range.clone() { for x in range.clone() { @@ -157,35 +158,35 @@ impl Site { } } } - max_cost + max_cost + (dir != old_dir) as i32 as f32 * 35.0 }; - let path = Astar::new(MAX_ITERS, a, heuristic, DefaultHashBuilder::default()) + let path = Astar::new(MAX_ITERS, (a, Vec2::zero()), DefaultHashBuilder::default()) .poll( MAX_ITERS, &heuristic, - |tile| { + |(tile, _)| { let tile = *tile; - CARDINALS.iter().map(move |dir| tile + *dir) + CARDINALS.iter().map(move |dir| (tile + *dir, *dir)) }, - |a, b| { + |(a, _), (b, _)| { let alt_a = land.get_alt_approx(self.tile_center_wpos(*a)); let alt_b = land.get_alt_approx(self.tile_center_wpos(*b)); (alt_a - alt_b).abs() / TILE_SIZE as f32 }, - |tile| *tile == b, + |(tile, _)| *tile == b, ) .into_path()?; let plot = self.create_plot(Plot { - kind: PlotKind::Road(path.clone()), + kind: PlotKind::Road(path.iter().map(|(tile, _)| *tile).collect()), root_tile: a, - tiles: path.clone().into_iter().collect(), + tiles: path.iter().map(|(tile, _)| *tile).collect(), seed: rng.gen(), }); self.roads.push(plot); - for (i, &tile) in path.iter().enumerate() { + for (i, (tile, _)) in path.iter().enumerate() { for y in range.clone() { for x in range.clone() { let tile = tile + Vec2::new(x, y); diff --git a/world/src/site2/plot/dungeon.rs b/world/src/site2/plot/dungeon.rs index 8b6d2d0a99..0adb946c78 100644 --- a/world/src/site2/plot/dungeon.rs +++ b/world/src/site2/plot/dungeon.rs @@ -543,7 +543,8 @@ impl Floor { } fn create_route(&mut self, _ctx: &mut GenCtx, a: Vec2, b: Vec2) { - let heuristic = move |l: &Vec2| (l - b).map(|e| e.abs()).reduce_max() as f32; + let heuristic = + move |l: &Vec2, _: &Vec2| (l - b).map(|e| e.abs()).reduce_max() as f32; let neighbors = |l: &Vec2| { let l = *l; CARDINALS @@ -562,12 +563,7 @@ impl Floor { // (1) we don't care about DDOS attacks (ruling out SipHash); // (2) we don't care about determinism across computers (we could use AAHash); // (3) we have 8-byte keys (for which FxHash is fastest). - let mut astar = Astar::new( - 20000, - a, - heuristic, - BuildHasherDefault::::default(), - ); + let mut astar = Astar::new(20000, a, BuildHasherDefault::::default()); let path = astar .poll( FLOOR_SIZE.product() as usize + 1,