summaryrefslogtreecommitdiff
path: root/src/game/map.rs
blob: c062c8fa92feb43536c7fd6b414e83a7c0a1a7f4 (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
use crate::geometry::*;
use crate::constants::*;

#[derive(Default, Debug, PartialEq, Eq, Clone)]
pub struct Map {
    cells: [u64; MAP_U64S]
}

impl Map {
    pub fn at(&self, p: Point2d<i8>) -> Option<bool> {
        if p.y < 0 || p.y as usize >= MAP_SIZE {
            None
        } else {
            let row_data = &MAP_ROW_SIZE[p.y as usize];
            if p.x < row_data.x_offset as i8 || p.x as usize >= row_data.x_offset + row_data.len() {
                None
            } else {
                let global_bit = row_data.start_bit + p.x as usize - row_data.x_offset;
                let integer = global_bit / 64;
                let bit = global_bit % 64;
                let mask = 1 << bit;
                Some(self.cells[integer] & mask != 0)
            }
        }
    }

    pub fn set(&mut self, p: Point2d<i8>) {
        if p.y < 0 || p.y as usize >= MAP_SIZE {
            debug_assert!(false, "Tried to set an out of bounds bit, {:?}", p);
        } else {
            let row_data = &MAP_ROW_SIZE[p.y as usize];
            if p.x < row_data.x_offset as i8 || p.x as usize >= row_data.x_offset + row_data.len() {
                debug_assert!(false, "Tried to set an out of bounds bit, {:?}", p);
            } else {
                let global_bit = row_data.start_bit + p.x as usize - row_data.x_offset;
                let integer = global_bit / 64;
                let bit = global_bit % 64;
                let mask = 1 << bit;
                self.cells[integer] |= mask;
            }
        }
    }
    pub fn clear(&mut self, p: Point2d<i8>) {
        if p.y < 0 || p.y as usize >= MAP_SIZE {
            debug_assert!(false, "Tried to set an out of bounds bit, {:?}", p);
        } else {
            let row_data = &MAP_ROW_SIZE[p.y as usize];
            if p.x < row_data.x_offset as i8 || p.x as usize >= row_data.x_offset + row_data.len() {
                debug_assert!(false, "Tried to set an out of bounds bit, {:?}", p);
            } else {
                let global_bit = row_data.start_bit + p.x as usize - row_data.x_offset;
                let integer = global_bit / 64;
                let bit = global_bit % 64;
                let mask = !(1 << bit);
                self.cells[integer] &= mask;
            }
        }
    }
}

#[cfg(test)]
mod test {
    // TODO: Property test for at, set and clear
}