From 58b1fced2563f40990123ab362b0df53b5a91c0e Mon Sep 17 00:00:00 2001 From: Malte Voos Date: Sun, 2 Apr 2023 12:24:23 +0200 Subject: make it run in the browser --- src/main.rs | 233 ------------------------------------------------------------ 1 file changed, 233 deletions(-) delete mode 100644 src/main.rs (limited to 'src/main.rs') diff --git a/src/main.rs b/src/main.rs deleted file mode 100644 index a9af30d..0000000 --- a/src/main.rs +++ /dev/null @@ -1,233 +0,0 @@ -use pixels::wgpu::Color; -use pixels::PixelsBuilder; -use pixels::SurfaceTexture; -use rand::distributions::Standard; -use rand::prelude::Distribution; -use winit::dpi::PhysicalSize; -use winit::event::Event; -use winit::event_loop::EventLoop; -use winit::window::WindowBuilder; -use winit_input_helper::WinitInputHelper; - -const RES_X: usize = 265; -const RES_Y: usize = 265; - -const WIN_WIDTH: u32 = 4 * RES_X as u32; -const WIN_HEIGHT: u32 = 4 * RES_Y as u32; - -fn main() -> anyhow::Result<()> { - let event_loop = EventLoop::new(); - let window = WindowBuilder::new() - .with_inner_size(PhysicalSize { - width: WIN_WIDTH, - height: WIN_HEIGHT, - }) - .with_resizable(false) - .build(&event_loop)?; - let mut input = WinitInputHelper::new(); - - let window_size = window.inner_size(); - let surface_texture = SurfaceTexture::new(window_size.width, window_size.height, &window); - - let mut pixels = PixelsBuilder::new(RES_X as u32, RES_Y as u32, surface_texture) - .clear_color(Color { - r: 0.0, - g: 0.0, - b: 0.0, - a: 1.0, - }) - .build()?; - let mut life = Life::new(); - - event_loop.run(move |event, _, control_flow| { - control_flow.set_poll(); - - if let Event::RedrawRequested(_) = event { - life.draw(pixels.get_frame()); - pixels.render().expect("failed to render"); - } - - if input.update(&event) { - if input.quit() { - control_flow.set_exit(); - return; - }; - - life.update(); - window.request_redraw(); - }; - }); -} - -#[derive(Clone, Copy, Debug)] -enum Cell { - Alive, - Dead { since: u8 }, -} - -#[derive(Debug)] -struct Grid { - pub cells: [[Cell; RES_X]; RES_Y], -} - -enum FrontGrid { - A, - B, -} - -struct Life { - grid_a: Grid, - grid_b: Grid, - front_grid: FrontGrid, -} - -impl Cell { - pub fn is_alive(&self) -> bool { - match self { - Cell::Alive => true, - Cell::Dead { .. } => false, - } - } -} - -impl Grid { - pub fn blank() -> Self { - Self { - cells: [[Cell::Dead { since: 0xff }; RES_X]; RES_Y], - } - } - - pub fn with_random_borders() -> Self { - let mut ret = Self::blank(); - ret.randomize_border(); - ret - } - - pub fn randomize_border(&mut self) { - self.cells[RES_X - 1] = rand::random(); - } - - pub fn draw(&self, frame: &mut [u8]) { - for row in 0..RES_X { - for col in 0..RES_Y { - let pixel_idx = 4 * (RES_X * row + col); - - match self.cells[row][col] { - Cell::Alive => { - frame[pixel_idx + 0] = 0xff; // R - frame[pixel_idx + 1] = 0xff; // G - frame[pixel_idx + 2] = 0xff; // B - frame[pixel_idx + 3] = 0xff; // A - } - Cell::Dead { since } => { - frame[pixel_idx + 0] = 0xff - since.saturating_mul(16); // R - frame[pixel_idx + 1] = if since < 0x8 { - 0 - } else { - (since - 0x8).saturating_mul(0x8) / 2 - }; - // G - frame[pixel_idx + 2] = 0xff; // B - frame[pixel_idx + 3] = 0xff - since; // A - } - }; - } - } - } - - pub fn num_alive_neighbors(&self, row: usize, col: usize) -> u8 { - let mut ret = 0; - - for i in row.saturating_sub(1)..=(row + 1).min(RES_X - 1) { - for j in col.saturating_sub(1)..=(col + 1).min(RES_Y - 1) { - if self.cells[i][j].is_alive() { - ret += 1; - } - } - } - if self.cells[row][col].is_alive() { - ret -= 1; - } - - ret - } - - pub fn new_state(&self, row: usize, col: usize) -> Cell { - match self.cells[row][col] { - Cell::Alive => { - if (2..=3).contains(&self.num_alive_neighbors(row, col)) { - Cell::Alive - } else { - Cell::Dead { since: 0 } - } - } - Cell::Dead { since } => { - if self.num_alive_neighbors(row, col) == 3 { - Cell::Alive - } else { - Cell::Dead { - since: since.saturating_add(1), - } - } - } - } - } -} - -impl Life { - pub fn new() -> Self { - Life { - grid_a: Grid::with_random_borders(), - grid_b: Grid::blank(), - front_grid: FrontGrid::A, - } - } - - pub fn draw(&self, frame: &mut [u8]) { - self.front_grid().draw(frame); - } - - pub fn update(&mut self) { - let (front, back) = self.grids(); - - for row in 0..RES_X { - for col in 0..RES_Y { - back.cells[row][col] = front.new_state(row, col); - } - } - back.randomize_border(); - - self.swap_grids(); - } - - fn grids(&mut self) -> (&Grid, &mut Grid) { - match self.front_grid { - FrontGrid::A => (&self.grid_a, &mut self.grid_b), - FrontGrid::B => (&self.grid_b, &mut self.grid_a), - } - } - - fn front_grid(&self) -> &Grid { - match self.front_grid { - FrontGrid::A => &self.grid_a, - FrontGrid::B => &self.grid_b, - } - } - - fn swap_grids(&mut self) { - self.front_grid = match self.front_grid { - FrontGrid::A => FrontGrid::B, - FrontGrid::B => FrontGrid::A, - } - } -} - -impl Distribution for Standard { - fn sample(&self, rng: &mut R) -> Cell { - if rng.gen() { - Cell::Alive - } else { - Cell::Dead { since: 0xff } - } - } -} -- cgit 1.4.1