1use crate::{
2 cell::BasicCell,
3 common::{Dimensions, DoubleVec, Index},
4};
5
6pub trait BasicWorld<C>
9where
10 C: BasicCell,
11 Self: Sized,
12{
13 fn blank(&self) -> Self {
15 Self::new_blank(self.dimensions())
16 }
17
18 fn random<R: rand::Rng + ?Sized>(&self, rng: &mut R) -> Self {
20 Self::new_random(rng, self.dimensions())
21 }
22
23 fn new(cells: DoubleVec<C>, dimensions: Dimensions) -> Self;
25 fn new_blank(dimensions: Dimensions) -> Self {
26 let default = C::default();
27 let cells = vec![vec![(); dimensions.0]; dimensions.1]
28 .into_iter()
29 .map(|row| row.into_iter().map(|_| default).collect())
30 .collect();
31 Self::new(cells, dimensions)
32 }
33
34 fn new_random<R: rand::Rng + ?Sized>(rng: &mut R, dimensions: Dimensions) -> Self {
35 let cells = (0..dimensions.0 * dimensions.1)
36 .collect::<Vec<usize>>()
37 .chunks(dimensions.0)
38 .into_iter()
39 .map(|chunk| chunk.iter().map(|_| C::random(rng)).collect())
40 .collect();
41 Self::new(cells, dimensions)
42 }
43
44 fn cells(&self) -> &DoubleVec<C>;
46 fn cells_mut(&mut self) -> &mut DoubleVec<C>;
48
49 fn changes(&self) -> Vec<(Index, C)>;
52
53 fn delta(&self) -> &Vec<(Index, C)>;
55 fn delta_mut(&mut self) -> &mut Vec<(Index, C)>;
57
58 fn dimensions(&self) -> Dimensions;
60
61 fn tick(&mut self) {
63 let changes = self.changes();
64 for ((x, y), cell) in changes.iter() {
65 self.cells_mut()[*y][*x] = *cell;
66 }
67 *self.delta_mut() = changes;
68 }
69
70 fn click(&mut self, i @ (x, y): Index) {
72 let c = &mut self.cells_mut()[y][x];
73 *c = c.next_state();
74 *self.delta_mut() = vec![(i, *c)]
75 }
76
77 fn moore_neighbors(&self, p @ (x, y): Index) -> Vec<Index> {
79 let (x, y) = (x as isize, y as isize);
80 let (w, h) = (self.dimensions().0 as isize, self.dimensions().1 as isize);
81
82 (-1..=1)
83 .flat_map(|i| {
84 (-1..=1).map(move |j| {
85 (
86 (x + i).rem_euclid(w) as usize,
87 (y + j).rem_euclid(h) as usize,
88 )
89 })
90 })
91 .filter(move |&item| item != p)
92 .collect()
93 }
94}
95
96#[cfg(test)]
97mod test {
98 use super::*;
99 use crate::cell::test::Cell;
100
101 struct World;
102
103 impl BasicWorld<Cell> for World {
104 fn new(cells: DoubleVec<Cell>, dimensions: Dimensions) -> Self {
105 todo!()
106 }
107
108 fn cells(&self) -> &DoubleVec<Cell> {
109 todo!()
110 }
111
112 fn cells_mut(&mut self) -> &mut DoubleVec<Cell> {
113 todo!()
114 }
115
116 fn changes(&self) -> Vec<(Index, Cell)> {
117 todo!()
118 }
119
120 fn delta(&self) -> &Vec<(Index, Cell)> {
121 todo!()
122 }
123
124 fn delta_mut(&mut self) -> &mut Vec<(Index, Cell)> {
125 todo!()
126 }
127
128 fn dimensions(&self) -> Dimensions {
129 Dimensions(50, 50)
130 }
131 }
132
133 #[test]
134 fn moore_neighbors_works() {
135 let world = World;
136
137 println!("{:?}", world.moore_neighbors((49, 49)));
138 }
139}