lattice_graph/hex/offset_based/
mod.rs

1/*!
2Module for Hex Graph with offset based coordinates.
3Offset coordinate is the coordinate pointing the same offset with underlying [`Offset`](`crate::lattice_abstract::Offset`),
4so converting to the [`Offset`](`crate::lattice_abstract::Offset) to get the weight of node or edge is just validating.
5Though, this might be costly for moving the coordinate ([`move_coord`](`crate::lattice_abstract::Shape::move_coord`)) than [`axial_based`](`super::axial_based`).
6*/
7
8use super::shapes::{DirectedMarker, LoopEW};
9use crate::lattice_abstract::LatticeGraph;
10mod shapes;
11pub use shapes::{ConstHexOffsetShape, HexOffset, HexOffsetShape};
12
13///Hex Graph with offset based coordinates.
14pub type HexGraph<N, E, B, H = usize, V = usize> = LatticeGraph<N, E, HexOffsetShape<B, (), H, V>>;
15///Hex Graph with offset based coordinates and loop in e-w direction.
16pub type HexGraphLoopEW<N, E, B, H = usize, V = usize> =
17    LatticeGraph<N, E, HexOffsetShape<B, LoopEW, H, V>>;
18///Directed Hex Graph with offset based coordinates.
19pub type DiHexGraph<N, E, B, Loop = (), H = usize, V = usize> =
20    LatticeGraph<N, E, HexOffsetShape<DirectedMarker<B>, Loop, H, V>>;
21
22///Hex Graph with offset based coordinates.
23#[cfg(feature = "const-generic-wrap")]
24pub type HexGraphConst<N, E, B, const H: usize, const V: usize> =
25    LatticeGraph<N, E, ConstHexOffsetShape<B, (), H, V>>;
26///Hex Graph with offset based coordinates and loop in e-w direction.
27#[cfg(feature = "const-generic-wrap")]
28pub type HexGraphConstLoopEW<N, E, B, const H: usize, const V: usize> =
29    LatticeGraph<N, E, ConstHexOffsetShape<B, LoopEW, H, V>>;
30///Directed Hex Graph with offset based coordinates.
31#[cfg(feature = "const-generic-wrap")]
32pub type DiHexGraphConst<N, E, B, const H: usize, const V: usize> =
33    LatticeGraph<N, E, ConstHexOffsetShape<DirectedMarker<B>, (), H, V>>;
34
35#[cfg(test)]
36#[cfg(feature = "const-generic-wrap")]
37mod tests {
38    use super::*;
39    use crate::hex::shapes::*;
40    use petgraph::{data::DataMap, visit::*};
41    use rstest::*;
42
43    type Hex5x5 = HexGraphConst<HexOffset, (HexOffset, AxisR), OddR, 5, 5>;
44    type Hex5x5Lew = HexGraphConstLoopEW<HexOffset, (HexOffset, AxisR), OddR, 5, 5>;
45
46    #[fixture]
47    fn hexgraph_oddr55() -> Hex5x5 {
48        Hex5x5::new_with(HexOffsetShape::default(), |x| (x), |n, d| (n, d))
49    }
50
51    #[fixture]
52    fn hexgraph_oddr55_lew() -> Hex5x5Lew {
53        Hex5x5Lew::new_with(HexOffsetShape::default(), |x| (x), |n, d| (n, d))
54    }
55
56    #[rstest]
57    fn gen_oddr(hexgraph_oddr55: Hex5x5) {
58        let graph = hexgraph_oddr55;
59        for i in 0..graph.node_count() {
60            let x = graph.from_index(i);
61            assert_eq!(Some(&x), graph.node_weight(x));
62        }
63    }
64
65    #[rstest]
66    #[case(HexOffset::new(0, 0), [HexOffset::new(0, 1), HexOffset::new(1, 0)] )]
67    #[case(HexOffset::new(4, 0), [HexOffset::new(4, 1), HexOffset::new(3, 0), HexOffset::new(3, 1)] )]
68    #[case(HexOffset::new(1, 1), [
69        HexOffset::new(2, 2),
70        HexOffset::new(2, 1),
71        HexOffset::new(2, 0),
72        HexOffset::new(1, 0),
73        HexOffset::new(0, 1),
74        HexOffset::new(1, 2),
75    ])]
76    #[case(HexOffset::new(1, 2), [
77        HexOffset::new(1, 3),
78        HexOffset::new(2, 2),
79        HexOffset::new(1, 1),
80        HexOffset::new(0, 1),
81        HexOffset::new(0, 2),
82        HexOffset::new(0, 3),
83    ])]
84    fn neighbors_oddr(
85        hexgraph_oddr55: Hex5x5,
86        #[case] target: HexOffset,
87        #[case] neighbors: impl IntoIterator<Item = HexOffset>,
88    ) {
89        let graph = hexgraph_oddr55;
90        let e = graph.neighbors(target);
91        debug_assert!(e.eq(neighbors));
92    }
93
94    #[rstest]
95    #[case(HexOffset::new(0, 0), [AxisDR::NE, AxisDR::E,] )]
96    #[case(HexOffset::new(4, 0), [AxisDR::NE, AxisDR::W, AxisDR::NW] )]
97    #[case(HexOffset::new(1, 1), [AxisDR::NE, AxisDR::E, AxisDR::SE, AxisDR::SW, AxisDR::W, AxisDR::NW] )]
98    #[case(HexOffset::new(1, 2), [AxisDR::NE, AxisDR::E, AxisDR::SE, AxisDR::SW, AxisDR::W, AxisDR::NW] )]
99    fn edges_oddr(
100        hexgraph_oddr55: Hex5x5,
101        #[case] target: HexOffset,
102        #[case] edge_targets: impl IntoIterator<Item = AxisDR>,
103    ) {
104        let graph = hexgraph_oddr55;
105        let e = graph.edges(target).map(|e| e.direction().clone());
106        debug_assert!(e.eq(edge_targets));
107    }
108
109    #[rstest]
110    #[case(HexOffset::new(0, 0), [
111        HexOffset::new(0, 1),
112        HexOffset::new(1, 0),
113        HexOffset::new(4, 0),
114        HexOffset::new(4, 1),]) ]
115    #[case(HexOffset::new(4, 0), [
116        HexOffset::new(4, 1),
117        HexOffset::new(0, 0),
118        HexOffset::new(3, 0),
119        HexOffset::new(3, 1)]) ]
120    #[case(HexOffset::new(1, 1), [
121        HexOffset::new(2, 2),
122        HexOffset::new(2, 1),
123        HexOffset::new(2, 0),
124        HexOffset::new(1, 0),
125        HexOffset::new(0, 1),
126        HexOffset::new(1, 2),
127    ])]
128    #[case(HexOffset::new(1, 2), [
129        HexOffset::new(1, 3),
130        HexOffset::new(2, 2),
131        HexOffset::new(1, 1),
132        HexOffset::new(0, 1),
133        HexOffset::new(0, 2),
134        HexOffset::new(0, 3),
135    ])]
136    fn neighbors_oddr_lew(
137        hexgraph_oddr55_lew: Hex5x5Lew,
138        #[case] target: HexOffset,
139        #[case] neighbors: impl IntoIterator<Item = HexOffset>,
140    ) {
141        let graph = hexgraph_oddr55_lew;
142        let e = graph.neighbors(target);
143        debug_assert!(e.eq(neighbors));
144    }
145
146    #[test]
147    fn gen_oddr_di() {
148        let graph = DiHexGraphConst::<_, _, OddR, 5, 3>::new_with(
149            HexOffsetShape::default(),
150            |x| (x),
151            |n, d| Some((n, d)),
152        );
153        for i in 0..graph.node_count() {
154            let x = graph.from_index(i);
155            assert_eq!(Some(&x), graph.node_weight(x));
156        }
157    }
158
159    #[test]
160    fn edges_oddr_dir() {
161        let graph = DiHexGraphConst::<_, _, OddR, 5, 5>::new_with(
162            HexOffsetShape::default(),
163            |x| (x),
164            |n, d| Some((n, d)),
165        );
166        assert!(graph
167            .edges(HexOffset::new(0, 0))
168            .map(|e| e.source())
169            .all(|x| x == HexOffset::new(0, 0)));
170        assert!(graph
171            .edges(HexOffset::new(1, 1))
172            .map(|e| e.source())
173            .all(|x| x == HexOffset::new(1, 1)));
174    }
175}