diff --git a/src/lib.rs b/src/lib.rs index 501db3b..9dbfe9a 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -11,6 +11,30 @@ pub mod life; pub const BLACK: Color = Color::RGB(0, 0, 0); pub const WHITE: Color = Color::RGB(255, 255, 255); +pub struct Grid { + size: usize, + flat_grid: Vec, +} + +impl Grid + where T: Clone +{ + pub fn new(default: T, size: usize) -> Grid { + Grid:: {size: size, flat_grid: vec![default; size*size]} + } + + pub fn get(&self, y: usize, x: usize) -> &T { + &self.flat_grid[ y*self.size + x ] + } + + pub fn set(&mut self, y: usize, x: usize, val: T) { + self.flat_grid[ y*self.size + x ] = val; + } + + pub fn size(&self) -> usize { + self.size + } +} #[derive(Clone)] @@ -19,7 +43,7 @@ pub struct Cell { } pub trait Engine { - fn evolve(&mut self) -> Vec>; + fn evolve(&mut self) -> Grid; } pub struct Renderer { @@ -32,14 +56,14 @@ impl Renderer { Renderer { px_size: px_size, canvas: canvas } } - pub fn render(&mut self, grid: &Vec>) { + pub fn render(&mut self, grid: Grid) { self.canvas.set_draw_color(BLACK); self.canvas.clear(); - for y in 0..grid.len() { - for x in 0..grid[y].len() { + for y in 0..grid.size() { + for x in 0..grid.size() { //if grid[y][x].alive { - self.canvas.set_draw_color(grid[y][x].color); + self.canvas.set_draw_color(grid.get(y, x).color); self.canvas.fill_rect(Rect::new(x as i32 * self.px_size, y as i32 * self.px_size, self.px_size as u32, self.px_size as u32)); //} } diff --git a/src/life.rs b/src/life.rs index a6efca6..5713134 100644 --- a/src/life.rs +++ b/src/life.rs @@ -1,70 +1,96 @@ use std::cmp; -use super::{Cell, Engine, WHITE, BLACK}; +use super::{Cell, Engine, Grid, WHITE, BLACK}; pub struct LifeEngine { - grid: Vec>, + grid: Grid, } pub fn new(size: usize) -> LifeEngine { - let mut life = LifeEngine{grid: vec![vec![false; size]; size]}; + let mut life = LifeEngine{grid: Grid::new(false, size)}; // r pemento let centery = size/2; let centerx = size/2; - life.grid[centery][centerx] = true; - life.grid[centery+1][centerx] = true; - life.grid[centery-1][centerx] = true; + life.grid.set(centery, centerx,true); + life.grid.set(centery+1, centerx, true); + life.grid.set(centery-1, centerx, true); - life.grid[centery-1][centerx-1] = true; - life.grid[centery][centerx+1] = 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) -> Vec> { - let mut new_render_grid = vec![vec![Cell{color: BLACK}; self.grid.len()]; self.grid.len()]; - let mut new_life_grid = vec![vec![false; self.grid.len()]; self.grid.len()]; + fn evolve(&mut self) -> super::Grid { + 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.len() { - for x in 0..self.grid[y].len() { - let mut nalive = 0; + for y in 0..self.grid.size() { + for x in 0..self.grid.size() { + let nalive = self.nalive(y, x); - let mut ylow = 0; - if y > 1 { - ylow = y-1; - } - let yhigh = cmp::min(self.grid.len()-1, y+1); - - let mut xlow = 0; - if x > 1 { - xlow = x-1; - } - let xhigh = cmp::min(self.grid.len()-1, x+1); - - for i in ylow..yhigh+1 { - for j in xlow..xhigh+1 { - if i == y && j == x { - continue; - } - if self.grid[i][j] { - nalive += 1; - } - } - } - - if self.grid[y][x] { + if *self.grid.get(y, x) { if nalive == 2 || nalive == 3 { - new_render_grid[y][x] = Cell{color: WHITE}; - new_life_grid[y][x] = true; + new_render_grid.set(y, x, Cell{color: WHITE}); + new_life_grid.set(y, x, true); } } else if nalive == 3 { - new_render_grid[y][x] = Cell{color: WHITE}; - new_life_grid[y][x] = true; + new_render_grid.set(y, x, Cell{color: WHITE}); + new_life_grid.set(y, x, true); } } } diff --git a/src/main.rs b/src/main.rs index f321eb6..b88987d 100644 --- a/src/main.rs +++ b/src/main.rs @@ -5,6 +5,7 @@ use std::{thread, time}; use std::time::{SystemTime}; use microworlds::Engine; +use microworlds::Grid; pub const SCREEN_SIZE: u32 = 800; pub const PX_SIZE: u32 = 2; @@ -16,7 +17,7 @@ fn main() { let window = video_subsystem.window("Microworlds", SCREEN_SIZE, SCREEN_SIZE).build().unwrap(); println!("Window: {}x{} at {} px per cell", SCREEN_SIZE, SCREEN_SIZE, PX_SIZE); let size: usize = (SCREEN_SIZE/PX_SIZE) as usize; - let mut grid = vec![vec![microworlds::Cell{color: microworlds::BLACK}; size]; size]; + let mut grid = Grid::new(microworlds::Cell{color: microworlds::BLACK}, size); println!("cell grid: {}x{} ({} cells) - {} steps per sec", size, size, (size*size), STEPS_PER_SEC); @@ -44,7 +45,7 @@ fn main() { } let start_rend = SystemTime::now(); - renderer.render(&grid); + renderer.render(grid); let render_time = start_rend.elapsed().unwrap(); let start_evo = SystemTime::now(); grid = engine.evolve();