summaryrefslogtreecommitdiff
path: root/src/state.rs
blob: 8c176e1904657ec50a848b4e7830d92f35a4a25b (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
use json;
use std::collections::HashMap;
use ships::*;

pub struct State {
    pub map_size: u16,
    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 opponent_map_json = json["OpponentMap"];
        let opponent_map = OpponentMap::new(&opponent_map_json, map_size)?;

        Ok(State {
            map_size: map_size,
            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
        }
    }
}