grid_map/loc/
neighbor_square.rs1use crate::{Dim, Dir, Loc, Scale};
2
3impl Loc {
4 pub fn neighbor(self, dir: Dir, dims: Dim) -> Option<Loc> {
8 match dir {
9 Dir::North => {
10 if self.y > 0 {
11 Some(Loc::new(self.x, self.y - 1))
12 } else {
13 None
14 }
15 }
16 Dir::East => {
17 let x: Scale = self.x + 1;
18 if x < dims.w {
19 Some(Loc::new(x, self.y))
20 } else {
21 None
22 }
23 }
24 Dir::South => {
25 let y: Scale = self.y + 1;
26 if y < dims.h {
27 Some(Loc::new(self.x, y))
28 } else {
29 None
30 }
31 }
32 Dir::West => {
33 if self.x > 0 {
34 Some(Loc::new(self.x - 1, self.y))
35 } else {
36 None
37 }
38 }
39 }
40 }
41
42 pub fn neighbor_unchecked(self, dir: Dir) -> Loc {
44 match dir {
45 Dir::North => Loc::new(self.x, self.y - 1),
46 Dir::East => Loc::new(self.x + 1, self.y),
47 Dir::South => Loc::new(self.x, self.y + 1),
48 Dir::West => Loc::new(self.x - 1, self.y),
49 }
50 }
51}
52
53#[cfg(test)]
54mod tests {
55 use crate::{Dim, Dir, Loc};
56
57 #[test]
58 fn neighbor_center() {
59 let dims: Dim = Dim::new(3, 3);
60 let loc: Loc = Loc::new(1, 1);
61 assert_eq!(loc.neighbor(Dir::North, dims), Some(Loc::new(1, 0)));
62 assert_eq!(loc.neighbor(Dir::East, dims), Some(Loc::new(2, 1)));
63 assert_eq!(loc.neighbor(Dir::South, dims), Some(Loc::new(1, 2)));
64 assert_eq!(loc.neighbor(Dir::West, dims), Some(Loc::new(0, 1)));
65 }
66
67 #[test]
68 fn neighbor_top_left_corner() {
69 let dims: Dim = Dim::new(3, 3);
70 let loc: Loc = Loc::new(0, 0);
71 assert_eq!(loc.neighbor(Dir::North, dims), None);
72 assert_eq!(loc.neighbor(Dir::West, dims), None);
73 assert_eq!(loc.neighbor(Dir::East, dims), Some(Loc::new(1, 0)));
74 assert_eq!(loc.neighbor(Dir::South, dims), Some(Loc::new(0, 1)));
75 }
76
77 #[test]
78 fn neighbor_bottom_right_corner() {
79 let dims: Dim = Dim::new(3, 3);
80 let loc: Loc = Loc::new(2, 2);
81 assert_eq!(loc.neighbor(Dir::East, dims), None);
82 assert_eq!(loc.neighbor(Dir::South, dims), None);
83 assert_eq!(loc.neighbor(Dir::North, dims), Some(Loc::new(2, 1)));
84 assert_eq!(loc.neighbor(Dir::West, dims), Some(Loc::new(1, 2)));
85 }
86
87 #[test]
88 fn neighbor_unchecked_matches_neighbor() {
89 let dims: Dim = Dim::new(5, 5);
90 let loc: Loc = Loc::new(2, 2);
91 for dir in Dir::ALL {
92 assert_eq!(
93 loc.neighbor(dir, dims).unwrap(),
94 loc.neighbor_unchecked(dir),
95 );
96 }
97 }
98
99 #[test]
100 fn neighbor_opposite_roundtrip() {
101 let loc: Loc = Loc::new(2, 2);
102 for dir in Dir::ALL {
103 let n: Loc = loc.neighbor_unchecked(dir);
104 assert_eq!(n.neighbor_unchecked(dir.opposite()), loc);
105 }
106 }
107}