From 1b6a7e0d00703e3da2e1620b5a2b2cba027161de Mon Sep 17 00:00:00 2001 From: Joris Date: Tue, 28 Jan 2020 09:55:58 +0100 Subject: Implement game of life --- src/state.rs | 72 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) create mode 100644 src/state.rs (limited to 'src/state.rs') 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::, +} + +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"); + } + } + } + } +} -- cgit v1.2.3