From 90e93249a57ac9347440c09424383bd43e497135 Mon Sep 17 00:00:00 2001 From: Justin Worthe Date: Tue, 6 Aug 2019 10:25:06 +0200 Subject: New statefile changes --- src/game.rs | 19 ++++++---------- src/json.rs | 72 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 78 insertions(+), 13 deletions(-) diff --git a/src/game.rs b/src/game.rs index dbf02e5..c9f9b56 100644 --- a/src/game.rs +++ b/src/game.rs @@ -116,8 +116,6 @@ impl GameBoard { } pub fn update(&mut self, json: json::State) { - // Much of this becomes easier if this issue is implemented: https://github.com/EntelectChallenge/2019-Worms/issues/44 - for w in &json.my_player.worms { if let Some(worm) = self.players[0].find_worm_mut(w.id) { worm.health = w.health; @@ -129,17 +127,7 @@ impl GameBoard { 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); - // TODO: How to update opponent worm bombs? One idea: - // start the update by passing in the move that I did, - // and doing a simulation where the opponent did - // nothing. Then, looking at the points that the - // opponent actually got, determine if they did a - // simple walk / dig / shoot or if they hit multiple - // worms, hit worms with bomb levels of damage, or - // destroyed a dirt not next to them. I can further - // tell if they used a select (number of selects), and - // who their new active worm is, and if that worm - // could have bombed. + // TODO: Update number of bombs / snowballs based on previous move } } self.players[0].moves_score = json.my_player.score - json.my_player.health_score(); @@ -186,10 +174,15 @@ impl GameBoard { pub fn simulate(&mut self, moves: [Command; 2]) { let actions = [moves[0].action, moves[1].action]; + // TODO: move lava in + // TODO: hurt worms that are standing on lava + // TODO: tick frozen timers + self.simulate_select(moves); self.simulate_moves(actions); self.simulate_digs(actions); self.simulate_bombs(actions); + // TODO: simulalte snowballs (question order on forums?) self.simulate_shoots(actions); for player in &mut self.players { diff --git a/src/json.rs b/src/json.rs index 4ac274a..73d28e9 100644 --- a/src/json.rs +++ b/src/json.rs @@ -20,6 +20,8 @@ pub fn read_state_from_json_file(filename: &Path) -> Result> { pub struct State { pub current_round: u16, pub max_rounds: u16, + pub pushback_damage: i32, + pub lava_damage: i32, pub map_size: u8, pub current_worm_id: i32, pub consecutive_do_nothing_count: u32, @@ -52,8 +54,10 @@ pub struct PlayerWorm { pub position: Position, pub digging_range: u32, pub movement_range: u32, + pub rounds_until_unfrozen: u8, pub weapon: Weapon, pub banana_bombs: Option, + pub snowballs: Option, pub profession: WormType, } @@ -63,6 +67,7 @@ pub struct Opponent { pub id: i32, pub score: i32, pub current_worm_id: i32, + pub previous_command: String, pub worms: Vec, pub remaining_worm_selections: u8, } @@ -81,6 +86,7 @@ pub struct OpponentWorm { pub position: Position, pub digging_range: u32, pub movement_range: u32, + pub rounds_until_unfrozen: u8, pub profession: WormType, } @@ -89,6 +95,7 @@ pub struct OpponentWorm { pub enum WormType { Commando, Agent, + Technologist, } #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq)] @@ -172,6 +179,15 @@ pub struct Bomb { pub damage_radius: u8, } +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq)] +#[serde(rename_all = "camelCase")] +pub struct Snowball { + pub freeze_duration: u8, + pub range: u8, + pub count: u8, + pub freeze_radius: u8, +} + impl State { pub fn active_worm_index(&self) -> Option { self.my_player @@ -200,6 +216,8 @@ mod test { { "currentRound": 0, "maxRounds": 200, + "pushbackDamage": 20, + "lavaDamage": 3, "mapSize": 33, "currentWormId": 1, "consecutiveDoNothingCount": 0, @@ -229,6 +247,7 @@ mod test { }, "diggingRange": 1, "movementRange": 1, + "roundsUntilUnfrozen": 0, "profession": "Agent" }, { @@ -244,7 +263,30 @@ mod test { }, "diggingRange": 1, "movementRange": 1, + "roundsUntilUnfrozen": 0, "profession": "Commando" + }, + { + "id": 3, + "health": 100, + "position": { + "x": 24, + "y": 4 + }, + "weapon": { + "damage": 8, + "range": 4 + }, + "snowballs": { + "freezeDuration": 5, + "range": 5, + "count": 3, + "freezeRadius": 1 + }, + "diggingRange": 1, + "movementRange": 1, + "roundsUntilUnfrozen": 3, + "profession": "Technologist" } ] }, @@ -254,6 +296,7 @@ mod test { "score": 100, "currentWormId": 3, "remainingWormSelections": 2, + "previousCommand": "nothing", "worms": [ { "id": 1, @@ -264,6 +307,7 @@ mod test { }, "diggingRange": 1, "movementRange": 1, + "roundsUntilUnfrozen": 0, "profession": "Commando" } ] @@ -340,6 +384,8 @@ mod test { let expected = State { current_round: 0, max_rounds: 200, + pushback_damage: 20, + lava_damage: 3, map_size: 33, current_worm_id: 1, consecutive_do_nothing_count: 0, @@ -365,6 +411,8 @@ mod test { count: 3, damage_radius: 2, }), + snowballs: None, + rounds_until_unfrozen: 0, profession: WormType::Agent, }, PlayerWorm { @@ -378,8 +426,30 @@ mod test { digging_range: 1, movement_range: 1, banana_bombs: None, + snowballs: None, + rounds_until_unfrozen: 0, profession: WormType::Commando, }, + PlayerWorm { + id: 3, + health: 100, + position: Position { x: 24, y: 4 }, + weapon: Weapon { + damage: 8, + range: 4, + }, + digging_range: 1, + movement_range: 1, + banana_bombs: None, + snowballs: Some(Snowball { + freeze_duration: 5, + range: 5, + count: 3, + freeze_radius: 1, + }), + rounds_until_unfrozen: 3, + profession: WormType::Technologist, + }, ], }, opponents: vec![Opponent { @@ -387,12 +457,14 @@ mod test { score: 100, remaining_worm_selections: 2, current_worm_id: 3, + previous_command: "nothing".into(), worms: vec![OpponentWorm { id: 1, health: 100, position: Position { x: 31, y: 16 }, digging_range: 1, movement_range: 1, + rounds_until_unfrozen: 0, profession: WormType::Commando, }], }], -- cgit v1.2.3