Replace SquareLocationRestriction with Aabr<i32>.

This is a fixup for 1572a5a759
This commit is contained in:
Tormod G. Hellen 2023-05-23 00:26:47 +02:00
parent af080016ab
commit a2ecd0b403
No known key found for this signature in database
GPG Key ID: 13F76F45CB334E5B

View File

@ -112,14 +112,6 @@ struct ProximityRequirements {
any_of: Vec<ProximitySpec>, any_of: Vec<ProximitySpec>,
} }
#[derive(Debug, PartialEq, Clone)]
struct SquareLocationRestriction {
pub min_x: i32,
pub max_x: i32,
pub min_y: i32,
pub max_y: i32,
}
impl ProximityRequirements { impl ProximityRequirements {
pub fn satisfied_by(&self, site: Vec2<i32>) -> bool { pub fn satisfied_by(&self, site: Vec2<i32>) -> bool {
let all_of_compliance = self.all_of.iter().all(|spec| spec.satisfied_by(site)); let all_of_compliance = self.all_of.iter().all(|spec| spec.satisfied_by(site));
@ -128,48 +120,42 @@ impl ProximityRequirements {
all_of_compliance && any_of_compliance all_of_compliance && any_of_compliance
} }
pub fn location_hint( pub fn location_hint(&self, world_dims: &Aabr<i32>) -> Aabr<i32> {
&self, let bounding_box_of_point = |point: Vec2<i32>, max_distance: i32| Aabr {
world_dims: &SquareLocationRestriction, min: Vec2 {
) -> SquareLocationRestriction { x: point.x - max_distance,
use std::cmp::{max, min}; y: point.y - max_distance,
},
max: Vec2 {
x: point.x + max_distance,
y: point.y + max_distance,
},
};
let any_of_hint = self let any_of_hint = self
.any_of .any_of
.iter() .iter()
.fold(None, |acc, spec| match spec.max_distance { .fold(None, |acc, spec| match spec.max_distance {
None => acc, None => acc,
Some(max_distance) => match acc { Some(max_distance) => {
None => Some(SquareLocationRestriction { let bounding_box_of_new_point =
min_x: spec.location.x - max_distance, bounding_box_of_point(spec.location, max_distance);
max_x: spec.location.x + max_distance, match acc {
min_y: spec.location.y - max_distance, None => Some(bounding_box_of_new_point),
max_y: spec.location.y + max_distance, Some(acc) => Some(acc.union(bounding_box_of_new_point)),
}), }
Some(acc) => Some(SquareLocationRestriction {
min_x: min(acc.min_x, spec.location.x - max_distance),
max_x: max(acc.max_x, spec.location.x + max_distance),
min_y: min(acc.min_y, spec.location.y - max_distance),
max_y: max(acc.max_y, spec.location.y + max_distance),
}),
}, },
}) })
.map(|hint| SquareLocationRestriction { .map(|hint| hint.intersection(*world_dims))
min_x: max(world_dims.min_x, hint.min_x),
max_x: min(world_dims.max_x, hint.max_x),
min_y: max(world_dims.min_y, hint.min_y),
max_y: min(world_dims.max_y, hint.max_y),
})
.unwrap_or_else(|| world_dims.to_owned()); .unwrap_or_else(|| world_dims.to_owned());
let hint = self let hint = self
.all_of .all_of
.iter() .iter()
.fold(any_of_hint, |acc, spec| match spec.max_distance { .fold(any_of_hint, |acc, spec| match spec.max_distance {
None => acc, None => acc,
Some(max_distance) => SquareLocationRestriction { Some(max_distance) => {
min_x: max(acc.min_x, spec.location.x - max_distance), let bounding_box_of_new_point =
max_x: min(acc.max_x, spec.location.x + max_distance), bounding_box_of_point(spec.location, max_distance);
min_y: max(acc.min_y, spec.location.y - max_distance), acc.intersection(bounding_box_of_new_point)
max_y: min(acc.max_y, spec.location.y + max_distance),
}, },
}); });
hint hint
@ -1517,17 +1503,18 @@ fn find_site_loc(
const MAX_ATTEMPTS: usize = 10000; const MAX_ATTEMPTS: usize = 10000;
let mut loc = None; let mut loc = None;
for _ in 0..MAX_ATTEMPTS { for _ in 0..MAX_ATTEMPTS {
let world_dims = SquareLocationRestriction { let world_dims = Aabr {
min_x: 0, min: Vec2 { x: 0, y: 0 },
max_x: ctx.sim.get_size().x as i32, max: Vec2 {
min_y: 0, x: ctx.sim.get_size().x as i32,
max_y: ctx.sim.get_size().y as i32, y: ctx.sim.get_size().y as i32,
},
}; };
let location_hint = proximity_reqs.location_hint(&world_dims); let location_hint = proximity_reqs.location_hint(&world_dims);
let test_loc = loc.unwrap_or_else(|| { let test_loc = loc.unwrap_or_else(|| {
Vec2::new( Vec2::new(
ctx.rng.gen_range(location_hint.min_x..location_hint.max_x), ctx.rng.gen_range(location_hint.min.x..location_hint.max.x),
ctx.rng.gen_range(location_hint.min_y..location_hint.max_y), ctx.rng.gen_range(location_hint.min.y..location_hint.max.y),
) )
}); });
@ -1917,17 +1904,13 @@ mod tests {
vec![Vec2 { x: 1, y: 0 }, Vec2 { x: 13, y: 12 }].into_iter(), vec![Vec2 { x: 1, y: 0 }, Vec2 { x: 13, y: 12 }].into_iter(),
10, 10,
); );
let expected = SquareLocationRestriction { let expected = Aabr {
min_x: 0, min: Vec2 { x: 0, y: 0 },
max_x: 23, max: Vec2 { x: 23, y: 22 },
min_y: 0,
max_y: 22,
}; };
let map_dims = SquareLocationRestriction { let map_dims = Aabr {
min_x: 0, min: Vec2 { x: 0, y: 0 },
max_x: 200, max: Vec2 { x: 200, y: 300 },
min_y: 0,
max_y: 300,
}; };
assert_eq!(expected, reqs.location_hint(&map_dims)); assert_eq!(expected, reqs.location_hint(&map_dims));
} }