summaryrefslogtreecommitdiff
path: root/src/state.rs
blob: 1756ad01ce248b37a88ef11df3e7077757826ed1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
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
}