diff options
author | Justin Worthe <justin@worthe-it.co.za> | 2019-05-14 00:45:49 +0200 |
---|---|---|
committer | Justin Worthe <justin@worthe-it.co.za> | 2019-05-14 00:45:49 +0200 |
commit | dcbd04dfdc6dd6dac88020d3a51f23fa5905c356 (patch) | |
tree | dc02ab4951f01f6c1561928390e848f8f415ecac /src/game.rs | |
parent | 652242e584ee2b7cfb3021d570a63e57cfa52773 (diff) |
Filled in the rest of the MCTS
Problem: The current random things isn't actually finding any
victorious end states. This game easily meanders if it's played
without purpose.
Diffstat (limited to 'src/game.rs')
-rw-r--r-- | src/game.rs | 91 |
1 files changed, 76 insertions, 15 deletions
diff --git a/src/game.rs b/src/game.rs index bf014f1..3a7cd92 100644 --- a/src/game.rs +++ b/src/game.rs @@ -5,8 +5,10 @@ use crate::constants::*; use arrayvec::ArrayVec; -#[derive(Clone)] +#[derive(Debug, PartialEq, Eq, Clone)] pub struct GameBoard { + pub round: u16, + pub max_rounds: u16, pub players: [Player; 2], pub powerups: ArrayVec<[Powerup; 2]>, pub map: Map, @@ -33,7 +35,7 @@ pub enum Powerup { Health(Point2d<i8>, i32) } -#[derive(Clone)] +#[derive(Debug, PartialEq, Eq, Clone)] pub struct Map { pub cells: [u64; MAP_U64S] } @@ -82,6 +84,8 @@ impl GameBoard { } GameBoard { + round: json.current_round, + max_rounds: json.max_rounds, players: [player, opponent], powerups: json.map.iter().flatten().filter_map(|c| { c.powerup.clone().map(|p| Powerup::Health(Point2d::new(c.x, c.y), p.value)) @@ -91,14 +95,52 @@ impl GameBoard { } } - pub fn update(&mut self, _json: json::State) { - // TODO - // What can change? - // - Worm health (and dead worms die) - // - Active worms += 1 - // - The worms may move - // - The powerups may be taken - // - The map cells may change from dirt to not dirt + pub fn update(&mut self, json: json::State) { + for w in json.my_player.worms { + if let Some(worm) = self.players[0].find_worm_mut(w.id) { + worm.health = w.health; + worm.position = Point2d::new(w.position.x, w.position.y); + } + } + for w in json.opponents.iter().flat_map(|o| &o.worms) { + if let Some(worm) = self.players[1].find_worm_mut(w.id) { + worm.health = w.health; + worm.position = Point2d::new(w.position.x, w.position.y); + } + } + + self.powerups = json.map.iter().flatten().filter_map(|c| { + c.powerup.clone().map(|p| Powerup::Health(Point2d::new(c.x, c.y), p.value)) + }).collect(); + + for cell in json.map.iter().flatten() { + if cell.cell_type == json::CellType::Air { + self.map.clear(Point2d::new(cell.x, cell.y)) + } + } + + self.round += 1; + debug_assert_eq!(json.current_round, self.round); + + // Remove dead worms and update active worm + for player in &mut self.players { + for worm_index in (0..player.worms.len()).rev() { + if player.worms[worm_index].health <= 0 { + player.worms.remove(worm_index); + if player.active_worm >= worm_index { + if player.active_worm > 0 { + player.active_worm -= 1; + } else { + player.active_worm = player.worms.len()-1; + } + } + } + } + // Update the active worm + if player.worms.len() > 0 { + player.active_worm = (player.active_worm + 1).checked_rem(player.worms.len()).unwrap_or(0); + } + } } pub fn simulate(&mut self, moves: [Command; 2]) -> SimulationOutcome { @@ -131,6 +173,14 @@ impl GameBoard { worm.position.x = x; worm.position.y = y; + + self.powerups.retain(|p| match p { + Powerup::Health(point, size) if *point == worm.position => { + worm.health += *size; + false + }, + _ => true + }); } } } @@ -200,13 +250,18 @@ impl GameBoard { } } // Update the active worm - player.active_worm = (player.active_worm + 1) % player.worms.len(); + if player.worms.len() > 0 { + player.active_worm = (player.active_worm + 1).checked_rem(player.worms.len()).unwrap_or(0); + } } - self.outcome = match (self.players[0].worms.len(), self.players[1].worms.len()) { - (0, 0) => SimulationOutcome::Draw, - (_, 0) => SimulationOutcome::PlayerWon(0), - (0, _) => SimulationOutcome::PlayerWon(1), + self.round += 1; + + self.outcome = match (self.players[0].worms.len(), self.players[1].worms.len(), self.round > self.max_rounds) { + (0, 0, _) => SimulationOutcome::Draw, + (_, 0, _) => SimulationOutcome::PlayerWon(0), + (0, _, _) => SimulationOutcome::PlayerWon(1), + (_, _, true) => SimulationOutcome::Draw, _ => SimulationOutcome::Continue }; @@ -248,6 +303,12 @@ impl Player { .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] } |