Skip to content

Instantly share code, notes, and snippets.

@madorama
Created October 17, 2020 04:48
Show Gist options
  • Select an option

  • Save madorama/f387887d6c8304d307bf74abfe38066e to your computer and use it in GitHub Desktop.

Select an option

Save madorama/f387887d6c8304d307bf74abfe38066e to your computer and use it in GitHub Desktop.
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