From f3f798441e56afec9e6357c96274f90bf4ea6947 Mon Sep 17 00:00:00 2001 From: Justin Wernick Date: Fri, 10 Apr 2020 23:17:35 +0200 Subject: Game state from JSON state --- src/json.rs | 149 ++++++++++++++++++++++++++++++++++++++++++++++------------- src/main.rs | 9 ++-- src/state.rs | 30 ++++++------ 3 files changed, 138 insertions(+), 50 deletions(-) diff --git a/src/json.rs b/src/json.rs index 55173bd..79f20e9 100644 --- a/src/json.rs +++ b/src/json.rs @@ -6,63 +6,64 @@ use serde::{Deserialize, Serialize}; use serde_json; use serde_repr::{Deserialize_repr, Serialize_repr}; -pub fn read_state_from_json_file(filename: &str) -> Result { +use crate::state::*; + +pub fn read_state_from_json_file(filename: &str) -> Result { 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) + let json_state: JsonState = serde_json::from_str(content.as_ref())?; + Ok(json_state.to_game_state()) } #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq)] #[serde(rename_all = "camelCase")] -pub struct State { - pub current_round: u32, - pub max_rounds: u32, - pub player: Player, - pub opponent: Opponent, - pub world_map: Vec>, +pub struct JsonState { + pub current_round: usize, + pub max_rounds: usize, + pub player: JsonPlayer, + pub opponent: JsonOpponent, + pub world_map: Vec>, } #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq)] #[serde(rename_all = "camelCase")] -pub struct Player { - id: u32, - position: Position, - speed: u32, - state: PlayerState, - powerups: Vec, +pub struct JsonPlayer { + id: usize, + position: JsonPosition, + speed: usize, + state: JsonPlayerState, + powerups: Vec, boosting: bool, - boost_counter: u32, + boost_counter: usize, } #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq)] #[serde(rename_all = "camelCase")] -pub struct Opponent { - id: u32, - position: Position, - speed: u32, +pub struct JsonOpponent { + id: usize, + position: JsonPosition, + speed: usize, } #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq)] #[serde(rename_all = "camelCase")] -pub struct WorldMapCell { - position: Position, - surface_object: SurfaceObject, - occupied_by_player_id: u32, +pub struct JsonWorldMapCell { + position: JsonPosition, + surface_object: JsonSurfaceObject, + occupied_by_player_id: usize, } #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq)] #[serde(rename_all = "camelCase")] -pub struct Position { - x: u32, - y: u32, +pub struct JsonPosition { + x: usize, + y: usize, } #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq)] #[serde(rename_all = "SCREAMING_SNAKE_CASE")] -pub enum PlayerState { +pub enum JsonPlayerState { Ready, Nothing, TurningLeft, @@ -78,7 +79,7 @@ pub enum PlayerState { #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq)] #[serde(rename_all = "SCREAMING_SNAKE_CASE")] -pub enum Powerup { +pub enum JsonPowerup { Boost, Oil, } @@ -86,7 +87,7 @@ pub enum Powerup { #[derive(Serialize_repr, Deserialize_repr, Clone, Debug, PartialEq, Eq)] #[serde(rename_all = "camelCase")] #[repr(u8)] -pub enum SurfaceObject { +pub enum JsonSurfaceObject { Empty = 0, Mud = 1, OilSpill = 2, @@ -94,3 +95,89 @@ pub enum SurfaceObject { FinishLine = 4, Boost = 5, } + +impl JsonState { + fn to_game_state(&self) -> GameState { + GameState { + status: GameStatus::Continue, + players: [self.player.to_player(), self.opponent.to_player()], + obstacles: self + .world_map + .iter() + .flatten() + .filter(|cell| { + cell.surface_object == JsonSurfaceObject::Mud + || cell.surface_object == JsonSurfaceObject::OilSpill + }) + .map(|cell| cell.position.to_position()) + .collect(), + powerup_oils: self + .world_map + .iter() + .flatten() + .filter(|cell| cell.surface_object == JsonSurfaceObject::OilItem) + .map(|cell| cell.position.to_position()) + .collect(), + powerup_boosts: self + .world_map + .iter() + .flatten() + .filter(|cell| cell.surface_object == JsonSurfaceObject::Boost) + .map(|cell| cell.position.to_position()) + .collect(), + finish_lines: self + .world_map + .iter() + .flatten() + .filter(|cell| cell.surface_object == JsonSurfaceObject::FinishLine) + .map(|cell| cell.position.to_position()) + .collect(), + } + } +} + +impl JsonPlayer { + fn to_player(&self) -> Player { + Player { + position: self.position.to_position(), + next_position: self.position.to_position(), + speed: self.speed, + boost_remaining: self.boost_counter, + oils: self + .powerups + .iter() + .filter(|powerup| **powerup == JsonPowerup::Oil) + .count(), + boosts: self + .powerups + .iter() + .filter(|powerup| **powerup == JsonPowerup::Boost) + .count(), + finished: false, + } + } +} + +impl JsonOpponent { + // TODO: Track opponent powerups from round to round? + fn to_player(&self) -> Player { + Player { + position: self.position.to_position(), + next_position: self.position.to_position(), + speed: self.speed, + boost_remaining: 0, + oils: 0, + boosts: 0, + finished: false, + } + } +} + +impl JsonPosition { + fn to_position(&self) -> Position { + Position { + x: self.x, + y: self.y, + } + } +} diff --git a/src/main.rs b/src/main.rs index 81bc3b4..74428c3 100644 --- a/src/main.rs +++ b/src/main.rs @@ -7,14 +7,15 @@ mod json; mod state; use command::*; -use json::*; +use state::*; fn main() { for line in stdin().lock().lines() { let round_number = line.expect("Failed to read line from stdin: {}"); let command = - match read_state_from_json_file(&format!("./rounds/{}/state.json", round_number)) { - Ok(state) => choose_command(state), + match json::read_state_from_json_file(&format!("./rounds/{}/state.json", round_number)) + { + Ok(state) => choose_command(&state), Err(e) => { eprintln!("WARN: State file could not be parsed: {}", e); Command::Nothing @@ -24,6 +25,6 @@ fn main() { } } -fn choose_command(state: State) -> Command { +fn choose_command(state: &GameState) -> Command { Command::Accelerate } diff --git a/src/state.rs b/src/state.rs index 45e39eb..1dfa21d 100644 --- a/src/state.rs +++ b/src/state.rs @@ -9,28 +9,28 @@ pub enum GameStatus { } pub struct GameState { - status: GameStatus, - players: [Player; 2], - obstacles: Vec, - powerup_oils: Vec, - powerup_boosts: Vec, - finish_lines: Vec, + pub status: GameStatus, + pub players: [Player; 2], + pub obstacles: Vec, + pub powerup_oils: Vec, + pub powerup_boosts: Vec, + pub finish_lines: Vec, } pub struct Player { - position: Position, - next_position: Position, - speed: usize, - boost_remaining: usize, - oils: usize, - boosts: usize, - finished: bool, + pub position: Position, + pub next_position: Position, + pub speed: usize, + pub boost_remaining: usize, + pub oils: usize, + pub boosts: usize, + pub finished: bool, } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct Position { - x: usize, - y: usize, + pub x: usize, + pub y: usize, } impl GameState { -- cgit v1.2.3