summaryrefslogtreecommitdiff
path: root/src/global_json.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/global_json.rs')
-rw-r--r--src/global_json.rs162
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,
+ }
+ }
+}