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
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
use std::collections::{HashSet};
use std::marker::PhantomData;
use std::{cell::RefCell, rc::Rc, collections::HashMap};
use std::hash::Hash;
use bitvec::vec::BitVec;
use rand::seq::SliceRandom;
use super::collapsable_wave_function::{CollapsableWaveFunction, CollapsableNode, CollapsedNodeState, CollapsedWaveFunction};
pub struct AccommodatingCollapsableWaveFunction<'a, TNodeState: Eq + Hash + Clone + std::fmt::Debug + Ord> {
collapsable_nodes: Vec<Rc<RefCell<CollapsableNode<'a, TNodeState>>>>,
collapsable_node_per_id: HashMap<&'a str, Rc<RefCell<CollapsableNode<'a, TNodeState>>>>,
accommodate_node_ids: Vec<&'a str>,
accommodate_node_ids_length: usize,
accommodate_node_ids_index: usize,
accommodated_total: usize,
impacted_node_ids: HashSet<&'a str>,
node_state_type: PhantomData<TNodeState>
}
impl<'a, TNodeState: Eq + Hash + Clone + std::fmt::Debug + Ord> AccommodatingCollapsableWaveFunction<'a, TNodeState> {
fn initialize_nodes(&mut self) -> Result<Vec<CollapsedNodeState<TNodeState>>, String> {
let mut initial_node_states: Vec<CollapsedNodeState<TNodeState>> = Vec::new();
for wrapped_collapsable_node in self.collapsable_nodes.iter() {
let mut collapsable_node = wrapped_collapsable_node.borrow_mut();
if !collapsable_node.node_state_indexed_view.try_move_next() {
return Err(String::from("Cannot collapse wave function."));
}
self.accommodate_node_ids.push(collapsable_node.id);
let node_state = collapsable_node.node_state_indexed_view.get().unwrap();
let collapsed_node_state: CollapsedNodeState<TNodeState> = CollapsedNodeState {
node_id: String::from(collapsable_node.id),
node_state_id: Some((*node_state).clone())
};
initial_node_states.push(collapsed_node_state);
}
self.accommodate_node_ids_length = self.accommodate_node_ids.len();
self.accommodated_total = self.accommodate_node_ids_length;
for wrapped_collapsable_node in self.collapsable_nodes.iter() {
let collapsable_node = wrapped_collapsable_node.borrow();
let node_state = collapsable_node.node_state_indexed_view.get().unwrap();
let neighbor_node_ids: &Vec<&str> = &collapsable_node.neighbor_node_ids;
let mask_per_neighbor_per_state: &HashMap<&TNodeState, HashMap<&str, BitVec>> = &collapsable_node.mask_per_neighbor_per_state;
if let Some(mask_per_neighbor) = mask_per_neighbor_per_state.get(node_state) {
for neighbor_node_id in neighbor_node_ids.iter() {
if mask_per_neighbor.contains_key(neighbor_node_id) {
let wrapped_neighbor_collapsable_node = self.collapsable_node_per_id.get(neighbor_node_id).unwrap();
let mut neighbor_collapsable_node = wrapped_neighbor_collapsable_node.borrow_mut();
let mask = mask_per_neighbor.get(neighbor_node_id).unwrap();
neighbor_collapsable_node.add_mask(mask);
debug!("adding mask to {:?} when in initialize_nodes", neighbor_node_id);
}
}
}
}
Ok(initial_node_states)
}
fn is_fully_collapsed(&self) -> bool {
self.accommodated_total == 0
}
fn prepare_nodes_for_iteration(&mut self) {
debug!("prior to being prepared: {:?}", self.accommodate_node_ids);
self.accommodate_node_ids_index = 0;
self.accommodate_node_ids.shuffle(&mut rand::thread_rng()); self.accommodated_total = 0;
self.impacted_node_ids.clear();
debug!("after being prepared: {:?}", self.accommodate_node_ids);
}
fn is_done_accommodating_nodes(&self) -> bool {
self.accommodate_node_ids_index == self.accommodate_node_ids_length
}
fn is_current_node_in_conflict(&mut self) -> bool {
let current_collapsable_node_id: &str = self.accommodate_node_ids[self.accommodate_node_ids_index];
let wrapped_current_collapsable_node = self.collapsable_node_per_id.get(current_collapsable_node_id).unwrap();
let current_collapsable_node = wrapped_current_collapsable_node.borrow();
let mut is_current_collapsable_node_in_conflict = current_collapsable_node.node_state_indexed_view.is_current_state_restricted();
if self.impacted_node_ids.contains(current_collapsable_node_id) {
is_current_collapsable_node_in_conflict = false;
}
else {
for parent_neighbor_node_id in current_collapsable_node.parent_neighbor_node_ids.iter() {
if self.impacted_node_ids.contains(parent_neighbor_node_id) {
is_current_collapsable_node_in_conflict = false;
break;
}
}
}
if !is_current_collapsable_node_in_conflict {
self.accommodate_node_ids_index += 1;
debug!("node is not in conflict: {:?}", current_collapsable_node_id);
}
else {
debug!("node is in conflict: {:?}", current_collapsable_node_id);
}
is_current_collapsable_node_in_conflict
}
fn accommodate_current_node(&mut self) -> Vec<CollapsedNodeState<TNodeState>> {
let mut changed_parent_node_states: Vec<CollapsedNodeState<TNodeState>> = Vec::new();
let mut to_node_state_and_from_node_state_tuple_per_parent_node_id: HashMap<&str, (&TNodeState, &TNodeState)> = HashMap::new();
{
let current_collapsable_node_id: &str = self.accommodate_node_ids[self.accommodate_node_ids_index];
let wrapped_current_collapsable_node = self.collapsable_node_per_id.get(current_collapsable_node_id).unwrap();
let current_collapsable_node = wrapped_current_collapsable_node.borrow();
self.impacted_node_ids.insert(current_collapsable_node_id);
for parent_neighbor_node_id in current_collapsable_node.parent_neighbor_node_ids.iter() {
self.impacted_node_ids.insert(parent_neighbor_node_id);
let wrapped_parent_neighbor_node = self.collapsable_node_per_id.get(parent_neighbor_node_id).unwrap();
let mut parent_neighbor_node = wrapped_parent_neighbor_node.borrow_mut();
let original_node_state = *parent_neighbor_node.node_state_indexed_view.get().unwrap();
let mut current_node_state = original_node_state;
let mut is_current_node_state_restrictive = true;
while is_current_node_state_restrictive {
let is_current_mask_from_parent_restrictive: bool;
if parent_neighbor_node.mask_per_neighbor_per_state.contains_key(¤t_node_state) {
let mask_per_neighbor = parent_neighbor_node.mask_per_neighbor_per_state.get(¤t_node_state).unwrap();
let mask = mask_per_neighbor.get(current_collapsable_node_id).unwrap();
is_current_mask_from_parent_restrictive = current_collapsable_node.is_mask_restrictive_to_current_state(mask);
}
else {
is_current_mask_from_parent_restrictive = false;
}
if !is_current_mask_from_parent_restrictive {
debug!("found unrestricted mask (or no mask) for neighbor {:?}", parent_neighbor_node_id);
is_current_node_state_restrictive = false; if current_node_state != original_node_state {
debug!("the node state had to change to {:?}", current_node_state);
changed_parent_node_states.push(CollapsedNodeState {
node_id: String::from(*parent_neighbor_node_id),
node_state_id: Some(current_node_state.clone())
});
to_node_state_and_from_node_state_tuple_per_parent_node_id.insert(parent_neighbor_node_id, (original_node_state, current_node_state));
}
else {
debug!("the node state was already good at {:?}", current_node_state);
}
}
else {
parent_neighbor_node.node_state_indexed_view.move_next();
let next_node_state = *parent_neighbor_node.node_state_indexed_view.get().unwrap();
if next_node_state == original_node_state {
debug!("Unable to accommodate the current collapsable node {:?} at state {:?}", current_collapsable_node_id, current_collapsable_node.node_state_indexed_view.get().unwrap());
break;
}
current_node_state = next_node_state;
}
}
}
}
{
for (parent_neighbor_node_id, (original_node_state, current_node_state)) in to_node_state_and_from_node_state_tuple_per_parent_node_id.iter() {
let wrapped_parent_neighbor_node = self.collapsable_node_per_id.get(parent_neighbor_node_id).unwrap();
let parent_neighbor_node = wrapped_parent_neighbor_node.borrow();
let neighbor_node_ids: &Vec<&str> = &parent_neighbor_node.neighbor_node_ids;
let mask_per_neighbor_per_state: &HashMap<&TNodeState, HashMap<&str, BitVec>> = &parent_neighbor_node.mask_per_neighbor_per_state;
if let Some(mask_per_neighbor) = mask_per_neighbor_per_state.get(original_node_state) {
for neighbor_node_id in neighbor_node_ids.iter() {
if mask_per_neighbor.contains_key(neighbor_node_id) {
let wrapped_neighbor_collapsable_node = self.collapsable_node_per_id.get(neighbor_node_id).unwrap();
let mut neighbor_collapsable_node = wrapped_neighbor_collapsable_node.borrow_mut();
let mask = mask_per_neighbor.get(neighbor_node_id).unwrap();
neighbor_collapsable_node.subtract_mask(mask);
debug!("subtracting mask to {:?} when in accommodate_current_node", neighbor_node_id);
}
}
}
if let Some(mask_per_neighbor) = mask_per_neighbor_per_state.get(current_node_state) {
for neighbor_node_id in neighbor_node_ids.iter() {
if mask_per_neighbor.contains_key(neighbor_node_id) {
let wrapped_neighbor_collapsable_node = self.collapsable_node_per_id.get(neighbor_node_id).unwrap();
let mut neighbor_collapsable_node = wrapped_neighbor_collapsable_node.borrow_mut();
let mask = mask_per_neighbor.get(neighbor_node_id).unwrap();
neighbor_collapsable_node.add_mask(mask);
debug!("adding mask to {:?} when in accommodate_current_node", neighbor_node_id);
}
}
}
}
}
self.accommodated_total += 1;
changed_parent_node_states
}
fn get_collapsed_wave_function(&self) -> CollapsedWaveFunction<TNodeState> {
let mut node_state_per_node: HashMap<String, TNodeState> = HashMap::new();
for wrapped_collapsable_node in self.collapsable_nodes.iter() {
let collapsable_node = wrapped_collapsable_node.borrow();
let node_state: TNodeState = (*collapsable_node.node_state_indexed_view.get().unwrap()).clone();
let node: String = String::from(collapsable_node.id);
debug!("established node {node} in state {:?}.", node_state);
node_state_per_node.insert(node, node_state);
}
CollapsedWaveFunction {
node_state_per_node: node_state_per_node
}
}
}
impl<'a, TNodeState: Eq + Hash + Clone + std::fmt::Debug + Ord> CollapsableWaveFunction<'a, TNodeState> for AccommodatingCollapsableWaveFunction<'a, TNodeState> {
fn new(collapsable_nodes: Vec<Rc<RefCell<CollapsableNode<'a, TNodeState>>>>, collapsable_node_per_id: HashMap<&'a str, Rc<RefCell<CollapsableNode<'a, TNodeState>>>>) -> Self {
AccommodatingCollapsableWaveFunction {
collapsable_nodes: collapsable_nodes,
collapsable_node_per_id: collapsable_node_per_id,
accommodate_node_ids: Vec::new(),
accommodate_node_ids_length: 0,
accommodate_node_ids_index: 0,
accommodated_total: 0,
impacted_node_ids: HashSet::new(),
node_state_type: PhantomData
}
}
fn collapse(&'a mut self) -> Result<CollapsedWaveFunction<TNodeState>, String> {
let initialize_result = self.initialize_nodes();
if initialize_result.is_err() {
return Err(initialize_result.err().unwrap());
}
let mut iterations_total: u32 = 0;
debug!("about to enter while loop");
while !self.is_fully_collapsed() {
debug!("preparing nodes for iteration");
self.prepare_nodes_for_iteration();
debug!("checking if done accommodating nodes");
while !self.is_done_accommodating_nodes() {
debug!("checking if current node is in conflict");
if self.is_current_node_in_conflict() {
debug!("accommodating current node");
self.accommodate_current_node();
}
iterations_total += 1;
}
}
debug!("fully collapsed after {:?} iterations", iterations_total);
Ok(self.get_collapsed_wave_function())
}
fn collapse_into_steps(&'a mut self) -> Result<Vec<CollapsedNodeState<TNodeState>>, String> {
let mut collapsed_node_states: Vec<CollapsedNodeState<TNodeState>> = Vec::new();
let initialized_node_states_result = self.initialize_nodes();
if initialized_node_states_result.is_err() {
return Err(initialized_node_states_result.err().unwrap());
}
let initialized_node_states = initialized_node_states_result.unwrap();
collapsed_node_states.extend(initialized_node_states);
while !self.is_fully_collapsed() {
self.prepare_nodes_for_iteration();
while !self.is_done_accommodating_nodes() {
if self.is_current_node_in_conflict() {
let accommodated_neighbor_node_states = self.accommodate_current_node();
collapsed_node_states.extend(accommodated_neighbor_node_states);
}
}
}
Ok(collapsed_node_states)
}
}