mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Better town layout
This commit is contained in:
parent
06820dbf16
commit
85c572f6e2
@ -87,7 +87,7 @@ impl<S: Clone + Eq + Hash + fmt::Debug, H: BuildHasher> fmt::Debug for Astar<S,
|
||||
}
|
||||
|
||||
impl<S: Clone + Eq + Hash, H: BuildHasher + Clone> Astar<S, H> {
|
||||
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<S: Clone + Eq + Hash, H: BuildHasher + Clone> Astar<S, H> {
|
||||
},
|
||||
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<S: Clone + Eq + Hash, H: BuildHasher + Clone> Astar<S, H> {
|
||||
pub fn poll<I>(
|
||||
&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<S: Clone + Eq + Hash, H: BuildHasher + Clone> Astar<S, H> {
|
||||
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);
|
||||
|
||||
|
@ -534,7 +534,7 @@ where
|
||||
_ => return (None, false),
|
||||
};
|
||||
|
||||
let heuristic = |pos: &Vec3<i32>| (pos.distance_squared(end) as f32).sqrt();
|
||||
let heuristic = |pos: &Vec3<i32>, _: &Vec3<i32>| (pos.distance_squared(end) as f32).sqrt();
|
||||
let neighbors = |pos: &Vec3<i32>| {
|
||||
let pos = *pos;
|
||||
const DIRS: [Vec3<i32>; 17] = [
|
||||
@ -639,7 +639,7 @@ where
|
||||
let satisfied = |pos: &Vec3<i32>| 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,
|
||||
};
|
||||
|
||||
|
@ -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<i32>| (sprite_pos - pos).map(|x| x.abs()).sum() as f32;
|
||||
let heuristic = move |pos: &Vec3<i32>, _: &Vec3<i32>| {
|
||||
(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::<FxHasher64>::default(),
|
||||
);
|
||||
|
||||
|
@ -43,13 +43,8 @@ const CARDINALS: &[Vec2<i32>] = &[
|
||||
];
|
||||
|
||||
fn path_in_site(start: Vec2<i32>, end: Vec2<i32>, site: &site2::Site) -> PathResult<Vec2<i32>> {
|
||||
let heuristic = |tile: &Vec2<i32>| tile.as_::<f32>().distance(end.as_());
|
||||
let mut astar = Astar::new(
|
||||
1000,
|
||||
start,
|
||||
heuristic,
|
||||
BuildHasherDefault::<FxHasher64>::default(),
|
||||
);
|
||||
let heuristic = |tile: &Vec2<i32>, _: &Vec2<i32>| tile.as_::<f32>().distance(end.as_());
|
||||
let mut astar = Astar::new(1000, start, BuildHasherDefault::<FxHasher64>::default());
|
||||
|
||||
let transition = |a: &Vec2<i32>, b: &Vec2<i32>| {
|
||||
let distance = a.as_::<f32>().distance(b.as_());
|
||||
@ -128,14 +123,10 @@ fn path_between_sites(
|
||||
let get_site = |site: &Id<civ::Site>| world.civs().sites.get(*site);
|
||||
|
||||
let end_pos = get_site(&end).center.as_::<f32>();
|
||||
let heuristic = |site: &Id<civ::Site>| get_site(site).center.as_().distance(end_pos);
|
||||
let heuristic =
|
||||
|site: &Id<civ::Site>, _: &Id<civ::Site>| get_site(site).center.as_().distance(end_pos);
|
||||
|
||||
let mut astar = Astar::new(
|
||||
250,
|
||||
start,
|
||||
heuristic,
|
||||
BuildHasherDefault::<FxHasher64>::default(),
|
||||
);
|
||||
let mut astar = Astar::new(250, start, BuildHasherDefault::<FxHasher64>::default());
|
||||
|
||||
let neighbors = |site: &Id<civ::Site>| world.civs().neighbors(*site);
|
||||
|
||||
@ -734,14 +725,10 @@ fn chunk_path(
|
||||
to: Vec2<i32>,
|
||||
chunk_height: impl Fn(Vec2<i32>) -> Option<i32>,
|
||||
) -> Box<dyn Action> {
|
||||
let heuristics = |(p, _): &(Vec2<i32>, i32)| p.distance_squared(to) as f32;
|
||||
let heuristics =
|
||||
|(p, _): &(Vec2<i32>, i32), _: &(Vec2<i32>, i32)| p.distance_squared(to) as f32;
|
||||
let start = (from, chunk_height(from).unwrap());
|
||||
let mut astar = Astar::new(
|
||||
1000,
|
||||
start,
|
||||
heuristics,
|
||||
BuildHasherDefault::<FxHasher64>::default(),
|
||||
);
|
||||
let mut astar = Astar::new(1000, start, BuildHasherDefault::<FxHasher64>::default());
|
||||
|
||||
let path = astar.poll(
|
||||
1000,
|
||||
|
@ -659,7 +659,7 @@ impl Civs {
|
||||
|
||||
/// Find the cheapest route between two places
|
||||
fn route_between(&self, a: Id<Site>, b: Id<Site>) -> Option<(Path<Id<Site>>, f32)> {
|
||||
let heuristic = move |p: &Id<Site>| {
|
||||
let heuristic = move |p: &Id<Site>, _: &Id<Site>| {
|
||||
(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::<FxHasher64>::default(),
|
||||
);
|
||||
let mut astar = Astar::new(100, a, BuildHasherDefault::<FxHasher64>::default());
|
||||
astar
|
||||
.poll(100, heuristic, neighbors, transition, satisfied)
|
||||
.into_path()
|
||||
@ -1306,7 +1301,7 @@ fn find_path(
|
||||
) -> Option<(Path<Vec2<i32>>, f32)> {
|
||||
const MAX_PATH_ITERS: usize = 100_000;
|
||||
let sim = &ctx.sim;
|
||||
let heuristic = move |l: &Vec2<i32>| (l.distance_squared(b) as f32).sqrt();
|
||||
let heuristic = move |l: &Vec2<i32>, _: &Vec2<i32>| (l.distance_squared(b) as f32).sqrt();
|
||||
let get_bridge = &get_bridge;
|
||||
let neighbors = |l: &Vec2<i32>| {
|
||||
let l = *l;
|
||||
@ -1327,7 +1322,6 @@ fn find_path(
|
||||
let mut astar = Astar::new(
|
||||
MAX_PATH_ITERS,
|
||||
a,
|
||||
heuristic,
|
||||
BuildHasherDefault::<FxHasher64>::default(),
|
||||
);
|
||||
astar
|
||||
|
@ -1349,7 +1349,7 @@ impl Land {
|
||||
dest: Vec2<i32>,
|
||||
mut path_cost_fn: impl FnMut(Option<&Tile>, Option<&Tile>) -> f32,
|
||||
) -> Option<Path<Vec2<i32>>> {
|
||||
let heuristic = |pos: &Vec2<i32>| (pos - dest).map(|e| e as f32).magnitude();
|
||||
let heuristic = |pos: &Vec2<i32>, _: &Vec2<i32>| (pos - dest).map(|e| e as f32).magnitude();
|
||||
let neighbors = |pos: &Vec2<i32>| {
|
||||
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::<FxHasher64>::default(),
|
||||
)
|
||||
.poll(250, heuristic, neighbors, transition, satisfied)
|
||||
.into_path()
|
||||
Astar::new(250, origin, BuildHasherDefault::<FxHasher64>::default())
|
||||
.poll(250, heuristic, neighbors, transition, satisfied)
|
||||
.into_path()
|
||||
}
|
||||
|
||||
/// We use this hasher (FxHasher64) because
|
||||
|
@ -146,7 +146,8 @@ impl Site {
|
||||
) -> Option<Id<Plot>> {
|
||||
const MAX_ITERS: usize = 4096;
|
||||
let range = -(w as i32) / 2..w as i32 - (w as i32 + 1) / 2;
|
||||
let heuristic = |tile: &Vec2<i32>| {
|
||||
let heuristic = |(tile, dir): &(Vec2<i32>, Vec2<i32>),
|
||||
(_, old_dir): &(Vec2<i32>, Vec2<i32>)| {
|
||||
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);
|
||||
|
@ -543,7 +543,8 @@ impl Floor {
|
||||
}
|
||||
|
||||
fn create_route(&mut self, _ctx: &mut GenCtx<impl Rng>, a: Vec2<i32>, b: Vec2<i32>) {
|
||||
let heuristic = move |l: &Vec2<i32>| (l - b).map(|e| e.abs()).reduce_max() as f32;
|
||||
let heuristic =
|
||||
move |l: &Vec2<i32>, _: &Vec2<i32>| (l - b).map(|e| e.abs()).reduce_max() as f32;
|
||||
let neighbors = |l: &Vec2<i32>| {
|
||||
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::<FxHasher64>::default(),
|
||||
);
|
||||
let mut astar = Astar::new(20000, a, BuildHasherDefault::<FxHasher64>::default());
|
||||
let path = astar
|
||||
.poll(
|
||||
FLOOR_SIZE.product() as usize + 1,
|
||||
|
Loading…
Reference in New Issue
Block a user