Advertisement
Guest User

Game of life

a guest
May 12th, 2019
132
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Rust 4.38 KB | None | 0 0
  1. extern crate minifb;
  2. use std::mem;
  3. use std::time::SystemTime;
  4. use std::usize;
  5.  
  6. use minifb::{Key, MouseButton, MouseMode, Window, WindowOptions};
  7.  
  8. const CELL_SIZE: usize = 8;
  9. const GRID_SIZE: usize = 100;
  10.  
  11. const WIDTH: usize = CELL_SIZE * GRID_SIZE;
  12. const HEIGHT: usize = CELL_SIZE * GRID_SIZE;
  13.  
  14. const CELL_WIDTH: usize = GRID_SIZE;
  15. const CELL_HEIGHT: usize = GRID_SIZE;
  16.  
  17. struct Grid {
  18.     front_buffer: Vec<bool>,
  19.     back_buffer: Vec<bool>
  20. }
  21.  
  22. impl Grid {
  23.     fn compute_neighbour(&self, x: usize, y: usize) -> u32 {
  24.         let mut count = 0u32;
  25.  
  26.         if self.get_cell_value(x.wrapping_sub(1), y.wrapping_sub(1)) { count += 1; }
  27.         if self.get_cell_value(x,                   y.wrapping_sub(1)) { count += 1; }
  28.         if self.get_cell_value(x.wrapping_add(1), y.wrapping_sub(1)) { count += 1; }
  29.         if self.get_cell_value(x.wrapping_sub(1), y) { count += 1; }
  30.         if self.get_cell_value(x.wrapping_add(1), y) { count += 1; }
  31.         if self.get_cell_value(x.wrapping_sub(1), y.wrapping_add(1)) { count += 1; }
  32.         if self.get_cell_value(x,                   y.wrapping_add(1)) { count += 1; }
  33.         if self.get_cell_value(x.wrapping_add(1), y.wrapping_add(1)) { count += 1; }
  34.  
  35.         count
  36.     }
  37.  
  38.     fn get_xy(value: usize, x: &mut usize, y: &mut usize) {
  39.         *x = value % GRID_SIZE;
  40.         *y = value / GRID_SIZE;
  41.     }
  42.  
  43.     fn get_cell_value(&self, x: usize, y: usize) -> bool {
  44.         if !Grid::is_in_bounds(x, y) {
  45.             return false;
  46.         }
  47.  
  48.         self.front_buffer[y * GRID_SIZE + x]
  49.     }
  50.  
  51.     fn is_in_bounds(x: usize, y: usize) -> bool {
  52.         x < GRID_SIZE && y < GRID_SIZE
  53.     }
  54.  
  55.     fn swap_buffers(&mut self) {
  56.         mem::swap(&mut self.front_buffer, &mut self.back_buffer);
  57.     }
  58.  
  59.     fn update(&mut self) {
  60.         for (index, _) in self.front_buffer.iter().enumerate() {
  61.             let mut x = 0usize;
  62.             let mut y = 0usize;
  63.             Grid::get_xy(index, &mut x, &mut y);
  64.  
  65.             self.back_buffer[index] = match self.compute_neighbour(x, y) {
  66.                 2 => self.front_buffer[index],
  67.                 3 => true,
  68.                 _ => false
  69.             };
  70.         }
  71.  
  72.         self.swap_buffers();
  73.     }
  74. }
  75.  
  76. fn main() {
  77.     let mut buffer: Vec<u32> = vec![0; WIDTH * HEIGHT];
  78.  
  79.     let mut grid = Grid {
  80.         front_buffer: vec![false; CELL_WIDTH * CELL_HEIGHT],
  81.         back_buffer:  vec![false; CELL_WIDTH * CELL_HEIGHT]
  82.     };
  83.  
  84.     grid.front_buffer[(1 * GRID_SIZE) + 1] = true;
  85.     grid.front_buffer[(1 * GRID_SIZE) + 2] = true;
  86.     grid.front_buffer[(1 * GRID_SIZE) + 3] = true;
  87.  
  88.     grid.update();
  89.  
  90.     let mut window = Window::new(
  91.         "Test - ESC to exit",
  92.         WIDTH,
  93.         HEIGHT,
  94.         WindowOptions::default(),
  95.     )
  96.     .unwrap_or_else(|e| {
  97.         panic!("{}", e);
  98.     });
  99.  
  100.     let mut clock = SystemTime::now();
  101.  
  102.     while window.is_open() && !window.is_key_down(Key::Escape) {
  103.         window.get_mouse_pos(MouseMode::Discard).map(|mouse| {
  104.             // map mouse position to grid cell position
  105.             let cell_x = mouse.0 as usize / CELL_SIZE;
  106.             let cell_y = mouse.1 as usize / CELL_SIZE;
  107.  
  108.             if window.get_mouse_down(MouseButton::Left) {
  109.                 grid.front_buffer[cell_y * CELL_WIDTH + cell_x] = true;
  110.             } else if window.get_mouse_down(MouseButton::Right) {
  111.                 grid.front_buffer[cell_y * CELL_WIDTH + cell_x] = false;
  112.             }
  113.         });
  114.  
  115.         if window.is_key_down(Key::Space) {
  116.             match clock.elapsed() {
  117.                 Ok(d) => {
  118.                     if d.as_millis() >= 100u128 {
  119.                         grid.update();
  120.                         clock = SystemTime::now();
  121.                     }
  122.                 },
  123.                 Err(err) => {
  124.                     println!("An error occurred: {}", err);
  125.                 }
  126.             }
  127.         }
  128.  
  129.         for (index, cell) in buffer.iter_mut().enumerate() {
  130.             let x = index % WIDTH;
  131.             let y = index / WIDTH;
  132.  
  133.             let cell_x = x / CELL_SIZE;
  134.             let cell_y = y / CELL_SIZE;
  135.  
  136.             *cell = if grid.front_buffer[cell_y * CELL_WIDTH + cell_x] { 0xFFFFFF } else { 0 };
  137.         }
  138.  
  139.         // We unwrap here as we want this code to exit if it fails. Real applications may want to handle this in a different way
  140.         window.update_with_buffer(&buffer).unwrap();
  141.     }
  142. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement