summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/command.rs2
-rw-r--r--src/global_json.rs162
-rw-r--r--src/lib.rs1
-rw-r--r--src/state.rs20
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,
+ }
+ }
+}
diff --git a/src/lib.rs b/src/lib.rs
index 902cb73..ac73f72 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -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();