extern crate glutin_window; extern crate graphics; extern crate opengl_graphics; extern crate piston; use glutin_window::GlutinWindow as Window; use opengl_graphics::{GlGraphics, OpenGL}; use piston::event_loop::{EventSettings, Events}; use piston::input::{RenderArgs, RenderEvent, UpdateArgs, UpdateEvent}; use piston::window::WindowSettings; use graphics::Rectangle; use std::cmp; pub const SCREEN_SIZE: u32 = 800; pub const BLACK: [f32; 4] = [0.0, 0.0, 0.0, 1.0]; pub const WHITE: [f32; 4] = [1.0, 1.0, 1.0, 1.0]; pub trait Cell { fn color(&self) -> [f32; 4]; } #[derive(Clone)] pub struct ConwayCell { color: [f32; 4], alive: bool, } /* impl Cell { pub fn clone(&self) -> Cell { Cell{color: self.color} } }*/ pub struct App { gl: GlGraphics, steps_per_sec: f64, px_size: u32, dt_last: f64, grid: Vec>, } impl App { fn render (&mut self, args: &RenderArgs) { use graphics::*; let grid = &self.grid; let px_size = self.px_size; self.gl.draw(args.viewport(), |c, gl| { // Clear the screen. clear(BLACK, gl); for y in 0..grid.len() { for x in 0..grid[y].len() { if grid[y][x].alive { rectangle(grid[y][x].color, rectangle::square((x as u32 * px_size) as f64, (y as u32 * px_size) as f64, px_size as f64), c.transform, gl) } } } /* 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) } }*/ }); } fn update(&mut self, args: &UpdateArgs) { //println!("update and update.dt: {} with self.dt_last: {}", args.dt, self.dt_last); if args.dt + self.dt_last > (1.0 / self.steps_per_sec) { self.dt_last = 0.0; print!(">"); self.evolve(); } else { print!("."); self.dt_last += args.dt; } } 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() { // Change this to OpenGL::V2_1 if not working. let opengl = OpenGL::V3_2; // Create an Glutin window. let mut window: Window = WindowSettings::new("spinning-square", [SCREEN_SIZE, SCREEN_SIZE]) .graphics_api(opengl) .exit_on_esc(true) .build() .unwrap(); let px_size = 2; let size: usize = (SCREEN_SIZE/px_size) as usize; let mut grid = vec![vec![ConwayCell{color: BLACK, alive: false}; size]; size]; // r pemento println!("size:{} size/2:{}", size, size/2); 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 mut app = App { gl: GlGraphics::new(opengl), steps_per_sec: 30.0, px_size: px_size, dt_last: 0.0, grid: grid, }; println!("{:?}", EventSettings::new()); let mut events = Events::new(EventSettings::new()); while let Some(e) = events.next(&mut window) { if let Some(args) = e.render_args() { app.render(&args); } if let Some(args) = e.update_args() { app.update(&args); } } }