Refactor the site enemy functions to return iterators.

This commit is contained in:
Tormod Gjeitnes Hellen
2023-02-21 17:14:04 +01:00
parent 5e506a02ef
commit 7164391c40

View File

@ -125,18 +125,22 @@ impl ProximityRequirements {
} }
} }
pub fn avoid_all_of(mut self, locations: Vec<Vec2<i32>>, distance: i32) -> Self { pub fn avoid_all_of(
let specs = locations mut self,
.into_iter() locations: impl Iterator<Item = Vec2<i32>>,
.map(|loc| ProximitySpec::avoid(loc, distance)); distance: i32,
) -> Self {
let specs = locations.map(|loc| ProximitySpec::avoid(loc, distance));
self.all_of.extend(specs); self.all_of.extend(specs);
self self
} }
pub fn close_to_one_of(mut self, locations: Vec<Vec2<i32>>, distance: i32) -> Self { pub fn close_to_one_of(
let specs = locations mut self,
.into_iter() locations: impl Iterator<Item = Vec2<i32>>,
.map(|loc| ProximitySpec::be_near(loc, distance)); distance: i32,
) -> Self {
let specs = locations.map(|loc| ProximitySpec::be_near(loc, distance));
self.any_of.extend(specs); self.any_of.extend(specs);
self self
} }
@ -1230,74 +1234,60 @@ impl Civs {
site site
} }
fn gnarling_enemies(&self) -> Vec<Vec2<i32>> { fn gnarling_enemies(&self) -> impl Iterator<Item = Vec2<i32>> + '_ {
self.sites() self.sites().filter_map(|s| match s.kind {
.filter_map(|s| match s.kind {
SiteKind::Tree | SiteKind::GiantTree => None, SiteKind::Tree | SiteKind::GiantTree => None,
_ => Some(s.center), _ => Some(s.center),
}) })
.collect()
} }
fn chapel_site_enemies(&self) -> Vec<Vec2<i32>> { fn chapel_site_enemies(&self) -> impl Iterator<Item = Vec2<i32>> + '_ {
self.sites() self.sites().filter_map(|s| match s.kind {
.filter_map(|s| match s.kind {
SiteKind::Tree | SiteKind::GiantTree => None, SiteKind::Tree | SiteKind::GiantTree => None,
_ => Some(s.center), _ => Some(s.center),
}) })
.collect()
} }
fn dungeon_enemies(&self) -> Vec<Vec2<i32>> { fn dungeon_enemies(&self) -> impl Iterator<Item = Vec2<i32>> + '_ {
self.sites() self.sites().filter_map(|s| match s.kind {
.filter_map(|s| match s.kind {
SiteKind::Tree | SiteKind::GiantTree => None, SiteKind::Tree | SiteKind::GiantTree => None,
_ => Some(s.center), _ => Some(s.center),
}) })
.collect()
} }
fn tree_enemies(&self) -> Vec<Vec2<i32>> { fn tree_enemies(&self) -> impl Iterator<Item = Vec2<i32>> + '_ {
self.sites() self.sites().filter_map(|s| match s.kind {
.filter_map(|s| match s.kind {
SiteKind::Castle => Some(s.center), SiteKind::Castle => Some(s.center),
_ if s.is_settlement() => Some(s.center), _ if s.is_settlement() => Some(s.center),
_ => None, _ => None,
}) })
.collect()
} }
fn castle_enemies(&self) -> Vec<Vec2<i32>> { fn castle_enemies(&self) -> impl Iterator<Item = Vec2<i32>> + '_ {
self.sites() self.sites().filter_map(|s| {
.filter_map(|s| {
if s.is_settlement() { if s.is_settlement() {
None None
} else { } else {
Some(s.center) Some(s.center)
} }
}) })
.collect()
} }
fn town_enemies(&self) -> Vec<Vec2<i32>> { fn town_enemies(&self) -> impl Iterator<Item = Vec2<i32>> + '_ {
self.sites() self.sites().filter_map(|s| match s.kind {
.filter_map(|s| match s.kind {
SiteKind::Castle | SiteKind::Citadel => None, SiteKind::Castle | SiteKind::Citadel => None,
_ => Some(s.center), _ => Some(s.center),
}) })
.collect()
} }
fn towns(&self) -> Vec<Vec2<i32>> { fn towns(&self) -> impl Iterator<Item = Vec2<i32>> + '_ {
self.sites() self.sites().filter_map(|s| {
.filter_map(|s| {
if s.is_settlement() { if s.is_settlement() {
Some(s.center) Some(s.center)
} else { } else {
None None
} }
}) })
.collect()
} }
} }
@ -1750,14 +1740,16 @@ mod tests {
#[test] #[test]
fn avoid_proximity_requirements() { fn avoid_proximity_requirements() {
let reqs = ProximityRequirements::new().avoid_all_of(vec![Vec2 { x: 0, y: 0 }], 10); let reqs =
ProximityRequirements::new().avoid_all_of(vec![Vec2 { x: 0, y: 0 }].into_iter(), 10);
assert!(reqs.satisfied_by(Vec2 { x: 8, y: -8 })); assert!(reqs.satisfied_by(Vec2 { x: 8, y: -8 }));
assert!(!reqs.satisfied_by(Vec2 { x: -1, y: 1 })); assert!(!reqs.satisfied_by(Vec2 { x: -1, y: 1 }));
} }
#[test] #[test]
fn near_proximity_requirements() { fn near_proximity_requirements() {
let reqs = ProximityRequirements::new().close_to_one_of(vec![Vec2 { x: 0, y: 0 }], 10); let reqs =
ProximityRequirements::new().close_to_one_of(vec![Vec2 { x: 0, y: 0 }].into_iter(), 10);
assert!(reqs.satisfied_by(Vec2 { x: 1, y: -1 })); assert!(reqs.satisfied_by(Vec2 { x: 1, y: -1 }));
assert!(!reqs.satisfied_by(Vec2 { x: -8, y: 8 })); assert!(!reqs.satisfied_by(Vec2 { x: -8, y: 8 }));
} }