diff options
author | Justin Wernick <justin@worthe-it.co.za> | 2022-04-19 21:27:56 +0200 |
---|---|---|
committer | Justin Wernick <justin@worthe-it.co.za> | 2022-04-19 21:27:56 +0200 |
commit | 3f5492b2bb67326be43cd7c5ba02ccf0ba1ae0e3 (patch) | |
tree | 96963ba885a9393106b4a88ffc4266203e87582e /src/json.rs | |
parent | 4ceec65b088f05d4ad03f9ac70b1d63452fd8197 (diff) |
Refile for merging repos
Diffstat (limited to 'src/json.rs')
-rw-r--r-- | src/json.rs | 554 |
1 files changed, 0 insertions, 554 deletions
diff --git a/src/json.rs b/src/json.rs deleted file mode 100644 index a83f102..0000000 --- a/src/json.rs +++ /dev/null @@ -1,554 +0,0 @@ -use std::error::Error; -use std::fs::File; -use std::io::prelude::*; -use std::path::Path; - -use serde::{Deserialize, Serialize}; -use serde_json; - -pub fn read_state_from_json_file(filename: &Path) -> Result<State, Box<dyn Error>> { - let mut file = File::open(filename)?; - let mut content = String::new(); - file.read_to_string(&mut content)?; - let state: State = serde_json::from_str(content.as_ref())?; - - Ok(state) -} - -// TODO: Narrow numeric types -// TODO: comment out stuff I don't want / need - -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq)] -#[serde(rename_all = "camelCase")] -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, - pub my_player: Player, - pub opponents: Vec<Opponent>, - pub map: Vec<Vec<Cell>>, -} - -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq)] -#[serde(rename_all = "camelCase")] -pub struct Player { - pub id: i32, - pub score: i32, - pub health: i32, - pub worms: Vec<PlayerWorm>, - pub remaining_worm_selections: u8, -} - -impl Player { - pub fn health_score(&self) -> i32 { - self.health / 3 - } -} - -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq)] -#[serde(rename_all = "camelCase")] -pub struct PlayerWorm { - pub id: i32, - pub health: i32, - pub position: Position, - pub digging_range: u32, - pub movement_range: u32, - pub rounds_until_unfrozen: u8, - pub weapon: Weapon, - pub banana_bombs: Option<Bomb>, - pub snowballs: Option<Snowball>, - pub profession: WormType, -} - -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq)] -#[serde(rename_all = "camelCase")] -pub struct Opponent { - pub id: i32, - pub score: i32, - pub current_worm_id: i32, - pub previous_command: String, - pub worms: Vec<OpponentWorm>, - pub remaining_worm_selections: u8, -} - -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 { - pub id: i32, - pub health: i32, - pub position: Position, - pub digging_range: u32, - pub movement_range: u32, - pub rounds_until_unfrozen: u8, - pub profession: WormType, -} - -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq)] -#[serde(rename_all = "PascalCase")] -pub enum WormType { - Commando, - Agent, - Technologist, -} - -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq)] -#[serde(rename_all = "camelCase")] -pub struct Cell { - pub x: i8, - pub y: i8, - #[serde(rename = "type")] - pub cell_type: CellType, - pub occupier: Option<CellWorm>, - pub powerup: Option<Powerup>, -} - -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq)] -#[serde(rename_all = "SCREAMING_SNAKE_CASE")] -pub enum CellType { - Air, - Dirt, - Lava, - DeepSpace, -} - -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq)] -#[serde(untagged)] -#[serde(rename_all = "camelCase")] -pub enum CellWorm { - #[serde(rename_all = "camelCase")] - PlayerWorm { - id: i32, - player_id: i32, - health: i32, - position: Position, - digging_range: u32, - movement_range: u32, - weapon: Weapon, - }, - #[serde(rename_all = "camelCase")] - OpponentWorm { - id: i32, - player_id: i32, - health: i32, - position: Position, - digging_range: u32, - movement_range: u32, - }, -} - -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq)] -#[serde(rename_all = "camelCase")] -pub struct Powerup { - #[serde(rename = "type")] - pub powerup_type: PowerupType, - pub value: i32, -} - -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq)] -#[serde(rename_all = "SCREAMING_SNAKE_CASE")] -pub enum PowerupType { - HealthPack, -} - -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq)] -#[serde(rename_all = "camelCase")] -pub struct Position { - pub x: i8, - pub y: i8, -} - -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq)] -#[serde(rename_all = "camelCase")] -pub struct Weapon { - pub damage: i32, - pub range: u8, -} - -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq)] -#[serde(rename_all = "camelCase")] -pub struct Bomb { - pub damage: i32, - pub range: u8, - pub count: u8, - 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<usize> { - self.my_player - .worms - .iter() - .filter(|w| w.health > 0) - .position(|w| w.id == self.current_worm_id) - } - - pub fn opponent_active_worm_index(&self) -> Option<usize> { - self.opponents[0] - .worms - .iter() - .filter(|w| w.health > 0) - .position(|w| w.id == self.opponents[0].current_worm_id) - } -} - -#[cfg(test)] -mod test { - use super::*; - - #[test] - fn example_parses_correctly() { - let example = r#" -{ - "currentRound": 0, - "maxRounds": 200, - "pushbackDamage": 20, - "lavaDamage": 3, - "mapSize": 33, - "currentWormId": 1, - "consecutiveDoNothingCount": 0, - "myPlayer": { - "id": 1, - "score": 100, - "health": 300, - "currentWormId": 1, - "remainingWormSelections": 1, - "worms": [ - { - "id": 1, - "health": 100, - "position": { - "x": 24, - "y": 29 - }, - "weapon": { - "damage": 1, - "range": 3 - }, - "bananaBombs": { - "damage": 20, - "range": 5, - "count": 3, - "damageRadius": 2 - }, - "diggingRange": 1, - "movementRange": 1, - "roundsUntilUnfrozen": 0, - "profession": "Agent" - }, - { - "id": 2, - "health": 150, - "position": { - "x": 1, - "y": 16 - }, - "weapon": { - "damage": 1, - "range": 3 - }, - "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" - } - ] - }, - "opponents": [ - { - "id": 2, - "score": 100, - "currentWormId": 3, - "remainingWormSelections": 2, - "previousCommand": "nothing", - "worms": [ - { - "id": 1, - "health": 100, - "position": { - "x": 31, - "y": 16 - }, - "diggingRange": 1, - "movementRange": 1, - "roundsUntilUnfrozen": 0, - "profession": "Commando" - } - ] - } - ], - "map": [ - [ - { - "x": 0, - "y": 0, - "type": "DEEP_SPACE" - }, - { - "x": 1, - "y": 0, - "type": "AIR" - }, - { - "x": 2, - "y": 0, - "type": "DIRT" - } - ], - [ - { - "x": 0, - "y": 1, - "type": "AIR", - "powerup": { - "type": "HEALTH_PACK", - "value": 5 - } - }, - { - "x": 1, - "y": 1, - "type": "AIR", - "occupier": { - "id": 1, - "playerId": 2, - "health": 100, - "position": { - "x": 1, - "y": 1 - }, - "diggingRange": 1, - "movementRange": 1 - } - }, - { - "x": 2, - "y": 1, - "type": "AIR", - "occupier": { - "id": 1, - "playerId": 1, - "health": 100, - "position": { - "x": 2, - "y": 1 - }, - "weapon": { - "damage": 1, - "range": 3 - }, - "diggingRange": 1, - "movementRange": 1 - } - } - ] - ] -}"#; - - 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, - my_player: Player { - id: 1, - score: 100, - health: 300, - remaining_worm_selections: 1, - worms: vec![ - PlayerWorm { - id: 1, - health: 100, - position: Position { x: 24, y: 29 }, - weapon: Weapon { - damage: 1, - range: 3, - }, - digging_range: 1, - movement_range: 1, - banana_bombs: Some(Bomb { - damage: 20, - range: 5, - count: 3, - damage_radius: 2, - }), - snowballs: None, - rounds_until_unfrozen: 0, - profession: WormType::Agent, - }, - PlayerWorm { - id: 2, - health: 150, - position: Position { x: 1, y: 16 }, - weapon: Weapon { - damage: 1, - range: 3, - }, - 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 { - id: 2, - 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, - }], - }], - map: vec![ - vec![ - Cell { - x: 0, - y: 0, - cell_type: CellType::DeepSpace, - occupier: None, - powerup: None, - }, - Cell { - x: 1, - y: 0, - cell_type: CellType::Air, - occupier: None, - powerup: None, - }, - Cell { - x: 2, - y: 0, - cell_type: CellType::Dirt, - occupier: None, - powerup: None, - }, - ], - vec![ - Cell { - x: 0, - y: 1, - cell_type: CellType::Air, - occupier: None, - powerup: Some(Powerup { - powerup_type: PowerupType::HealthPack, - value: 5, - }), - }, - Cell { - x: 1, - y: 1, - cell_type: CellType::Air, - occupier: Some(CellWorm::OpponentWorm { - id: 1, - player_id: 2, - health: 100, - position: Position { x: 1, y: 1 }, - digging_range: 1, - movement_range: 1, - }), - powerup: None, - }, - Cell { - x: 2, - y: 1, - cell_type: CellType::Air, - occupier: Some(CellWorm::PlayerWorm { - id: 1, - player_id: 1, - health: 100, - position: Position { x: 2, y: 1 }, - digging_range: 1, - movement_range: 1, - weapon: Weapon { - damage: 1, - range: 3, - }, - }), - powerup: None, - }, - ], - ], - }; - - let parsed: State = serde_json::from_str(example).unwrap(); - - assert_eq!( - parsed, expected, - "Parsed value did not match the expected value.\nParsed = {:#?}\nExpected = {:#?}", - parsed, expected - ); - } -} |