use sdl2::render::Canvas; use sdl2::pixels::Color; use sdl2::video::Window; use sdl2::rect::Rect; use std::cmp; use std::{thread, time}; use std::time::{Duration, SystemTime}; pub const SCREEN_SIZE: u32 = 800; pub const PX_SIZE: u32 = 2; pub const BLACK: Color = Color::RGB(0, 0, 0); pub const WHITE: Color = Color::RGB(255, 255, 255); pub trait Cell { fn color(&self) -> [f32; 4]; } #[derive(Clone)] pub struct ConwayCell { color: Color, alive: bool, } /* impl Cell { pub fn clone(&self) -> Cell { Cell{color: self.color} } }*/ pub struct App { steps_per_sec: u64, px_size: i32, grid: Vec>, canvas: Canvas, } impl App { fn render (&mut self) { self.canvas.set_draw_color(Color::RGB(0, 0, 0)); self.canvas.clear(); for y in 0..self.grid.len() { for x in 0..self.grid[y].len() { if self.grid[y][x].alive { self.canvas.set_draw_color(self.grid[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)); } } } /* for (y, row) in grid.iter().enumerate() { for (x, cell) in row.iter().enumerate() { rectangle( cell.color, rectangle::square((x as u32 * px_size) as f64, (y as u32 * px_size) as f64, px_size as f64), c.transform, gl) } }*/ self.canvas.present(); } fn evolve(&mut self) { let mut new_grid = vec![vec![ConwayCell{color: BLACK, alive: false}; self.grid.len()]; self.grid.len()]; for y in 0..self.grid.len() { for x in 0..self.grid[y].len() { let mut nalive = 0; 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].alive { nalive += 1; } } } if self.grid[y][x].alive { if nalive == 2 || nalive == 3 { new_grid[y][x] = ConwayCell{color: WHITE, alive: true} } } else if nalive == 3 { new_grid[y][x] = ConwayCell{color: WHITE, alive: true} } } } self.grid = new_grid; } } fn main() { let sdl_context = sdl2::init().unwrap(); let video_subsystem = sdl_context.video().unwrap(); let window = video_subsystem.window("Microworlds", SCREEN_SIZE, SCREEN_SIZE).build().unwrap(); let size: usize = (SCREEN_SIZE/PX_SIZE) as usize; let mut grid = vec![vec![ConwayCell{color: BLACK, alive: false}; size]; size]; println!("size:{}", size); // r pemento let centery = size/2; let centerx = size/2; println!("centery:{} centerx:{}", centery, centerx); grid[centery][centerx] = ConwayCell{color: WHITE, alive: true}; grid[centery+1][centerx] = ConwayCell{color: WHITE, alive: true}; grid[centery-1][centerx] = ConwayCell{color: WHITE, alive: true}; grid[centery-1][centerx-1] = ConwayCell{color: WHITE, alive: true}; grid[centery][centerx+1] = ConwayCell{color: WHITE, alive: true}; // Let's create a Canvas which we will use to draw in our Window let canvas : Canvas = window.into_canvas() .present_vsync() //< this means the screen cannot // render faster than your display rate (usually 60Hz or 144Hz) .build().unwrap(); let mut app = App { steps_per_sec: 32, px_size: PX_SIZE as i32, grid: grid, canvas: canvas, }; let mut frame = 0; let mut event_pump = sdl_context.event_pump().unwrap(); 'main: loop { for event in event_pump.poll_iter() { match event { sdl2::event::Event::Quit {..} => break 'main, _ => {}, } } let start_rend = SystemTime::now(); app.render(); let render_time = start_rend.elapsed().unwrap(); let start_evo = SystemTime::now(); app.evolve(); let evo_time = start_evo.elapsed().unwrap(); let total_time = start_rend.elapsed().unwrap(); frame += 1; println!("frame: {} - render time: {:?} | evolve time: {:?} | total time: {:?}", frame, render_time, evo_time, total_time); thread::sleep(time::Duration::from_millis(1000 / app.steps_per_sec)); } }