mirror of
https://github.com/eRgo35/game-of-life.git
synced 2026-02-04 04:26:10 +01:00
initial game finished
This commit is contained in:
136
src/board.rs
Normal file
136
src/board.rs
Normal file
@@ -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<Vec<Cell>>,
|
||||||
|
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<Cell>], 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<Vec<Cell>> {
|
||||||
|
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<Vec<Cell>> = 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;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
69
src/main.rs
69
src/main.rs
@@ -1,75 +1,14 @@
|
|||||||
use rand::Rng;
|
mod board;
|
||||||
|
use board::Board;
|
||||||
|
|
||||||
use std::{thread, time};
|
use std::{thread, time};
|
||||||
|
|
||||||
struct Board {
|
|
||||||
cells: Vec<Vec<Cell>>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[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<Vec<Cell>> {
|
|
||||||
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() {
|
fn main() {
|
||||||
let one_second = time::Duration::from_millis(1000);
|
let one_second = time::Duration::from_millis(1000);
|
||||||
let mut board = Board::init(32, 32);
|
let mut board = Board::init(32, 32);
|
||||||
loop {
|
loop {
|
||||||
board.render();
|
board.render();
|
||||||
thread::sleep(one_second);
|
thread::sleep(one_second/15);
|
||||||
board.next_generation();
|
board.next_generation();
|
||||||
clearscreen::clear().expect("Failed to clear screen");
|
clearscreen::clear().expect("Failed to clear screen");
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user