diff options
author | Justin Worthe <justin@worthe-it.co.za> | 2019-05-14 11:12:50 +0200 |
---|---|---|
committer | Justin Worthe <justin@worthe-it.co.za> | 2019-05-14 11:12:50 +0200 |
commit | 56627fa6c913919acef6799c489ba9c5cf25cd0a (patch) | |
tree | 46d00b0f10f0b152bcf982ca87f1397aaf68fa2b /src/game.rs | |
parent | dcbd04dfdc6dd6dac88020d3a51f23fa5905c356 (diff) |
Better performance for finding things to shoot at
Diffstat (limited to 'src/game.rs')
-rw-r--r-- | src/game.rs | 65 |
1 files changed, 41 insertions, 24 deletions
diff --git a/src/game.rs b/src/game.rs index 3a7cd92..9903250 100644 --- a/src/game.rs +++ b/src/game.rs @@ -268,31 +268,48 @@ impl GameBoard { self.outcome } - pub fn find_target(&self, center: Point2d<i8>, dir: Direction, weapon_range: u8) -> Option<&Worm> { - let diff = dir.as_vec(); - - let range = if dir.is_diagonal() { - ((weapon_range as f32 + 1.) / 2f32.sqrt()).floor() as i8 - } else { - weapon_range as i8 - }; - - let mut target_worm: Option<&Worm> = None; - for distance in 1..=range { - let target = center + diff * distance; - match self.map.at(target) { - Some(false) => { - target_worm = self.players.iter() - .flat_map(|p| p.worms.iter()) - .find(|w| w.position == target); - if target_worm.is_some() { - break; + pub fn find_targets(&self, center: Point2d<i8>, weapon_range: u8) -> Vec<Direction> { + let range = weapon_range as i8; + let dir_range = ((weapon_range as f32 + 1.) / 2f32.sqrt()).floor() as i8; + + let mut directions: Vec<Direction> = self.players.iter() + .flat_map(|p| p.worms.iter()) + .filter(|w| w.position != center) + .filter_map(|w| { + let diff = w.position - center; + if diff.x == 0 && diff.y.abs() <= range { + if diff.y > 0 { + Some((Direction::South, diff.y)) + } else { + Some((Direction::North, -diff.y)) } - }, - _ => break - } - } - target_worm + } else if diff.y == 0 && diff.x.abs() <= range { + if diff.x > 0 { + Some((Direction::East, diff.x)) + } else { + Some((Direction::West, -diff.x)) + } + } else if diff.x.abs() == diff.y.abs() && diff.x.abs() <= dir_range { + match (diff.x > 0, diff.y > 0) { + (true, true) => Some((Direction::SouthEast, diff.x)), + (false, true) => Some((Direction::SouthWest, -diff.x)), + (true, false) => Some((Direction::NorthEast, diff.x)), + (false, false) => Some((Direction::NorthWest, -diff.x)), + } + } else { + None + } + }) + .filter(|(dir, range)| { + let diff = dir.as_vec(); + (1..*range).any(|distance| self.map.at(center + diff * distance) != Some(false)) + }) + .map(|(dir, _range)| dir) + .collect(); + + directions.sort(); + directions.dedup(); + directions } } |