diff options
author | Justin Worthe <justin.worthe@gmail.com> | 2017-05-13 21:01:14 +0200 |
---|---|---|
committer | Justin Worthe <justin.worthe@gmail.com> | 2017-05-13 21:01:14 +0200 |
commit | 872529bc9a13b1923047a7f9308abaa40eb63d3c (patch) | |
tree | 9da73efa835896ee206daeb262fde550aaa99907 /src/actions.rs | |
parent | 36b72bfef7b7b8dea94546d11704ec529091bce1 (diff) |
Random placement
Diffstat (limited to 'src/actions.rs')
-rw-r--r-- | src/actions.rs | 52 |
1 files changed, 49 insertions, 3 deletions
diff --git a/src/actions.rs b/src/actions.rs index a7f61b5..1b6400d 100644 --- a/src/actions.rs +++ b/src/actions.rs @@ -3,9 +3,11 @@ use ships::*; use std::fmt; +use std::collections::HashSet; + #[derive(Clone, PartialEq, Eq, Debug)] pub enum Action { - PlaceShips(Vec<(Ship, Point, Orientation)>), + PlaceShips(Vec<ShipPlacement>), Shoot(Point) } @@ -13,10 +15,54 @@ impl fmt::Display for Action { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self { &Action::Shoot(p) => writeln!(f, "1,{},{}", p.x, p.y), - &Action::PlaceShips(ref ships) => ships.iter().map(|&(ref ship_type, p, orientation)| { - writeln!(f, "{} {} {} {}", ship_type, p.x, p.y, orientation) + &Action::PlaceShips(ref ships) => ships.iter().map(|ref ship| { + writeln!(f, "{} {} {} {}", ship.ship_type, ship.point.x, ship.point.y, ship.direction) }).fold(Ok(()), |acc, next| acc.and(next)) } } } +#[derive(Clone, PartialEq, Eq, Debug)] +pub struct ShipPlacement { + ship_type: Ship, + point: Point, + direction: Direction +} + +impl ShipPlacement { + pub fn new(ship_type: Ship, point: Point, direction: Direction) -> ShipPlacement { + ShipPlacement { + ship_type: ship_type, + point: point, + direction: direction + } + } + + pub fn valid(&self, map_size: u16) -> bool { + let start = self.point; + let end = start.move_point(self.direction, self.ship_type.length(), map_size); + start.x < map_size && start.y < map_size && end.is_some() + } + pub fn valid_placements(placements: &Vec<ShipPlacement>, map_size: u16) -> bool { + let mut occupied = HashSet::new(); + let mut individuals_valid = true; + let mut no_overlaps = true; + + for placement in placements { + individuals_valid = individuals_valid && placement.valid(map_size); + + for i in 0..placement.ship_type.length() { + match placement.point.move_point(placement.direction, i, map_size) { + Some(block) => { + no_overlaps = no_overlaps && !occupied.contains(&block); + occupied.insert(block); + }, + None => { + //invalid case here is handled above + } + } + } + } + individuals_valid && no_overlaps + } +} |