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"); } } } } }