diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/command.rs | 2 | ||||
-rw-r--r-- | src/global_json.rs | 162 | ||||
-rw-r--r-- | src/lib.rs | 1 | ||||
-rw-r--r-- | src/state.rs | 20 |
4 files changed, 180 insertions, 5 deletions
diff --git a/src/command.rs b/src/command.rs index f95ef98..1858202 100644 --- a/src/command.rs +++ b/src/command.rs @@ -1,6 +1,6 @@ use std::fmt; -#[derive(Clone, Copy, Debug, PartialEq, Eq)] +#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq)] pub enum Command { Nothing, Accelerate, 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, + } + } +} @@ -1,5 +1,6 @@ pub mod command; pub mod consts; +pub mod global_json; pub mod json; pub mod state; diff --git a/src/state.rs b/src/state.rs index e05a884..177db45 100644 --- a/src/state.rs +++ b/src/state.rs @@ -1,7 +1,7 @@ use crate::command::Command; use crate::consts::*; -#[derive(Debug, Clone, Copy, PartialEq, Eq)] +#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq)] pub enum GameStatus { Continue, PlayerOneWon, @@ -9,7 +9,7 @@ pub enum GameStatus { Draw, // Until I add score I guess } -#[derive(Debug, Clone, PartialEq, Eq)] +#[derive(Debug, Clone, Hash, PartialEq, Eq)] pub struct GameState { pub status: GameStatus, pub players: [Player; 2], @@ -19,7 +19,7 @@ pub struct GameState { pub finish_lines: Vec<Position>, } -#[derive(Debug, Clone, PartialEq, Eq)] +#[derive(Debug, Clone, Hash, PartialEq, Eq)] pub struct Player { pub position: Position, pub next_position: Position, @@ -30,7 +30,7 @@ pub struct Player { pub finished: bool, } -#[derive(Debug, Clone, Copy, PartialEq, Eq)] +#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq)] pub struct Position { pub x: usize, pub y: usize, @@ -64,6 +64,18 @@ impl GameState { }; } + pub fn reset_players_to_start(&mut self) { + self.players[0].position = Position { x: 1, y: 1 }; + self.players[1].position = Position { x: 1, y: 4 }; + for player in &mut self.players { + player.speed = 5; + player.boost_remaining = 0; + player.oils = 0; + player.boosts = 0; + player.finished = false; + } + } + fn do_command(&mut self, player_index: usize, command: &Command) { use Command::*; self.players[player_index].tick_boost(); |