summaryrefslogtreecommitdiff
path: root/src/game.rs
diff options
context:
space:
mode:
authorJustin Worthe <justin@worthe-it.co.za>2019-05-14 00:45:49 +0200
committerJustin Worthe <justin@worthe-it.co.za>2019-05-14 00:45:49 +0200
commitdcbd04dfdc6dd6dac88020d3a51f23fa5905c356 (patch)
treedc02ab4951f01f6c1561928390e848f8f415ecac /src/game.rs
parent652242e584ee2b7cfb3021d570a63e57cfa52773 (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.rs91
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]
}