diff options
Diffstat (limited to 'src/global_json.rs')
-rw-r--r-- | src/global_json.rs | 162 |
1 files changed, 162 insertions, 0 deletions
diff --git a/src/global_json.rs b/src/global_json.rs new file mode 100644 index 0000000..a27cd00 --- /dev/null +++ b/src/global_json.rs @@ -0,0 +1,162 @@ +use std::fs::File; +use std::io::prelude::*; + +use anyhow::Result; +use serde::{Deserialize, Serialize}; +use serde_json; +use serde_repr::{Deserialize_repr, Serialize_repr}; + +use crate::state::*; + +pub fn read_initial_state_from_global_json_file(filename: &str) -> Result<GameState> { + let mut state = read_state_from_global_json_file(filename)?; + state.reset_players_to_start(); + Ok(state) +} + +pub fn read_state_from_global_json_file(filename: &str) -> Result<GameState> { + let mut file = File::open(filename)?; + let mut content = String::new(); + file.read_to_string(&mut content)?; + 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 JsonState { + // pub current_round: usize, + // pub max_rounds: usize, + pub players: [JsonPlayer; 2], + pub blocks: Vec<JsonBlock>, +} + +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq)] +#[serde(rename_all = "camelCase")] +pub struct JsonPlayer { + // id: usize, + position: JsonPosition, + speed: usize, + // state: JsonPlayerState, + powerups: Vec<JsonPowerup>, + // boosting: bool, + boost_counter: usize, +} + +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq)] +#[serde(rename_all = "camelCase")] +pub struct JsonBlock { + position: JsonPosition, + surface_object: JsonSurfaceObject, + // occupied_by_player_id: usize, +} + +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq)] +#[serde(rename_all = "camelCase")] +pub struct JsonPosition { + block_number: usize, + lane: usize, +} + +// #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq)] +// #[serde(rename_all = "SCREAMING_SNAKE_CASE")] +// pub enum JsonPlayerState { +// Ready, +// Nothing, +// TurningLeft, +// TurningRight, +// Accelerating, +// Decelarating, +// PickedUpPowerup, +// UsedBoost, +// UsedOil, +// HitMud, +// HitOil, +// Finishing, +// } + +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq)] +#[serde(rename_all = "SCREAMING_SNAKE_CASE")] +pub enum JsonPowerup { + Boost, + Oil, +} + +#[derive(Serialize_repr, Deserialize_repr, Clone, Debug, PartialEq, Eq)] +#[serde(rename_all = "camelCase")] +#[repr(u8)] +pub enum JsonSurfaceObject { + Empty = 0, + Mud = 1, + OilSpill = 2, + OilItem = 3, + FinishLine = 4, + Boost = 5, +} + +impl JsonState { + fn to_game_state(&self) -> GameState { + GameState { + status: GameStatus::Continue, + players: [self.players[0].to_player(), self.players[1].to_player()], + obstacles: self + .blocks + .iter() + .filter(|cell| { + cell.surface_object == JsonSurfaceObject::Mud + || cell.surface_object == JsonSurfaceObject::OilSpill + }) + .map(|cell| cell.position.to_position()) + .collect(), + powerup_oils: self + .blocks + .iter() + .filter(|cell| cell.surface_object == JsonSurfaceObject::OilItem) + .map(|cell| cell.position.to_position()) + .collect(), + powerup_boosts: self + .blocks + .iter() + .filter(|cell| cell.surface_object == JsonSurfaceObject::Boost) + .map(|cell| cell.position.to_position()) + .collect(), + finish_lines: self + .blocks + .iter() + .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 JsonPosition { + fn to_position(&self) -> Position { + Position { + x: self.block_number, + y: self.lane, + } + } +} |