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
}
|