microworlds-rs/src/life.rs

101 lines
2.5 KiB
Rust

use std::cmp;
use super::{Cell, Engine, Grid, WHITE, BLACK};
pub struct LifeEngine {
grid: Grid<bool>,
}
pub fn new(size: usize) -> LifeEngine {
let mut life = LifeEngine{grid: Grid::new(false, size)};
// r pemento
let centery = size/2;
let centerx = size/2;
life.grid.set(centery, centerx,true);
life.grid.set(centery+1, centerx, true);
life.grid.set(centery-1, centerx, true);
life.grid.set(centery-1, centerx-1, true);
life.grid.set(centery, centerx+1, true);
life
}
impl LifeEngine {
fn nalive(&self, y: usize, x: usize) -> u8 {
let mut nalive = 0;
if y > 0 {
if x > 0 {
if *self.grid.get(y-1, x-1) {
nalive += 1;
}
}
if *self.grid.get(y-1, x) {
nalive += 1;
}
if x < self.grid.size()-1 {
if *self.grid.get(y-1, x+1) {
nalive += 1;
}
}
}
if x > 0 {
if *self.grid.get(y, x-1) {
nalive += 1;
}
}
if x < self.grid.size()-1 {
if *self.grid.get(y, x+1) {
nalive += 1;
}
}
if y < self.grid.size()-1 {
if x > 0 {
if *self.grid.get(y+1, x-1) {
nalive += 1;
}
}
if *self.grid.get(y+1, x) {
nalive += 1;
}
if x < self.grid.size()-1 {
if *self.grid.get(y+1, x+1) {
nalive += 1;
}
}
}
nalive
}
}
impl Engine for LifeEngine {
fn evolve(&mut self) -> super::Grid<Cell> {
let mut new_render_grid = super::Grid::new(Cell{color: BLACK}, self.grid.size());
let mut new_life_grid = Grid::new(false, self.grid.size());
for y in 0..self.grid.size() {
for x in 0..self.grid.size() {
let nalive = self.nalive(y, x);
if *self.grid.get(y, x) {
if nalive == 2 || nalive == 3 {
new_render_grid.set(y, x, Cell{color: WHITE});
new_life_grid.set(y, x, true);
}
} else if nalive == 3 {
new_render_grid.set(y, x, Cell{color: WHITE});
new_life_grid.set(y, x, true);
}
}
}
self.grid = new_life_grid;
new_render_grid
}
}