aboutsummaryrefslogtreecommitdiff
path: root/src/state.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/state.rs')
-rw-r--r--src/state.rs72
1 files changed, 72 insertions, 0 deletions
diff --git a/src/state.rs b/src/state.rs
new file mode 100644
index 0000000..5d13902
--- /dev/null
+++ b/src/state.rs
@@ -0,0 +1,72 @@
+use crate::canvas::Canvas;
+
+#[derive(Debug, Clone)]
+pub struct State {
+ width: u32,
+ height: u32,
+ cells: Vec::<bool>,
+}
+
+impl State {
+ pub fn new(width: u32, height: u32) -> State {
+ let cells = (0..width * height)
+ .map(|_| js_sys::Math::random() < 0.5)
+ .collect();
+
+ State {
+ width,
+ height,
+ cells,
+ }
+ }
+
+ pub fn neighbor_count(&self, x: u32, y: u32) -> u32 {
+ let mut count = 0;
+ for delta_x in [self.height - 1, 0, 1].iter().clone() {
+ for delta_y in [self.width - 1, 0, 1].iter().clone() {
+ let neighbor_x = (x + delta_x) % self.width;
+ let neighbor_y = (y + delta_y) % self.height;
+
+ if (*delta_x, *delta_y) != (0, 0) && self.is_on(neighbor_x, neighbor_y) {
+ count += 1;
+ }
+ }
+ }
+ count
+ }
+
+ pub fn next(&self) -> State {
+ let cells = (0..self.width * self.height)
+ .map(|i| {
+ let x = i % self.width;
+ let y = i / self.width;
+ let neighbor_count = self.neighbor_count(x, y);
+ neighbor_count == 3 || self.is_on(x, y) && neighbor_count == 2
+ })
+ .collect();
+
+ State {
+ width: self.width,
+ height: self.height,
+ cells,
+ }
+ }
+
+ fn is_on(&self, x: u32, y: u32) -> bool {
+ let inside_x = (x + self.width) % self.width;
+ let inside_y = (y + self.height) % self.height;
+ self.cells[(inside_x + inside_y * self.width) as usize]
+ }
+
+ pub fn draw(&self, canvas: &Canvas) {
+ canvas.clear();
+
+ for y in 0..self.height {
+ for x in 0..self.width {
+ if self.is_on(x, y) {
+ canvas.draw(x, y, "green");
+ }
+ }
+ }
+ }
+}