diff options
author | Justin Worthe <justin@worthe-it.co.za> | 2017-06-24 17:49:35 +0200 |
---|---|---|
committer | Justin Worthe <justin@worthe-it.co.za> | 2017-06-24 17:49:35 +0200 |
commit | 7355491e14081c6dff749d6c536e876cfebc5d0d (patch) | |
tree | 197c135c7c7d04f539c4ca7c0ecdb8c72e9173d8 /src/knowledge.rs | |
parent | d7a5ae25a5a15064f695d79e2b510c9c305fb841 (diff) |
Implemented knowledge updates based on all weapon types
Diffstat (limited to 'src/knowledge.rs')
-rw-r--r-- | src/knowledge.rs | 113 |
1 files changed, 104 insertions, 9 deletions
diff --git a/src/knowledge.rs b/src/knowledge.rs index 4ade5f5..f271dbe 100644 --- a/src/knowledge.rs +++ b/src/knowledge.rs @@ -53,21 +53,57 @@ impl Knowledge { .map(|weapon| (weapon.clone(), weapon.single_shot_rounds_to_ready(energy, state.map_size))) .collect(); - let points = match self.last_action { + let (hits, misses, _) = match self.last_action { Action::PlaceShips(_) => { - vec!() + (vec!(), vec!(), vec!()) }, Action::Shoot(Weapon::SingleShot, p) => { - vec!(p) + Knowledge::to_hits_and_misses(vec!(Some(p)), &state) }, - Action::Shoot(w, p) => { - vec!() - //TODO + Action::Shoot(Weapon::DoubleShotVertical, p) => { + Knowledge::to_hits_and_misses(vec!( + p.move_point(Direction::North, 1, state.map_size), + p.move_point(Direction::South, 1, state.map_size) + ), &state) + }, + Action::Shoot(Weapon::DoubleShotHorizontal, p) => { + Knowledge::to_hits_and_misses(vec!( + p.move_point(Direction::East, 1, state.map_size), + p.move_point(Direction::West, 1, state.map_size) + ), &state) + }, + Action::Shoot(Weapon::CornerShot, p) => { + Knowledge::to_hits_and_misses(vec!( + p.move_point(Direction::NorthEast, 1, state.map_size), + p.move_point(Direction::SouthEast, 1, state.map_size), + p.move_point(Direction::NorthWest, 1, state.map_size), + p.move_point(Direction::SouthWest, 1, state.map_size), + ), &state) + }, + Action::Shoot(Weapon::CrossShotDiagonal, p) => { + Knowledge::to_hits_and_misses(vec!( + p.move_point(Direction::NorthEast, 1, state.map_size), + p.move_point(Direction::SouthEast, 1, state.map_size), + p.move_point(Direction::NorthWest, 1, state.map_size), + p.move_point(Direction::SouthWest, 1, state.map_size), + Some(p) + ), &state) + }, + Action::Shoot(Weapon::CrossShotHorizontal, p) => { + Knowledge::to_hits_and_misses(vec!( + p.move_point(Direction::North, 1, state.map_size), + p.move_point(Direction::East, 1, state.map_size), + p.move_point(Direction::South, 1, state.map_size), + p.move_point(Direction::West, 1, state.map_size), + Some(p) + ), &state) + }, + + Action::Shoot(Weapon::SeekerMissle, p) => { + Knowledge::seeker_hits_and_misses(p, &state) } }; - - let misses = points.iter().filter(|p| state.opponent_map.cells[p.x as usize][p.y as usize].missed).cloned().collect(); - let hits = points.iter().filter(|p| !state.opponent_map.cells[p.x as usize][p.y as usize].missed).cloned().collect(); + let sunk_ships = new_knowledge.opponent_map.update_sunk_ships(&state); new_knowledge.opponent_map.update_from_shot(hits, misses, sunk_ships); @@ -75,6 +111,65 @@ impl Knowledge { new_knowledge } + fn to_hits_and_misses(points: Vec<Option<Point>>, state: &State) -> (Vec<Point>, Vec<Point>, Vec<Point>) { + let points = points.iter().filter_map(|&p| p).collect::<Vec<_>>(); + + let hits = points.iter().filter(|p| !state.opponent_map.cells[p.x as usize][p.y as usize].damaged).cloned().collect(); + let misses = points.iter().filter(|p| state.opponent_map.cells[p.x as usize][p.y as usize].missed).cloned().collect(); + let unknown = points.iter().filter(|p| !state.opponent_map.cells[p.x as usize][p.y as usize].missed && !state.opponent_map.cells[p.x as usize][p.y as usize].damaged).cloned().collect(); + + (hits, misses, unknown) + } + + fn seeker_hits_and_misses(p: Point, state: &State) -> (Vec<Point>, Vec<Point>, Vec<Point>) { + let mut misses: Vec<Point> = Vec::new(); + let mut hits: Vec<Point> = Vec::new(); + + let rings = vec!( + vec!( + //0 + Some(p) + ), + vec!( + //1 + p.move_point(Direction::North, 1, state.map_size), + p.move_point(Direction::East, 1, state.map_size), + p.move_point(Direction::South, 1, state.map_size), + p.move_point(Direction::West, 1, state.map_size), + ), + vec!( + //1.44 + p.move_point(Direction::NorthEast, 1, state.map_size), + p.move_point(Direction::SouthEast, 1, state.map_size), + p.move_point(Direction::NorthWest, 1, state.map_size), + p.move_point(Direction::SouthWest, 1, state.map_size) + ), + vec!( + //2 + p.move_point(Direction::North, 2, state.map_size), + p.move_point(Direction::East, 2, state.map_size), + p.move_point(Direction::South, 2, state.map_size), + p.move_point(Direction::West, 2, state.map_size), + ) + ); + + //start in the center. Add rings, until I find a hit + //don't add more after a hit is found + for ring in rings { + if hits.is_empty() { + let (mut new_hits, mut new_misses, mut unknown) = Knowledge::to_hits_and_misses(ring, &state); + misses.append(&mut new_misses); + if !new_hits.is_empty() { + hits.append(&mut new_hits); + } else { + misses.append(&mut unknown); + } + } + } + + (hits, misses, vec!()) + } + pub fn has_unknown_hits(&self) -> bool { self.opponent_map.cells.iter().fold(false, |acc, x| { x.iter().fold(acc, |acc, y| acc || y.unknown_hit()) |