From b3d6b7cb77a660fc8a8e96645627da16c6b7c059 Mon Sep 17 00:00:00 2001 From: Justin Worthe Date: Sat, 18 May 2019 21:28:18 +0200 Subject: Started breaking up state for easier unit testing --- src/game.rs | 126 +++++++--------------------------------------------- src/game/map.rs | 64 ++++++++++++++++++++++++++ src/game/player.rs | 49 ++++++++++++++++++++ src/game/powerup.rs | 7 +++ 4 files changed, 135 insertions(+), 111 deletions(-) create mode 100644 src/game/map.rs create mode 100644 src/game/player.rs create mode 100644 src/game/powerup.rs (limited to 'src') diff --git a/src/game.rs b/src/game.rs index 1ac627d..1d9d33b 100644 --- a/src/game.rs +++ b/src/game.rs @@ -1,7 +1,15 @@ use crate::geometry::*; use crate::command::Command; use crate::json; -use crate::constants::*; + +mod player; +use player::*; + +mod powerup; +use powerup::*; + +mod map; +use map::*; use arrayvec::ArrayVec; @@ -15,32 +23,6 @@ pub struct GameBoard { pub outcome: SimulationOutcome } -#[derive(Debug, PartialEq, Eq, Clone)] -pub struct Player { - pub active_worm: usize, - pub worms: ArrayVec<[Worm; 3]> -} - -#[derive(Debug, PartialEq, Eq, Clone)] -pub struct Worm { - pub id: i32, - pub health: i32, - pub position: Point2d, - pub weapon_damage: i32, - pub weapon_range: u8 -} - -#[derive(Debug, PartialEq, Eq, Clone, Copy)] -pub struct Powerup { - pub position: Point2d, - pub value: i32 -} - -#[derive(Debug, PartialEq, Eq, Clone)] -pub struct Map { - pub cells: [u64; MAP_U64S] -} - #[derive(Debug, PartialEq, Eq, Clone, Copy)] pub enum SimulationOutcome { PlayerWon(usize), @@ -75,9 +57,7 @@ impl GameBoard { }).collect() }; - let mut map = Map { - cells: [0; MAP_U64S] - }; + let mut map = Map::default(); for cell in json.map.iter().flatten() { if cell.cell_type == json::CellType::Dirt { map.set(Point2d::new(cell.x, cell.y)) @@ -89,7 +69,7 @@ impl GameBoard { max_rounds: json.max_rounds, players: [player, opponent], powerups: json.map.iter().flatten().filter_map(|c| { - c.powerup.clone().map(|p| Powerup { + c.powerup.as_ref().map(|p| Powerup { position: Point2d::new(c.x, c.y), value: p.value }) @@ -114,7 +94,7 @@ impl GameBoard { } self.powerups = json.map.iter().flatten().filter_map(|c| { - c.powerup.clone().map(|p| Powerup { + c.powerup.as_ref().map(|p| Powerup { position: Point2d::new(c.x, c.y), value: p.value }) @@ -324,83 +304,7 @@ impl GameBoard { } } -impl Player { - pub fn find_worm(&self, id: i32) -> Option<&Worm> { - self.worms - .iter() - .find(|w| w.id == id) - } - - pub fn find_worm_mut(&mut self, id: i32) -> Option<&mut Worm> { - self.worms - .iter_mut() - .find(|w| w.id == id) - } - - pub fn active_worm(&self) -> &Worm { - &self.worms[self.active_worm] - } - - fn active_worm_mut(&mut self) -> &mut Worm { - &mut self.worms[self.active_worm] - } - - pub fn health(&self) -> i32 { - self.worms - .iter() - .map(|w| w.health) - .sum() - } -} - -impl Map { - pub fn at(&self, p: Point2d) -> Option { - if p.y < 0 || p.y as usize >= MAP_SIZE { - None - } else { - let row_data = &MAP_ROW_SIZE[p.y as usize]; - if p.x < row_data.x_offset as i8 || p.x as usize >= row_data.x_offset + row_data.len() { - None - } else { - let global_bit = row_data.start_bit + p.x as usize - row_data.x_offset; - let integer = global_bit / 64; - let bit = global_bit % 64; - let mask = 1 << bit; - Some(self.cells[integer] & mask != 0) - } - } - } - - fn set(&mut self, p: Point2d) { - if p.y < 0 || p.y as usize >= MAP_SIZE { - debug_assert!(false, "Tried to set an out of bounds bit, {:?}", p); - } else { - let row_data = &MAP_ROW_SIZE[p.y as usize]; - if p.x < row_data.x_offset as i8 || p.x as usize >= row_data.x_offset + row_data.len() { - debug_assert!(false, "Tried to set an out of bounds bit, {:?}", p); - } else { - let global_bit = row_data.start_bit + p.x as usize - row_data.x_offset; - let integer = global_bit / 64; - let bit = global_bit % 64; - let mask = 1 << bit; - self.cells[integer] |= mask; - } - } - } - fn clear(&mut self, p: Point2d) { - if p.y < 0 || p.y as usize >= MAP_SIZE { - debug_assert!(false, "Tried to set an out of bounds bit, {:?}", p); - } else { - let row_data = &MAP_ROW_SIZE[p.y as usize]; - if p.x < row_data.x_offset as i8 || p.x as usize >= row_data.x_offset + row_data.len() { - debug_assert!(false, "Tried to set an out of bounds bit, {:?}", p); - } else { - let global_bit = row_data.start_bit + p.x as usize - row_data.x_offset; - let integer = global_bit / 64; - let bit = global_bit % 64; - let mask = !(1 << bit); - self.cells[integer] &= mask; - } - } - } +#[cfg(test)] +mod test { + } diff --git a/src/game/map.rs b/src/game/map.rs new file mode 100644 index 0000000..c062c8f --- /dev/null +++ b/src/game/map.rs @@ -0,0 +1,64 @@ +use crate::geometry::*; +use crate::constants::*; + +#[derive(Default, Debug, PartialEq, Eq, Clone)] +pub struct Map { + cells: [u64; MAP_U64S] +} + +impl Map { + pub fn at(&self, p: Point2d) -> Option { + if p.y < 0 || p.y as usize >= MAP_SIZE { + None + } else { + let row_data = &MAP_ROW_SIZE[p.y as usize]; + if p.x < row_data.x_offset as i8 || p.x as usize >= row_data.x_offset + row_data.len() { + None + } else { + let global_bit = row_data.start_bit + p.x as usize - row_data.x_offset; + let integer = global_bit / 64; + let bit = global_bit % 64; + let mask = 1 << bit; + Some(self.cells[integer] & mask != 0) + } + } + } + + pub fn set(&mut self, p: Point2d) { + if p.y < 0 || p.y as usize >= MAP_SIZE { + debug_assert!(false, "Tried to set an out of bounds bit, {:?}", p); + } else { + let row_data = &MAP_ROW_SIZE[p.y as usize]; + if p.x < row_data.x_offset as i8 || p.x as usize >= row_data.x_offset + row_data.len() { + debug_assert!(false, "Tried to set an out of bounds bit, {:?}", p); + } else { + let global_bit = row_data.start_bit + p.x as usize - row_data.x_offset; + let integer = global_bit / 64; + let bit = global_bit % 64; + let mask = 1 << bit; + self.cells[integer] |= mask; + } + } + } + pub fn clear(&mut self, p: Point2d) { + if p.y < 0 || p.y as usize >= MAP_SIZE { + debug_assert!(false, "Tried to set an out of bounds bit, {:?}", p); + } else { + let row_data = &MAP_ROW_SIZE[p.y as usize]; + if p.x < row_data.x_offset as i8 || p.x as usize >= row_data.x_offset + row_data.len() { + debug_assert!(false, "Tried to set an out of bounds bit, {:?}", p); + } else { + let global_bit = row_data.start_bit + p.x as usize - row_data.x_offset; + let integer = global_bit / 64; + let bit = global_bit % 64; + let mask = !(1 << bit); + self.cells[integer] &= mask; + } + } + } +} + +#[cfg(test)] +mod test { + // TODO: Property test for at, set and clear +} diff --git a/src/game/player.rs b/src/game/player.rs new file mode 100644 index 0000000..acfc494 --- /dev/null +++ b/src/game/player.rs @@ -0,0 +1,49 @@ +use arrayvec::ArrayVec; +use crate::geometry::*; + +#[derive(Debug, PartialEq, Eq, Clone)] +pub struct Player { + pub active_worm: usize, + pub worms: ArrayVec<[Worm; 3]> +} + +#[derive(Debug, PartialEq, Eq, Clone)] +pub struct Worm { + pub id: i32, + pub health: i32, + pub position: Point2d, + pub weapon_damage: i32, + pub weapon_range: u8 +} + +impl Player { + pub fn find_worm(&self, id: i32) -> Option<&Worm> { + self.worms + .iter() + .find(|w| w.id == id) + } + + pub fn find_worm_mut(&mut self, id: i32) -> Option<&mut Worm> { + self.worms + .iter_mut() + .find(|w| w.id == id) + } + + pub fn active_worm(&self) -> &Worm { + &self.worms[self.active_worm] + } + + pub fn active_worm_mut(&mut self) -> &mut Worm { + &mut self.worms[self.active_worm] + } + + pub fn health(&self) -> i32 { + self.worms + .iter() + .map(|w| w.health) + .sum() + } + + // TODO: Cycle to next worm +} + diff --git a/src/game/powerup.rs b/src/game/powerup.rs new file mode 100644 index 0000000..2f07816 --- /dev/null +++ b/src/game/powerup.rs @@ -0,0 +1,7 @@ +use crate::geometry::*; + +#[derive(Debug, PartialEq, Eq, Clone, Copy)] +pub struct Powerup { + pub position: Point2d, + pub value: i32 +} -- cgit v1.2.3