Implement these for handling conversion to/from 2D coordinates (they are separate, because you might want Dwarf Fortress style 3D!)
| 20 | /// Implement these for handling conversion to/from 2D coordinates (they are separate, because you might |
| 21 | /// want Dwarf Fortress style 3D!) |
| 22 | pub trait Algorithm2D: BaseMap { |
| 23 | /// Convert a Point (x/y) to an array index. Defaults to an index based on an array |
| 24 | /// strided X first. |
| 25 | 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 | /// Convert an array index to a point. Defaults to an index based on an array |
| 33 | /// strided X first. |
| 34 | 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 | /// Retrieve the map's dimensions. Made optional to reduce API breakage. |
| 44 | 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 | // Optional - check that an x/y coordinate is within the map bounds. If not provided, |
| 49 | // it falls back to using the map's dimensions from that trait implementation. Most of |
| 50 | // the time, that's what you want. |
| 51 | 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)] |
| 58 | mod tests { |
no outgoing calls
no test coverage detected