1mod space;
10mod collapse_rule;
11mod state;
12mod set_state;
13mod all_state;
14pub mod square_grid;
15pub mod bitset_state;
16pub mod hashset_state;
17pub mod set_rule;
18
19use std::{collections::{HashSet, VecDeque}};
20
21use rand::{thread_rng, Rng};
22pub use space::*;
23pub use state::*;
24pub use collapse_rule::*;
25pub use set_state::*;
26pub use all_state::*;
27
28fn find_next_to_collapse<St: State, Sp: Space<St>>(unresoved_set: &mut HashSet<Sp::Coordinate>, lowest_entropy_set: &mut Vec<Sp::Coordinate>, resolved_set: &mut HashSet<Sp::Coordinate>, space: &Sp) -> Option<Sp::Coordinate> {
29 let mut lowest_entropy = std::u32::MAX;
30 lowest_entropy_set.clear();
31 resolved_set.clear();
32 for unresolved in unresoved_set.iter() {
33 let entropy = space[*unresolved].entropy();
34 if entropy == 0 {
35 resolved_set.insert(*unresolved);
36 } else if entropy < lowest_entropy {
37 lowest_entropy = entropy;
38 lowest_entropy_set.clear();
39 lowest_entropy_set.push(*unresolved);
40 } else if entropy == lowest_entropy {
41 lowest_entropy_set.push(*unresolved);
42 }
43 }
44 unresoved_set.retain(|x| !resolved_set.contains(x));
45 if lowest_entropy_set.len() == 0 {
46 return None;
47 } else {
48 Some(lowest_entropy_set[thread_rng().gen_range(0..lowest_entropy_set.len())])
49 }
50}
51
52pub fn collapse<Rule: CollapseRule<St, Sp>, St: State, Sp: Space<St>>(space: &mut Sp, rule: &Rule) {
55 let mut unresolved_set = HashSet::new();
56 let mut resolved_set = HashSet::new();
57 let mut lowest_entropy_set = Vec::new();
58 let neighbor_directions = rule.neighbor_offsets();
59 for coord in &space.coordinate_list()[..] {
60 if space[*coord].entropy() > 0 {
61 unresolved_set.insert(*coord);
62 }
63 }
64 let mut neighbors = vec![None; neighbor_directions.len()].into_boxed_slice();
65 let mut neighbor_states = vec![Option::<St>::None; neighbor_directions.len()].into_boxed_slice();
66 let mut to_propogate = VecDeque::new();
67
68 for coordinate in unresolved_set.iter() {
69 to_propogate.push_back(*coordinate);
70 }
71 run_propogation(space, rule, &mut to_propogate, &neighbor_directions, &mut neighbors, &mut neighbor_states);
72
73 while let Some(to_collapse) = find_next_to_collapse(&mut unresolved_set, &mut lowest_entropy_set, &mut resolved_set, space) {
74 to_propogate.clear();
75 space.neighbors(to_collapse, &neighbor_directions, &mut neighbors);
76 for i in 0 .. neighbor_directions.len() {
77 neighbor_states[i] = neighbors[i].map(|coord| space[coord].clone());
78 }
79 rule.observe(&mut space[to_collapse], &neighbor_states[..]);
80 for i in 0..neighbor_directions.len() {
81 if let Some(neighbor_coord) = neighbors[i] {
82 to_propogate.push_back(neighbor_coord);
83 }
84 }
85 run_propogation(space, rule, &mut to_propogate, &neighbor_directions, &mut neighbors, &mut neighbor_states);
86 }
87}
88
89fn run_propogation<Rule: CollapseRule<St, Sp>, St: State, Sp: Space<St>>(space: &mut Sp, rule: &Rule, to_propogate: &mut VecDeque<Sp::Coordinate>, neighbor_directions: &[Sp::CoordinateDelta], neighbors: &mut [Option<Sp::Coordinate>], neighbor_states: &mut [Option<St>]) {
90 while let Some(propogating) = to_propogate.pop_front() {
91 let entropy_before = space[propogating].entropy();
92
93 if entropy_before != 0 {
94 space.neighbors(propogating, &neighbor_directions, neighbors);
95 for i in 0 .. neighbor_directions.len() {
96 neighbor_states[i] = neighbors[i].map(|coord| space[coord].clone());
97 }
98 rule.collapse(&mut space[propogating], &neighbor_states[..]);
99 let entropy_after = space[propogating].entropy();
100
101 if entropy_after < entropy_before {
102 for i in 0 .. neighbor_directions.len() {
103 if let Some(neighbor) = neighbors[i] {
104 if space[neighbor].entropy() != 0 {
105 to_propogate.push_back(neighbor);
106 }
107 }
108 }
109 }
110 }
111 }
112}