bracket_algorithm_traits/
algorithm2d.rs1use crate::prelude::BaseMap;
17use bracket_geometry::prelude::Point;
18use std::convert::TryInto;
19
20pub trait Algorithm2D: BaseMap {
23 fn point2d_to_index(&self, pt: Point) -> usize {
26 let bounds = self.dimensions();
27 ((pt.y * bounds.x) + pt.x)
28 .try_into()
29 .expect("Not a valid usize. Did something go negative?")
30 }
31
32 fn index_to_point2d(&self, idx: usize) -> Point {
35 let bounds = self.dimensions();
36 let w: usize = bounds
37 .x
38 .try_into()
39 .expect("Not a valid usize. Did something go negative?");
40 Point::new(idx % w, idx / w)
41 }
42
43 fn dimensions(&self) -> Point {
45 panic!("You must either define the dimensions function (trait Algorithm2D) on your map, or define the various point2d_to_index and index_to_point2d functions.");
46 }
47
48 fn in_bounds(&self, pos: Point) -> bool {
52 let bounds = self.dimensions();
53 pos.x >= 0 && pos.x < bounds.x && pos.y >= 0 && pos.y < bounds.y
54 }
55}
56
57#[cfg(test)]
58mod tests {
59 use crate::prelude::{Algorithm2D, BaseMap};
60 use bracket_geometry::prelude::Point;
61
62 #[test]
63 #[should_panic]
65 fn test_unimplemented_dimensions() {
66 struct TestMap {}
67 impl BaseMap for TestMap {}
68 impl Algorithm2D for TestMap {}
69
70 let map = TestMap {};
71 assert!(map.in_bounds(Point::new(1, 1)));
72 }
73
74 #[test]
75 fn test_in_bounds() {
76 struct TestMap {}
77 impl BaseMap for TestMap {}
78 impl Algorithm2D for TestMap {
79 fn dimensions(&self) -> Point {
80 Point::new(2, 2)
81 }
82 }
83
84 let map = TestMap {};
85 assert!(map.in_bounds(Point::new(0, 0)));
86 assert!(map.in_bounds(Point::new(1, 1)));
87 assert!(!map.in_bounds(Point::new(3, 3)));
88 }
89
90 #[test]
91 fn test_point2d_to_index() {
92 struct TestMap {}
93 impl BaseMap for TestMap {}
94 impl Algorithm2D for TestMap {
95 fn dimensions(&self) -> Point {
96 Point::new(10, 10)
97 }
98 }
99
100 let map = TestMap {};
101 assert!(map.point2d_to_index(Point::new(0, 0)) == 0);
102 assert!(map.point2d_to_index(Point::new(1, 0)) == 1);
103 assert!(map.point2d_to_index(Point::new(0, 1)) == 10);
104 assert!(map.point2d_to_index(Point::new(9, 9)) == 99);
105 }
106
107 #[test]
108 fn test_index_to_point2d() {
109 struct TestMap {}
110 impl BaseMap for TestMap {}
111 impl Algorithm2D for TestMap {
112 fn dimensions(&self) -> Point {
113 Point::new(10, 10)
114 }
115 }
116
117 let map = TestMap {};
118 let mut x = 0;
119 let mut y = 0;
120 for i in 0..100 {
121 assert!(map.index_to_point2d(i) == Point::new(x, y));
122
123 x += 1;
124 if x > 9 {
125 x = 0;
126 y += 1;
127 }
128 }
129 }
130}