Created
October 17, 2020 04:48
-
-
Save madorama/f387887d6c8304d307bf74abfe38066e to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| pub trait CA<T> { | |
| fn rule(&self, x: usize, y: usize) -> T; | |
| fn update(&mut self) -> (); | |
| fn render(&self) -> String; | |
| } | |
| mod lifegame { | |
| #[derive(Copy, Clone, PartialEq)] | |
| pub enum CellStatus { | |
| Dead, | |
| Alive, | |
| } | |
| pub struct Lifegame { | |
| world: Vec<Vec<CellStatus>>, | |
| width: usize, | |
| height: usize, | |
| } | |
| use rand::Rng; | |
| pub fn random_init(w: usize, h: usize) -> Lifegame { | |
| let mut rng = rand::thread_rng(); | |
| let world = (0..w).map(|_| { | |
| (0..h).map(|_| { | |
| if rng.gen_range(0.0, 1.0) >= 0.3 { | |
| CellStatus::Dead | |
| } else { | |
| CellStatus::Alive | |
| } | |
| }).collect() | |
| }).collect(); | |
| Lifegame { | |
| world, | |
| width: w, | |
| height: h, | |
| } | |
| } | |
| fn cell_status_to_i32(cell: &CellStatus) -> i32 { | |
| match cell { | |
| CellStatus::Dead => { 0 } | |
| CellStatus::Alive => { 1 } | |
| } | |
| } | |
| fn next_life(now_cell: CellStatus, alive_count: i32) -> CellStatus { | |
| match (now_cell, alive_count) { | |
| (CellStatus::Dead, 3) => CellStatus::Alive, | |
| (CellStatus::Alive, x) if x == 2 || x == 3 => CellStatus::Alive, | |
| (CellStatus::Alive, x) if x <= 1 || x >= 4 => CellStatus::Dead, | |
| (_, _) => now_cell | |
| } | |
| } | |
| use crate::CA; | |
| impl CA<CellStatus> for Lifegame { | |
| fn rule(&self, px: usize, py: usize) -> CellStatus { | |
| let mut live_cell_num = 0; | |
| for iy in -1..2 { | |
| for ix in -1..2 { | |
| if ix == 0 && iy == 0 { continue } | |
| let (x, y) = (px as i32 + ix, py as i32 + iy); | |
| if x < 0 || x >= self.width as i32 || y < 0 || y >= self.height as i32 { continue } | |
| live_cell_num += cell_status_to_i32(&self.world[x as usize][y as usize]) | |
| } | |
| } | |
| let cell = self.world[px][py]; | |
| next_life(cell, live_cell_num) | |
| } | |
| fn update(&mut self) { | |
| let mut next = self.world.clone(); | |
| for iy in 0..self.height { | |
| for ix in 0..self.width { | |
| next[ix][iy] = self.rule(ix, iy); | |
| } | |
| } | |
| self.world = next | |
| } | |
| fn render(&self) -> String { | |
| let mut str = String::from(""); | |
| for line in &self.world { | |
| for cell in line { | |
| let symbol = if *cell == CellStatus::Dead { "." } else { "*" }; | |
| str.push_str(symbol); | |
| } | |
| str.push_str("\n") | |
| } | |
| str | |
| } | |
| } | |
| } | |
| fn main() { | |
| let mut game = lifegame::random_init(50, 50); | |
| for _ in 0..100 { | |
| println!("{}", game.render()); | |
| game.update(); | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment