optimizations: move all things to Grid (1 Vec internal) and life uses nalive() (8 ifs instead of 2 loops)
This commit is contained in:
parent
6381d02fb9
commit
02a3f3aad1
34
src/lib.rs
34
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<T: Clone> {
|
||||
size: usize,
|
||||
flat_grid: Vec<T>,
|
||||
}
|
||||
|
||||
impl<T> Grid<T>
|
||||
where T: Clone
|
||||
{
|
||||
pub fn new(default: T, size: usize) -> Grid<T> {
|
||||
Grid::<T> {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<Vec<Cell>>;
|
||||
fn evolve(&mut self) -> Grid<Cell>;
|
||||
}
|
||||
|
||||
pub struct Renderer {
|
||||
|
@ -32,14 +56,14 @@ impl Renderer {
|
|||
Renderer { px_size: px_size, canvas: canvas }
|
||||
}
|
||||
|
||||
pub fn render(&mut self, grid: &Vec<Vec<Cell>>) {
|
||||
pub fn render(&mut self, grid: Grid<Cell>) {
|
||||
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));
|
||||
//}
|
||||
}
|
||||
|
|
100
src/life.rs
100
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<Vec<bool>>,
|
||||
grid: Grid<bool>,
|
||||
}
|
||||
|
||||
|
||||
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 Engine for LifeEngine {
|
||||
fn evolve(&mut self) -> Vec<Vec<Cell>> {
|
||||
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()];
|
||||
|
||||
for y in 0..self.grid.len() {
|
||||
for x in 0..self.grid[y].len() {
|
||||
impl LifeEngine {
|
||||
fn nalive(&self, y: usize, x: usize) -> u8 {
|
||||
let mut nalive = 0;
|
||||
|
||||
let mut ylow = 0;
|
||||
if y > 1 {
|
||||
ylow = y-1;
|
||||
if y > 0 {
|
||||
if x > 0 {
|
||||
if *self.grid.get(y-1, x-1) {
|
||||
nalive += 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.get(y-1, x) {
|
||||
nalive += 1;
|
||||
}
|
||||
if self.grid[i][j] {
|
||||
if x < self.grid.size()-1 {
|
||||
if *self.grid.get(y-1, x+1) {
|
||||
nalive += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if self.grid[y][x] {
|
||||
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[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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
|
Loading…
Reference in New Issue