diff --git a/src/cell.rs b/src/cell.rs new file mode 100644 index 0000000..4b185e8 --- /dev/null +++ b/src/cell.rs @@ -0,0 +1,20 @@ +#[derive(Debug, Clone, Copy, PartialEq)] +pub enum CellType { + Empty = 0, + Sand, +} + +#[derive(Debug, Clone, Copy)] +pub enum MovementType { + None = 0b0000_0000, + Down = 0b0000_0001, + Side = 0b0000_0010, + DownSide = 0b0000_0011, +} + +#[derive(Debug, Clone, Copy)] +pub struct Cell { + pub cell_type: CellType, + pub movement_type: MovementType, + pub color: u32, +} diff --git a/src/engine.rs b/src/engine.rs index 8135807..8a50411 100644 --- a/src/engine.rs +++ b/src/engine.rs @@ -5,13 +5,15 @@ use minifb::{Key, Window, WindowOptions}; const WIDTH: usize = 800; const HEIGHT: usize = 600; -use crate::{materials::*, rand::Random}; +use crate::{materials::*, rand::Random, world::World}; pub struct Engine { pub window: Window, - pub buffer: Vec, + pub front_buffer: Vec, pub brush_size: usize, pub random: Random, + + pub world: World, } impl Engine { @@ -26,9 +28,10 @@ impl Engine { .unwrap_or_else(|e| { panic!("{}", e); }), - buffer: vec![0; WIDTH * HEIGHT], + front_buffer: vec![0; WIDTH * HEIGHT], brush_size: 1, random: Random::new(0), + world: World::new(), } } @@ -83,19 +86,13 @@ impl Engine { for x in 0..WIDTH { for y in 0..HEIGHT { let index = xy_to_i(x, y); - let cell = self.buffer[index]; + let cell = self.front_buffer[index]; if cell == SAND { let down = self.is_empty(x, y + 1); - let mut left = self.is_empty(x - 1, y + 1); - let mut right = self.is_empty(x + 1, y + 1); - - if left && right { - // TODO: handle left/right randomization here - let rand = self.random.random_bool(); - left = rand; - right = !rand; - } + let random = self.random.random_bool(); + let left = self.is_empty(x - 1, y + 1) && random; + let right = self.is_empty(x + 1, y + 1) ^ left; if down { self.set_cell(x, y + 1, SAND) @@ -113,7 +110,7 @@ impl Engine { } // TODO Handle this. self.window - .update_with_buffer(&self.buffer, WIDTH, HEIGHT) + .update_with_buffer(&self.front_buffer, WIDTH, HEIGHT) .unwrap(); } } @@ -122,18 +119,18 @@ impl Engine { impl Engine { fn is_empty(&mut self, x: usize, y: usize) -> bool { let index = xy_to_i(x, y); - if index >= self.buffer.len() { + if index >= self.front_buffer.len() { false } else { - self.buffer[index] == EMPTY + self.front_buffer[index] == EMPTY } } fn set_cell(&mut self, x: usize, y: usize, mat: u32) { let index = xy_to_i(x, y); - if index >= self.buffer.len() { + if index >= self.front_buffer.len() { } else { - self.buffer[index] = mat; + self.front_buffer[index] = mat; } } @@ -141,7 +138,7 @@ impl Engine { for x in 0..WIDTH { for y in 0..HEIGHT { let index = xy_to_i(x, y); - self.buffer[index] = EMPTY; + self.front_buffer[index] = EMPTY; } } } diff --git a/src/main.rs b/src/main.rs index e29f2f7..7455dcf 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,6 +1,8 @@ +mod cell; mod engine; mod materials; mod rand; +mod world; fn main() { let mut engine = engine::Engine::new(); diff --git a/src/world.rs b/src/world.rs new file mode 100644 index 0000000..c38648e --- /dev/null +++ b/src/world.rs @@ -0,0 +1,57 @@ +use crate::cell::{Cell, MovementType}; + +use crate::cell::CellType::Empty; +use crate::engine::xy_to_i; +use crate::materials::EMPTY; + +const WIDTH: usize = 800; +const HEIGHT: usize = 600; + +pub struct World { + pub width: usize, + pub height: usize, + pub cells: Vec, +} +impl World { + pub fn new() -> Self { + Self { + width: WIDTH, + height: HEIGHT, + cells: vec![ + Cell { + cell_type: Empty, + movement_type: MovementType::None, + color: 0 + }; + WIDTH * HEIGHT + ], + } + } +} + +impl World { + pub fn get_xy(&mut self, x: usize, y: usize) -> Cell { + let index = x + self.width * y; + + self.cells[index] + } + + pub fn get_i(&mut self, index: usize) -> Cell { + self.cells[index] + } + + pub fn is_empty(&mut self, x: usize, y: usize) -> bool { + in_bounds(x, y) && self.get_xy(x, y).cell_type == Empty + } + + pub fn set_xy(&mut self, x: usize, y: usize, cell: Cell) { + self.cells[xy_to_i(x, y)] = cell + } +} + +pub fn in_bounds(x: usize, y: usize) -> bool { + let x_in_bounds = x < WIDTH; + let y_in_bounds = y < HEIGHT; + + x_in_bounds && y_in_bounds +}