entropy_base/
grid.rs

1use rand::{rngs::SmallRng, Rng, RngCore, SeedableRng};
2use serde::{de, ser::SerializeTupleStruct, Deserialize, Serialize, Serializer};
3use std::{fmt, ops::Deref};
4
5pub const NODE_MAX_SIZE: usize = 16 * 1024; // 16KiB
6
7//         ^UP
8//         |
9// LEFT <-   -> RIGHT
10//         |
11//         vDOWN
12pub mod navi {
13    pub type Direction = (i16, i16);
14    pub const SITU: (i16, i16) = (0, 0);
15    pub const UP: (i16, i16) = (0, 1);
16    pub const DOWN: (i16, i16) = (0, -1);
17    pub const LEFT: (i16, i16) = (-1, 0);
18    pub const RIGHT: (i16, i16) = (1, 0);
19}
20
21/// y
22/// ^ 0,1,2
23/// | 3,4,5,
24/// | 6,7,8
25/// |------> x
26pub const INDEXED_NAVI: [(i16, i16); 9] = [
27    (-1, 1),
28    (0, 1),
29    (1, 1),
30    (-1, 0),
31    (0, 0),
32    (1, 0),
33    (-1, -1),
34    (0, -1),
35    (1, -1),
36];
37
38pub const ALLOWED_NAVI: [(i16, i16); 4] = [(-1, 0), (1, 0), (0, -1), (0, 1)];
39
40#[derive(
41    Debug, Default, Clone, Copy, Serialize, Deserialize, PartialEq, Eq, PartialOrd, Ord, Hash,
42)]
43pub struct NodeID(i16, i16);
44impl NodeID {
45    pub const UP_LEFT: Self = NodeID(i16::MIN, i16::MAX);
46    pub const UP_MIDDLE: Self = NodeID(0, i16::MAX);
47    pub const UP_RIGHT: Self = NodeID(i16::MAX, i16::MAX);
48    pub const LEFT_MIDDLE: Self = NodeID(i16::MIN, 0);
49    pub const SITU: Self = NodeID(0, 0);
50    pub const ORIGIN: Self = NodeID(0, 0);
51    pub const RIGHT_MIDDLE: Self = NodeID(i16::MAX, 0);
52    pub const DOWN_LEFT: Self = NodeID(i16::MIN, i16::MIN);
53    pub const DOWN_MIDDLE: Self = NodeID(0, i16::MIN);
54    pub const DOWN_RIGHT: Self = NodeID(i16::MAX, i16::MIN);
55
56    pub fn new((x, y): (i16, i16)) -> Self {
57        NodeID(x, y)
58    }
59
60    pub fn from_i32(value: i32) -> Self {
61        FlatID::from_i32(value).into_node_id()
62    }
63
64    pub fn from_xy(x: i16, y: i16) -> Self {
65        Self(x, y)
66    }
67
68    pub fn into_tuple(self) -> (i16, i16) {
69        self.into()
70    }
71
72    pub fn into_i32(self) -> i32 {
73        self.into_flat().0
74    }
75
76    pub fn into_flat(self) -> FlatID {
77        self.into()
78    }
79
80    pub fn navi_to(&mut self, to: navi::Direction) -> NodeID {
81        self.0 = self.0.wrapping_add(to.0);
82        self.1 = self.1.wrapping_add(to.1);
83        self.clone()
84    }
85}
86
87impl From<(i16, i16)> for NodeID {
88    fn from(value: (i16, i16)) -> Self {
89        NodeID(value.0, value.1)
90    }
91}
92impl Into<(i16, i16)> for NodeID {
93    fn into(self) -> (i16, i16) {
94        (self.0, self.1)
95    }
96}
97
98#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
99pub struct NodeData(Vec<i8>);
100impl NodeData {
101    pub fn random() -> Self {
102        let mut rng = SmallRng::from_entropy();
103        let length = rng.gen_range(0..NODE_MAX_SIZE);
104        let mut rnt = vec![0u8; length];
105        rng.fill_bytes(&mut rnt);
106        let rnt = rnt
107            .into_iter()
108            .map(|cell| i8::from_be_bytes([cell]))
109            .collect();
110        Self(rnt)
111    }
112    pub fn get(&self, index: usize) -> Option<i8> {
113        self.0.get(index).map(|x| *x)
114    }
115    pub fn set(&mut self, index: usize, value: i8) -> Option<()> {
116        self.0.get_mut(index).map(|cell| *cell = value)
117    }
118    pub fn to_bytes(self) -> Vec<u8> {
119        self.0
120            .into_iter()
121            .map(|cell| cell.to_be_bytes()[0])
122            .collect()
123    }
124    pub fn from_bytes(value: impl AsRef<[u8]>) -> Self {
125        value.into()
126    }
127}
128
129/// Default big endian encoding
130impl Into<Vec<u8>> for NodeData {
131    fn into(self) -> Vec<u8> {
132        self.to_bytes()
133    }
134}
135
136impl<T: AsRef<[u8]>> From<T> for NodeData {
137    fn from(value: T) -> Self {
138        Self(
139            value
140                .as_ref()
141                .iter()
142                .map(|b| i8::from_be_bytes([*b]))
143                .collect(),
144        )
145    }
146}
147
148impl Deref for NodeData {
149    type Target = Vec<i8>;
150
151    fn deref(&self) -> &Self::Target {
152        &self.0
153    }
154}
155
156#[derive(Debug, Clone, Serialize, Deserialize)]
157pub struct Node {
158    pub id: NodeID,
159    pub data: NodeData,
160}
161impl Node {
162    pub fn new((x, y): (i16, i16), data: impl AsRef<[u8]>) -> Self {
163        Node {
164            id: NodeID(x, y),
165            data: NodeData::from(data),
166        }
167    }
168}
169
170#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
171pub struct FlatID(
172    #[serde(
173        serialize_with = "crate::grid::ser_flat",
174        deserialize_with = "crate::grid::de_flat"
175    )]
176    i32,
177);
178impl FlatID {
179    pub fn into_node_id(self) -> NodeID {
180        self.into()
181    }
182
183    pub fn into_tuple(self) -> (i16, i16) {
184        self.into_node_id().into_tuple()
185    }
186
187    pub fn from_i32(value: i32) -> Self {
188        Self::from(value)
189    }
190
191    pub fn from_xy(x: i16, y: i16) -> Self {
192        NodeID::from_xy(x, y).into()
193    }
194}
195
196impl From<i32> for FlatID {
197    fn from(value: i32) -> Self {
198        Self(value)
199    }
200}
201impl Into<i32> for FlatID {
202    fn into(self) -> i32 {
203        self.0
204    }
205}
206impl From<NodeID> for FlatID {
207    fn from(value: NodeID) -> Self {
208        let [x1, x2] = value.0.to_be_bytes();
209        let [y1, y2] = value.1.to_be_bytes();
210        let f = i32::from_be_bytes([x1, x2, y1, y2]);
211        FlatID(f)
212    }
213}
214impl Into<NodeID> for FlatID {
215    fn into(self) -> NodeID {
216        let [x1, x2, y1, y2] = self.0.to_be_bytes();
217        NodeID::from_xy(i16::from_be_bytes([x1, x2]), i16::from_be_bytes([y1, y2]))
218    }
219}
220
221pub fn ser_flat<S>(id: &i32, serializer: S) -> Result<S::Ok, S::Error>
222where
223    S: Serializer,
224{
225    let (x, y) = FlatID::from(*id).into_tuple();
226    let mut tuple = serializer.serialize_tuple_struct("FlatID", 4)?;
227    tuple.serialize_field(&x)?;
228    tuple.serialize_field(&y)?;
229    tuple.end()
230}
231
232pub fn de_flat<'de, D>(deserializer: D) -> Result<i32, D::Error>
233where
234    D: serde::Deserializer<'de>,
235{
236    #[derive(Debug)]
237    struct FlatIDVisitor;
238
239    impl<'de> de::Visitor<'de> for FlatIDVisitor {
240        type Value = i32;
241
242        fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
243            formatter.write_str("a tuple of two i32 values")
244        }
245
246        fn visit_seq<A>(self, mut seq: A) -> Result<i32, A::Error>
247        where
248            A: de::SeqAccess<'de>,
249        {
250            let x = seq
251                .next_element()?
252                .ok_or_else(|| de::Error::invalid_length(0, &self))?;
253            let y = seq
254                .next_element()?
255                .ok_or_else(|| de::Error::invalid_length(1, &self))?;
256
257            if seq.next_element::<()>()?.is_some() {
258                return Err(de::Error::invalid_length(2, &self));
259            }
260
261            Ok(FlatID::from_xy(x, y).into())
262        }
263    }
264
265    deserializer.deserialize_tuple_struct("FlatID", 2, FlatIDVisitor)
266}