summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJustin Wernick <justin@worthe-it.co.za>2020-04-10 23:17:35 +0200
committerJustin Wernick <justin@worthe-it.co.za>2020-04-10 23:17:35 +0200
commitf3f798441e56afec9e6357c96274f90bf4ea6947 (patch)
treeab65f01f4757059c2ab1d3f0c21b9c6a625f0763
parent124c89cdeadc53457b016c9f8aa1ba3c4a1aa15d (diff)
Game state from JSON state
-rw-r--r--src/json.rs149
-rw-r--r--src/main.rs9
-rw-r--r--src/state.rs30
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<State> {
+use crate::state::*;
+
+pub fn read_state_from_json_file(filename: &str) -> Result<GameState> {
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<Vec<WorldMapCell>>,
+pub struct JsonState {
+ pub current_round: usize,
+ pub max_rounds: usize,
+ pub player: JsonPlayer,
+ pub opponent: JsonOpponent,
+ pub world_map: Vec<Vec<JsonWorldMapCell>>,
}
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq)]
#[serde(rename_all = "camelCase")]
-pub struct Player {
- id: u32,
- position: Position,
- speed: u32,
- state: PlayerState,
- powerups: Vec<Powerup>,
+pub struct JsonPlayer {
+ id: usize,
+ position: JsonPosition,
+ speed: usize,
+ state: JsonPlayerState,
+ powerups: Vec<JsonPowerup>,
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<Position>,
- powerup_oils: Vec<Position>,
- powerup_boosts: Vec<Position>,
- finish_lines: Vec<Position>,
+ pub status: GameStatus,
+ pub players: [Player; 2],
+ pub obstacles: Vec<Position>,
+ pub powerup_oils: Vec<Position>,
+ pub powerup_boosts: Vec<Position>,
+ pub finish_lines: Vec<Position>,
}
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 {