summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJustin Worthe <justin@worthe-it.co.za>2019-05-25 22:52:19 +0200
committerJustin Worthe <justin@worthe-it.co.za>2019-05-25 22:52:19 +0200
commit7b3fe83b4bdb943d3d44ed036150d017279cfe05 (patch)
tree4ed9bc57722d771fdecf9845e2412ec086eb80d0
parente9a514409565c17a4a86e8c6402be8d7a4f399ae (diff)
Implemented tracking of the tiebreaking score
-rw-r--r--src/game.rs45
-rw-r--r--src/game/player.rs13
-rw-r--r--src/json.rs12
-rw-r--r--tests/official-runner-matching.rs1
4 files changed, 65 insertions, 6 deletions
diff --git a/src/game.rs b/src/game.rs
index fe54f40..2112076 100644
--- a/src/game.rs
+++ b/src/game.rs
@@ -37,6 +37,7 @@ impl GameBoard {
let player = Player {
active_worm: json.active_worm_index().unwrap(),
+ moves_score: json.my_player.score - json.my_player.health_score(),
worms: json.my_player.worms.iter().map(|w| Worm {
id: w.id,
health: w.health,
@@ -48,6 +49,7 @@ impl GameBoard {
let opponent = Player {
active_worm: 0,
+ moves_score: json.opponents[0].score - json.opponents[0].health_score(),
worms: json.opponents.iter().flat_map(|o| &o.worms).map(|w| Worm {
id: w.id,
health: w.health,
@@ -93,6 +95,9 @@ impl GameBoard {
}
}
+ self.players[0].moves_score = json.my_player.score - json.my_player.health_score();
+ self.players[1].moves_score = json.opponents[0].score - json.opponents[0].health_score();
+
self.powerups = json.map.iter().flatten().filter_map(|c| {
c.powerup.as_ref().map(|p| Powerup {
position: Point2d::new(c.x, c.y),
@@ -143,7 +148,6 @@ impl GameBoard {
// TODO: Get this from some sort of config rather
let damage = 20;
-
debug_assert_eq!(Some(false), self.map.at(Point2d::new(p1.x, p1.y)), "Movement target wasn't empty, ({}, {})", p1.x, p1.y);
// Worms have a 50% chance of swapping places
// here. I'm treating that as an edge case that I
@@ -151,6 +155,7 @@ impl GameBoard {
for player in &mut self.players {
let worm = player.active_worm_mut();
worm.health = worm.health.saturating_sub(damage);
+ player.moves_score += 5;
}
},
_ => {
@@ -158,6 +163,8 @@ impl GameBoard {
if let Command::Move(p) = moves[player_index] {
debug_assert_eq!(Some(false), self.map.at(p), "Movement target wasn't empty, ({}, {})", p.x, p.y);
+ self.players[player_index].moves_score += 5;
+
let worm = self.players[player_index].active_worm_mut();
debug_assert!(
@@ -196,13 +203,15 @@ impl GameBoard {
"Tried to dig too far away, ({}, {})", p.x, p.y
};
+ self.players[player_index].moves_score += 7;
+
self.map.clear(p);
}
}
}
fn simulate_shoots(&mut self, moves: [Command; 2]) {
- for player_index in 0..moves.len() {
+ 'players_loop: for player_index in 0..moves.len() {
if let Command::Shoot(dir) = moves[player_index] {
let (center, weapon_range, weapon_damage) = {
let worm = self.players[player_index].active_worm();
@@ -220,17 +229,41 @@ impl GameBoard {
let target = center + diff * distance;
match self.map.at(target) {
Some(false) => {
- let target_worm: Option<&mut Worm> = self.players.iter_mut()
- .flat_map(|p| p.worms.iter_mut())
+ let target_own_worm: Option<&mut Worm> = self.players[player_index]
+ .worms.iter_mut()
.find(|w| w.position == target);
- if let Some(target_worm) = target_worm {
+
+ if let Some(target_worm) = target_own_worm {
target_worm.health -= weapon_damage;
- break;
+ if target_worm.health <= 0 {
+ // TODO: This will probably be changed soon https://github.com/EntelectChallenge/2019-Worms/issues/42
+ self.players[player_index].moves_score += 40;
+ } else {
+ self.players[player_index].moves_score -= 20;
+ }
+ continue 'players_loop;
+ }
+
+ let target_opponent_worm: Option<&mut Worm> = self.players[GameBoard::opponent(player_index)]
+ .worms.iter_mut()
+ .find(|w| w.position == target);
+ if let Some(target_worm) = target_opponent_worm {
+ target_worm.health -= weapon_damage;
+ if target_worm.health <= 0 {
+ self.players[player_index].moves_score += 40;
+ } else {
+ self.players[player_index].moves_score += 20;
+ }
+
+ continue 'players_loop;
}
},
_ => break
}
}
+
+ // You get here if the shot missed. Hits are an early return.
+ self.players[player_index].moves_score += 2;
}
}
}
diff --git a/src/game/player.rs b/src/game/player.rs
index e083a7a..917abef 100644
--- a/src/game/player.rs
+++ b/src/game/player.rs
@@ -3,6 +3,7 @@ use crate::geometry::*;
#[derive(Debug, PartialEq, Eq, Clone)]
pub struct Player {
+ pub moves_score: i32,
pub active_worm: usize,
pub worms: ArrayVec<[Worm; 3]>
}
@@ -64,6 +65,14 @@ impl Player {
pub fn next_active_worm(&mut self) {
self.active_worm = (self.active_worm + 1).checked_rem(self.worms.len()).unwrap_or(0);
}
+
+ fn health_score(&self) -> i32 {
+ self.health() / 3
+ }
+
+ pub fn score(&self) -> i32 {
+ self.moves_score + self.health_score()
+ }
}
#[cfg(test)]
@@ -96,6 +105,7 @@ mod test {
});
let mut player = Player {
active_worm: 1,
+ moves_score: 0,
worms: worms
};
@@ -134,6 +144,7 @@ mod test {
});
let mut player = Player {
active_worm: 1,
+ moves_score: 0,
worms: worms
};
@@ -172,6 +183,7 @@ mod test {
});
let mut player = Player {
active_worm: 0,
+ moves_score: 0,
worms: worms
};
@@ -196,6 +208,7 @@ mod test {
});
let mut player = Player {
active_worm: 0,
+ moves_score: 0,
worms: worms
};
diff --git a/src/json.rs b/src/json.rs
index c796d2b..3cd603c 100644
--- a/src/json.rs
+++ b/src/json.rs
@@ -37,6 +37,12 @@ pub struct Player {
pub worms: Vec<PlayerWorm>,
}
+impl Player {
+ pub fn health_score(&self) -> i32 {
+ self.health / self.worms.len() as i32
+ }
+}
+
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq)]
#[serde(rename_all = "camelCase")]
pub struct PlayerWorm {
@@ -56,6 +62,12 @@ pub struct Opponent {
pub worms: Vec<OpponentWorm>,
}
+impl Opponent {
+ pub fn health_score(&self) -> i32 {
+ self.worms.iter().map(|w| w.health).sum::<i32>() / 3
+ }
+}
+
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq)]
#[serde(rename_all = "camelCase")]
pub struct OpponentWorm {
diff --git a/tests/official-runner-matching.rs b/tests/official-runner-matching.rs
index c9cc387..19cfdeb 100644
--- a/tests/official-runner-matching.rs
+++ b/tests/official-runner-matching.rs
@@ -45,6 +45,7 @@ fn simulates_the_same_match() {
0 => &player,
_ => &opponent
};
+ assert_eq!(csv_row[4].parse::<i32>().unwrap(), game_board.players[player_index].score(), "Score is incorrect for player {}, Row: {:?}", player_index, csv_row);
for worm_index in 0..3 {
let worm_id = worm_index as i32 + 1;