screeps_utils/
large_cost_matrix.rs1use std::ops::{Index, IndexMut};
2
3use serde::{Deserialize, Serialize};
4use serde_with::serde_as;
5
6use screeps::{
7 constants::ROOM_SIZE,
8 objects::CostMatrix,
9 traits::{CostMatrixGet, CostMatrixSet},
10};
11
12use screeps::local::{linear_index_to_xy, xy_to_linear_index, LocalCostMatrix, Position, RoomXY};
13
14pub const ROOM_AREA: usize = ROOM_SIZE as usize * ROOM_SIZE as usize;
15
16#[serde_as]
20#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
21#[serde(transparent)]
22pub struct LargeCostMatrix {
23 #[serde_as(as = "[_; ROOM_AREA]")]
24 bits: [u16; ROOM_AREA],
25}
26
27impl Default for LargeCostMatrix {
28 fn default() -> Self {
29 Self::new()
30 }
31}
32
33impl LargeCostMatrix {
34 #[inline]
35 pub const fn new() -> Self {
36 LargeCostMatrix {
37 bits: [0; ROOM_AREA],
38 }
39 }
40 #[inline]
41 pub const fn new_with_default(default: u16) -> Self {
42 LargeCostMatrix {
43 bits: [default; ROOM_AREA],
44 }
45 }
46
47 #[inline]
51 pub fn set(&mut self, xy: RoomXY, val: u16) {
52 self[xy] = val;
53 }
54
55 #[inline]
59 pub fn get(&self, xy: RoomXY) -> u16 {
60 self[xy]
61 }
62
63 pub const fn get_bits(&self) -> &[u16; ROOM_AREA] {
64 &self.bits
65 }
66
67 pub fn iter(&self) -> impl Iterator<Item = (RoomXY, u16)> + '_ {
68 self.bits
69 .iter()
70 .enumerate()
71 .map(|(idx, &val)| (linear_index_to_xy(idx), val))
72 }
73
74 pub fn iter_mut(&mut self) -> impl Iterator<Item = (RoomXY, &mut u16)> {
75 self.bits
76 .iter_mut()
77 .enumerate()
78 .map(|(idx, val)| (linear_index_to_xy(idx), val))
79 }
80}
81
82impl From<LargeCostMatrix> for Vec<u16> {
83 #[inline]
86 fn from(lcm: LargeCostMatrix) -> Vec<u16> {
87 lcm.bits.into()
88 }
89}
90
91impl From<&LargeCostMatrix> for Vec<u16> {
92 fn from(lcm: &LargeCostMatrix) -> Vec<u16> {
93 lcm.bits.into()
94 }
95}
96
97impl From<&CostMatrix> for LargeCostMatrix {
98 fn from(js_matrix: &CostMatrix) -> Self {
99 let mut bits: [u16; ROOM_AREA] = [0; ROOM_AREA];
100 js_matrix
101 .get_bits()
102 .to_vec()
103 .iter()
104 .enumerate()
105 .for_each(|(idx, &val)| bits[idx] = val.into());
106
107 LargeCostMatrix { bits }
108 }
109}
110
111impl Index<RoomXY> for LargeCostMatrix {
112 type Output = u16;
113
114 fn index(&self, xy: RoomXY) -> &Self::Output {
115 unsafe { self.bits.get_unchecked(xy_to_linear_index(xy)) }
117 }
118}
119
120impl IndexMut<RoomXY> for LargeCostMatrix {
121 fn index_mut(&mut self, xy: RoomXY) -> &mut Self::Output {
122 unsafe { self.bits.get_unchecked_mut(xy_to_linear_index(xy)) }
124 }
125}
126
127impl Index<Position> for LargeCostMatrix {
128 type Output = u16;
129
130 fn index(&self, idx: Position) -> &Self::Output {
131 &self[RoomXY::from(idx)]
132 }
133}
134
135impl IndexMut<Position> for LargeCostMatrix {
136 fn index_mut(&mut self, idx: Position) -> &mut Self::Output {
137 &mut self[RoomXY::from(idx)]
138 }
139}
140
141impl CostMatrixSet for LargeCostMatrix {
142 fn set_xy(&mut self, xy: RoomXY, cost: u8) {
143 LargeCostMatrix::set(self, xy, cost as u16);
144 }
145}
146
147impl CostMatrixGet for LargeCostMatrix {
148 fn get_xy(&mut self, xy: RoomXY) -> u8 {
149 match u8::try_from(LargeCostMatrix::get(self, xy)) {
150 Ok(var) => var,
151 Err(_) => u8::MAX,
152 }
153 }
154}
155
156impl From<LargeCostMatrix> for LocalCostMatrix {
157 fn from(lcm: LargeCostMatrix) -> LocalCostMatrix {
158 let mut ret_lcm = LocalCostMatrix::new();
159
160 lcm.bits
161 .to_vec()
162 .iter()
163 .enumerate()
164 .for_each(|(idx, &val)| {
165 ret_lcm.set(linear_index_to_xy(idx), val.try_into().unwrap_or(u8::MAX))
166 });
167
168 ret_lcm
169 }
170}
171
172impl From<&LargeCostMatrix> for LocalCostMatrix {
173 fn from(lcm: &LargeCostMatrix) -> LocalCostMatrix {
174 let mut ret_lcm = LocalCostMatrix::new();
175
176 lcm.bits
177 .to_vec()
178 .iter()
179 .enumerate()
180 .for_each(|(idx, &val)| {
181 ret_lcm.set(linear_index_to_xy(idx), val.try_into().unwrap_or(u8::MAX))
182 });
183
184 ret_lcm
185 }
186}
187
188impl From<LargeCostMatrix> for CostMatrix {
189 fn from(lcm: LargeCostMatrix) -> CostMatrix {
190 let mut bits: [u8; ROOM_AREA] = [0; ROOM_AREA];
191 lcm.bits
192 .to_vec()
193 .iter()
194 .enumerate()
195 .for_each(|(idx, &val)| bits[idx] = val.try_into().unwrap_or(u8::MAX));
196
197 CostMatrix::new_from_bits(&bits)
198 }
199}