1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
use crate::Hex;
#[derive(Debug, Clone)]
#[cfg_attr(feature = "ser_de", derive(serde::Serialize, serde::Deserialize))]
pub struct HexMap {
radius: u32,
center: Hex,
mirrors: [Hex; 6],
}
impl HexMap {
#[inline]
#[must_use]
pub const fn new(radius: u32) -> Self {
Self {
radius,
center: Hex::ZERO,
mirrors: Hex::wraparound_mirrors(radius),
}
}
#[inline]
#[must_use]
pub fn with_center(self, center: Hex) -> Self {
Self {
radius: self.radius,
center,
mirrors: self.mirrors.map(|h| h + center),
}
}
#[inline]
#[must_use]
pub const fn center(&self) -> Hex {
self.center
}
#[inline]
#[must_use]
pub const fn radius(&self) -> u32 {
self.radius
}
#[must_use]
pub fn wrapped_hex(&self, hex: Hex) -> Hex {
let pos = hex - self.center;
let pos = pos.wrap_with(self.radius, &self.mirrors);
pos + self.center
}
#[must_use]
#[inline]
pub fn wrapped_neighbors(&self, hex: Hex) -> [Hex; 6] {
hex.all_neighbors().map(|h| self.wrapped_hex(h))
}
#[must_use]
#[inline]
pub const fn hex_count(&self) -> usize {
Hex::range_count(self.radius)
}
pub fn all_coords(&self) -> impl Iterator<Item = Hex> {
self.center.range(self.radius)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn wrapping_works() {
let map = HexMap::new(3);
assert_eq!(map.wrapped_hex(Hex::new(0, 4)), Hex::new(-3, 0));
assert_eq!(map.wrapped_hex(Hex::new(4, 0)), Hex::new(-3, 3));
assert_eq!(map.wrapped_hex(Hex::new(4, -4)), Hex::new(0, 3));
}
#[test]
fn wrapping_outside_works() {
let map = HexMap::new(2);
assert_eq!(map.wrapped_hex(Hex::new(3, 0)), Hex::new(-2, 2));
assert_eq!(map.wrapped_hex(Hex::new(5, 0)), Hex::new(0, 2));
assert_eq!(map.wrapped_hex(Hex::new(6, 0)), Hex::new(-1, -1));
assert_eq!(map.wrapped_hex(Hex::new(2, 3)), Hex::new(0, 0)); assert_eq!(map.wrapped_hex(Hex::new(4, 6)), Hex::new(0, 0));
}
}