summaryrefslogtreecommitdiff
path: root/2017-battleships/src/state.rs
diff options
context:
space:
mode:
Diffstat (limited to '2017-battleships/src/state.rs')
-rw-r--r--2017-battleships/src/state.rs146
1 files changed, 146 insertions, 0 deletions
diff --git a/2017-battleships/src/state.rs b/2017-battleships/src/state.rs
new file mode 100644
index 0000000..1756ad0
--- /dev/null
+++ b/2017-battleships/src/state.rs
@@ -0,0 +1,146 @@
+use json;
+use std::collections::HashMap;
+use ships::*;
+
+pub struct State {
+ pub map_size: u16,
+ pub player_map: PlayerMap,
+ pub opponent_map: OpponentMap
+}
+
+impl State {
+ pub fn new(json: &json::JsonValue) -> Result<State, String> {
+ let map_size = State::map_size_from_json(&json)?;
+
+ let ref player_map_json = json["PlayerMap"];
+ let player_map = PlayerMap::new(&player_map_json)?;
+
+ let ref opponent_map_json = json["OpponentMap"];
+ let opponent_map = OpponentMap::new(&opponent_map_json, map_size)?;
+
+ Ok(State {
+ map_size: map_size,
+ player_map: player_map,
+ opponent_map: opponent_map
+ })
+ }
+
+ pub fn map_size_from_json(json: &json::JsonValue) -> Result<u16, String> {
+ json["MapDimension"]
+ .as_u16()
+ .ok_or(String::from("Did not find the map dimension in the state json file"))
+ }
+}
+
+pub struct OpponentMap {
+ pub cells: Vec<Vec<Cell>>,
+ pub ships: HashMap<Ship, OpponentShip>,
+}
+
+impl OpponentMap {
+ fn new(json: &json::JsonValue, map_size: u16) -> Result<OpponentMap, String> {
+ let mut cells = Vec::with_capacity(map_size as usize);
+ for _ in 0..map_size {
+ let mut row = Vec::with_capacity(map_size as usize);
+ for _ in 0..map_size {
+ row.push(Cell::new());
+ }
+ cells.push(row);
+ }
+
+ for json_cell in json["Cells"].members() {
+ let x = json_cell["X"]
+ .as_u16()
+ .ok_or(String::from("Failed to read X value of opponent map cell in json file"))?;
+ let y = json_cell["Y"]
+ .as_u16()
+ .ok_or(String::from("Failed to read Y value of opponent map cell in json file"))?;
+ let damaged = json_cell["Damaged"]
+ .as_bool()
+ .ok_or(String::from("Failed to read Damaged value of opponent map cell in json file"))?;
+ let missed = json_cell["Missed"]
+ .as_bool()
+ .ok_or(String::from("Failed to read Missed value of opponent map cell in json file"))?;
+
+ cells[x as usize][y as usize].damaged = damaged;
+ cells[x as usize][y as usize].missed = missed;
+ }
+
+ let mut ships = HashMap::new();
+ for json_ship in json["Ships"].members() {
+ let ship_type_string = json_ship["ShipType"]
+ .as_str()
+ .ok_or(String::from("Failed to read ShipType value of opponent map ship in json file"))?;
+ let ship_type = ship_type_string.parse::<Ship>()?;
+
+ let destroyed = json_ship["Destroyed"]
+ .as_bool()
+ .ok_or(String::from("Failed to read Destroyed value of opponent map ship in json file"))?;
+ ships.insert(ship_type, OpponentShip {
+ destroyed: destroyed
+ });
+ }
+
+
+ Ok(OpponentMap {
+ cells: cells,
+ ships: ships
+ })
+ }
+}
+
+pub struct OpponentShip {
+ pub destroyed: bool
+}
+
+pub struct Cell {
+ pub damaged: bool,
+ pub missed: bool
+}
+
+impl Cell {
+ fn new() -> Cell {
+ Cell {
+ damaged: false,
+ missed: false
+ }
+ }
+}
+
+pub struct PlayerMap {
+ pub ships: HashMap<Ship, PlayerShip>,
+ pub energy: u16
+}
+
+impl PlayerMap {
+ fn new(json: &json::JsonValue) -> Result<PlayerMap, String> {
+ let mut ships = HashMap::new();
+ for json_ship in json["Owner"]["Ships"].members() {
+ let ship_type_string = json_ship["ShipType"]
+ .as_str()
+ .ok_or(String::from("Failed to read ShipType value of player map ship in json file"))?;
+ let ship_type = ship_type_string.parse::<Ship>()?;
+
+ let destroyed = json_ship["Destroyed"]
+ .as_bool()
+ .ok_or(String::from("Failed to read Destroyed value of player map ship in json file"))?;
+ ships.insert(ship_type, PlayerShip {
+ destroyed: destroyed
+ });
+ }
+
+ let energy = json["Owner"]["Energy"]
+ .as_u16()
+ .ok_or(String::from("Did not find the energy in the state json file"))?;
+
+ Ok(PlayerMap {
+ ships: ships,
+ energy: energy
+ })
+ }
+}
+
+
+pub struct PlayerShip {
+ pub destroyed: bool
+}