hexagon_map/sparse_map/
mod.rs

1use crate::{CubicPoint, HPoint, IsometricLine, Joint, Orientation, WPoint};
2use itertools::Itertools;
3use std::{cmp::Ordering, collections::BTreeMap};
4pub mod action_field;
5pub mod iters;
6pub mod path_finder;
7
8/// A sparse hexagon map, if your map size will grow, or most areas will be blank, this is a better choice.
9pub struct HexagonMap<T> {
10    sparse: BTreeMap<CubicPoint, T>,
11}
12
13impl<T: Default> HexagonMap<T> {
14    pub fn circle(diameter: usize) -> Self {
15        let mut map = BTreeMap::new();
16        for x in 0..diameter {
17            for y in 0..diameter {
18                let point = CubicPoint::new(x as isize, y as isize);
19                map.insert(point, Default::default());
20            }
21        }
22        Self { sparse: map }
23    }
24    pub fn rhombus(width: usize, height: usize) -> Self {
25        let mut map = BTreeMap::new();
26        for x in 0..width {
27            for y in 0..height {
28                map.insert(CubicPoint::new(x as isize, y as isize), Default::default());
29            }
30        }
31        Self { sparse: map }
32    }
33    /// Create a width first hexagon map.
34    ///
35    /// # Arguments
36    ///
37    /// * `width`: row count
38    /// * `height`: column count
39    /// * `odd_left`: Fill the extra line at left if width is odd.
40    ///
41    /// returns: HexagonMap<T>
42    ///
43    /// # Examples
44    ///
45    /// ```
46    /// # use hexagon_map::HexagonMap;
47    /// let map = HexagonMap::<u8>::width_first(5, 5, true);
48    /// assert_eq!(map.points_count(), 25)
49    /// ```
50    pub fn width_first(rows: usize, columns: usize, odd_left: bool) -> Self {
51        let mut map = BTreeMap::new();
52        for x in 0..rows {
53            for y in 0..columns {
54                let point = match rows % 2 {
55                    1 if odd_left => WPoint::new(x as isize - 1, y as isize),
56                    _ => WPoint::new(x as isize, y as isize),
57                };
58                map.insert(point.into(), Default::default());
59            }
60        }
61        Self { sparse: map }
62    }
63    pub fn height_first(rows: usize, columns: usize, odd_up: bool) -> Self {
64        let mut map = BTreeMap::new();
65        for y in 0..columns {
66            for x in 0..rows {
67                let point = match columns % 2 {
68                    1 if odd_up => HPoint::new(x as isize, y as isize - 1),
69                    _ => HPoint::new(x as isize, y as isize),
70                };
71                map.insert(point.into(), Default::default());
72            }
73        }
74        Self { sparse: map }
75    }
76}
77
78impl<T> HexagonMap<T> {
79    /// Get the value at a point, if it exists.
80    pub fn get_point(&self, point: CubicPoint) -> Option<&T> {
81        self.sparse.get(&point)
82    }
83    /// Add a point to the map, if it already exists, return the old value.
84    pub fn add_point(&mut self, point: CubicPoint, value: T) -> Option<T> {
85        self.sparse.insert(point, value)
86    }
87    /// Get a mutable reference to a point, if it exists.
88    pub fn mut_point(&mut self, point: CubicPoint) -> Option<&mut T> {
89        self.sparse.get_mut(&point)
90    }
91    /// Remove a point from the map, if it exists, return the old value.
92    pub fn remove_point(&mut self, point: CubicPoint) -> Option<T> {
93        self.sparse.remove(&point)
94    }
95}