From d727456cead9011d6ad4edcdb223f4251d1d074f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20Czy=C5=BC?= Date: Sun, 30 Jun 2024 19:19:49 +0200 Subject: [PATCH] initial game finished --- src/board.rs | 136 +++++++++++++++++++++++++++++++++++++++++++++++++++ src/main.rs | 69 ++------------------------ 2 files changed, 140 insertions(+), 65 deletions(-) create mode 100644 src/board.rs diff --git a/src/board.rs b/src/board.rs new file mode 100644 index 0000000..e2abbc6 --- /dev/null +++ b/src/board.rs @@ -0,0 +1,136 @@ +use rand::Rng; + +#[derive(Clone, PartialEq)] +enum State { + Alive, + Dead, +} + +#[derive(Clone)] +pub struct Cell { + state: State, +} + +pub struct Board { + cells: Vec>, + width: usize, + height: usize, +} + +impl Board { + // fn dead_state() -> State { + // State::Dead + // } + + // fn alive_state() -> State { + // State::Alive + // } + + fn random_state() -> State { + let mut rng = rand::thread_rng(); + + match rng.gen_bool(0.5) { + true => State::Alive, + false => State::Dead, + } + } + + fn count_alive_neightbors(cells: &[Vec], i: usize, j: usize) -> usize { + let mut alive_neightbors = 0; + + let a_lim = cells.len() as i32; + let b_lim = cells[i].len() as i32; + + for a in 0..3 { + for b in 0..3 { + let row: i32 = i as i32 + 1 - a; + let col: i32 = j as i32 + 1 - b; + + if a == 1 && b == 1 { + continue; + } + + if row < 0 || col < 0 || row >= a_lim || col >= b_lim { + continue; + } + + if cells[row as usize][col as usize].state == State::Alive { + alive_neightbors += 1; + } + } + } + + alive_neightbors + } + + fn generate_cells(width: usize, height: usize, state: &dyn Fn() -> State) -> Vec> { + let mut cells = Vec::new(); + + for _ in 0..height { + let mut row = Vec::new(); + for _ in 0..width { + row.push(Cell { state: state() }); + } + cells.push(row); + } + + cells + } + + pub fn init(width: usize, height: usize) -> Self { + let cells = Self::generate_cells(width, height, &Self::random_state); + + Self { + cells, + width, + height, + } + } + + pub fn render(&self) { + for row in &self.cells { + for cell in row { + match cell.state { + State::Alive => print!("██"), + State::Dead => print!(" "), + } + } + println!(); + } + } + + pub fn next_generation(&mut self) { + let width = self.width; + let height = self.height; + let cells = self.cells.clone(); + + let mut new_cells: Vec> = cells.clone(); + + for i in 0..width { + for j in 0..height { + let current_cell = &cells[i][j]; + let alive_neightbors = Self::count_alive_neightbors(&cells, i, j); + + // Main Gmae Logic + // TODO: Optimize and remove magic numbers + match current_cell.state { + State::Alive => { + // Any live cell with less than two or more than three live neighbours survives. + if !(2..=3).contains(&alive_neightbors) { + new_cells[i][j].state = State::Dead; + } + }, + State::Dead => { + // Any dead cell with three live neighbours becomes a live cell. + if alive_neightbors == 3 { + new_cells[i][j].state = State::Alive; + } + }, + } + } + } + + self.cells = new_cells; + + } +} diff --git a/src/main.rs b/src/main.rs index 55c0c73..e60d65b 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,75 +1,14 @@ -use rand::Rng; +mod board; +use board::Board; + use std::{thread, time}; -struct Board { - cells: Vec>, -} - -#[derive(Clone)] -struct Cell { - state: State, -} - -#[derive(Clone)] -enum State { - Alive, - Dead, -} - -impl Board { - fn random_state() -> State { - let mut rng = rand::thread_rng(); - - match rng.gen_bool(0.5) { - true => State::Alive, - false => State::Dead - } - } - - fn generate_cells(width: usize, height: usize) -> Vec> { - let mut cells = Vec::new(); - - for _ in 0..height { - let mut row = Vec::new(); - for _ in 0..width { - row.push(Cell { state: Self::random_state() }); - } - cells.push(row); - } - - cells - } - - pub fn init(width: usize, height: usize) -> Self { - let cells = Self::generate_cells(width, height); - - Self { cells } - } - - pub fn render(&self) { - for row in &self.cells { - for cell in row { - match cell.state { - State::Alive => print!("██"), - State::Dead => print!(" "), - } - } - println!(); - } - } - - pub fn next_generation(&mut self) { - let cells = Self::generate_cells(self.cells.len(), self.cells[0].len()); - self.cells = cells; - } -} - fn main() { let one_second = time::Duration::from_millis(1000); let mut board = Board::init(32, 32); loop { board.render(); - thread::sleep(one_second); + thread::sleep(one_second/15); board.next_generation(); clearscreen::clear().expect("Failed to clear screen"); }