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 { 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 { 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>, pub ships: HashMap, } impl OpponentMap { fn new(json: &json::JsonValue, map_size: u16) -> Result { 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::()?; 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, pub energy: u16 } impl PlayerMap { fn new(json: &json::JsonValue) -> Result { 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::()?; 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 }