mirror of
https://gitlab1.ptb.de/waltem01/Matrix
synced 2024-12-26 12:01:45 +00:00
added comments to code
This commit is contained in:
parent
95467cb94f
commit
4808e7c78a
25
src/cell.rs
25
src/cell.rs
@ -6,6 +6,7 @@ use crate::K2;
|
|||||||
use crate::Q;
|
use crate::Q;
|
||||||
use crate::WIDTH;
|
use crate::WIDTH;
|
||||||
|
|
||||||
|
// Class to store information about each cell
|
||||||
#[derive(PartialEq)]
|
#[derive(PartialEq)]
|
||||||
pub struct Cell {
|
pub struct Cell {
|
||||||
pub x: u32,
|
pub x: u32,
|
||||||
@ -13,6 +14,7 @@ pub struct Cell {
|
|||||||
pub state: u32,
|
pub state: u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Type Enumerator to keep track of different state operations
|
||||||
#[derive(PartialEq)]
|
#[derive(PartialEq)]
|
||||||
enum StateOp {
|
enum StateOp {
|
||||||
Types,
|
Types,
|
||||||
@ -20,28 +22,34 @@ enum StateOp {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Cell {
|
impl Cell {
|
||||||
|
// Cell method to count neighbors depending on state operation
|
||||||
fn neighbor_count(&self, grid: &Vec<Vec<Cell>>, operation: StateOp) -> (u32, u32) {
|
fn neighbor_count(&self, grid: &Vec<Vec<Cell>>, operation: StateOp) -> (u32, u32) {
|
||||||
let mut infected: u32 = 0;
|
let mut infected: u32 = 0;
|
||||||
let mut states: u32 = 0;
|
let mut states: u32 = 0;
|
||||||
let mut sum: u32 = 0;
|
let mut sum: u32 = 0;
|
||||||
let mut ill: u32 = 0;
|
let mut ill: u32 = 0;
|
||||||
|
|
||||||
|
// Loop through neighbors
|
||||||
for j in -1..=1 {
|
for j in -1..=1 {
|
||||||
for i in -1..=1 {
|
for i in -1..=1 {
|
||||||
|
// Ignore self onlz if operation is generic 'types'
|
||||||
if i == 0 && j == 0 && operation == StateOp::Types {
|
if i == 0 && j == 0 && operation == StateOp::Types {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
// Get cell at position with wrap-around
|
||||||
let nx = (self.x as i32 + i + WIDTH as i32) % WIDTH as i32;
|
let nx = (self.x as i32 + i + WIDTH as i32) % WIDTH as i32;
|
||||||
let ny = (self.y as i32 + j + HEIGHT as i32) % HEIGHT as i32;
|
let ny = (self.y as i32 + j + HEIGHT as i32) % HEIGHT as i32;
|
||||||
let next = &grid[ny as usize][nx as usize];
|
let next = &grid[ny as usize][nx as usize];
|
||||||
let state = next.state;
|
let state = next.state;
|
||||||
|
|
||||||
|
// Count ill and infected cells
|
||||||
if operation == StateOp::Types {
|
if operation == StateOp::Types {
|
||||||
if state > 1 && state < Q - 1 {
|
if state > 1 && state < Q - 1 {
|
||||||
infected += 1;
|
infected += 1;
|
||||||
} else if state == Q - 1 {
|
} else if state == Q - 1 {
|
||||||
ill += 1;
|
ill += 1;
|
||||||
}
|
}
|
||||||
|
// Count and sum states around cell
|
||||||
} else {
|
} else {
|
||||||
sum += state;
|
sum += state;
|
||||||
if state == 1 && next != self {
|
if state == 1 && next != self {
|
||||||
@ -51,6 +59,7 @@ impl Cell {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Return results based on operation type
|
||||||
if operation == StateOp::Types {
|
if operation == StateOp::Types {
|
||||||
return (infected, ill);
|
return (infected, ill);
|
||||||
} else {
|
} else {
|
||||||
@ -59,38 +68,47 @@ impl Cell {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Initialize grid with random states or if option is provided, with previous states
|
||||||
pub fn init_grid(option: Option<&Vec<Vec<Cell>>>) -> Vec<Vec<Cell>> {
|
pub fn init_grid(option: Option<&Vec<Vec<Cell>>>) -> Vec<Vec<Cell>> {
|
||||||
let mut grid: Vec<Vec<Cell>> = Vec::new();
|
let mut grid: Vec<Vec<Cell>> = Vec::new();
|
||||||
for j in 0..HEIGHT {
|
for j in 0..HEIGHT {
|
||||||
let mut row: Vec<Cell> = Vec::new();
|
let mut row: Vec<Cell> = Vec::new();
|
||||||
for i in 0..WIDTH {
|
for i in 0..WIDTH {
|
||||||
|
// Generate random state
|
||||||
let mut value = rand::random::<u32>() % Q;
|
let mut value = rand::random::<u32>() % Q;
|
||||||
if let Some(g) = option {
|
if let Some(g) = option {
|
||||||
|
// Extract previous state
|
||||||
value = g[j as usize][i as usize].state;
|
value = g[j as usize][i as usize].state;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Add cell
|
||||||
row.push(Cell {
|
row.push(Cell {
|
||||||
x: i,
|
x: i,
|
||||||
y: j,
|
y: j,
|
||||||
state: value,
|
state: value,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
// Add row
|
||||||
grid.push(row);
|
grid.push(row);
|
||||||
}
|
}
|
||||||
grid
|
grid
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Map number from one range to another
|
||||||
fn map_num(n: usize, s: usize, e: usize, a: usize, b: usize) -> usize {
|
fn map_num(n: usize, s: usize, e: usize, a: usize, b: usize) -> usize {
|
||||||
(a as f64 + (n as f64 - s as f64) * (b as f64 - a as f64) / (e as f64 - s as f64)) as usize
|
(a as f64 + (n as f64 - s as f64) * (b as f64 - a as f64) / (e as f64 - s as f64)) as usize
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Display grid in console
|
||||||
pub fn display_grid(grid: &Vec<Vec<Cell>>) {
|
pub fn display_grid(grid: &Vec<Vec<Cell>>) {
|
||||||
for j in 0..HEIGHT {
|
for j in 0..HEIGHT {
|
||||||
for i in 0..WIDTH {
|
for i in 0..WIDTH {
|
||||||
|
// Get cell in grid
|
||||||
let x = i as usize;
|
let x = i as usize;
|
||||||
let y = j as usize;
|
let y = j as usize;
|
||||||
let state = grid[y][x].state as usize;
|
let state = grid[y][x].state as usize;
|
||||||
|
|
||||||
|
// Print cell to console
|
||||||
let index = map_num(state, 0, Q as usize, 0, BRIGHTNESS.len());
|
let index = map_num(state, 0, Q as usize, 0, BRIGHTNESS.len());
|
||||||
print!("{}", BRIGHTNESS.chars().nth(index).unwrap());
|
print!("{}", BRIGHTNESS.chars().nth(index).unwrap());
|
||||||
}
|
}
|
||||||
@ -98,26 +116,33 @@ pub fn display_grid(grid: &Vec<Vec<Cell>>) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Calculate next generation
|
||||||
pub fn update_grid(grid: &mut Vec<Vec<Cell>>) {
|
pub fn update_grid(grid: &mut Vec<Vec<Cell>>) {
|
||||||
|
// Initialize new generation by copying old
|
||||||
let mut new_gen = init_grid(Some(grid));
|
let mut new_gen = init_grid(Some(grid));
|
||||||
for j in 0..HEIGHT {
|
for j in 0..HEIGHT {
|
||||||
for i in 0..WIDTH {
|
for i in 0..WIDTH {
|
||||||
let x = i as usize;
|
let x = i as usize;
|
||||||
let y = j as usize;
|
let y = j as usize;
|
||||||
|
|
||||||
|
// Get cell in both grids
|
||||||
let current = &grid[y][x];
|
let current = &grid[y][x];
|
||||||
let next = &mut new_gen[y][x];
|
let next = &mut new_gen[y][x];
|
||||||
|
|
||||||
|
// Reset at end
|
||||||
if current.state == Q - 1 {
|
if current.state == Q - 1 {
|
||||||
next.state = 0;
|
next.state = 0;
|
||||||
|
// Calculate based on neighbors
|
||||||
} else if current.state == 0 {
|
} else if current.state == 0 {
|
||||||
let (inf, ill) = current.neighbor_count(&grid, StateOp::Types);
|
let (inf, ill) = current.neighbor_count(&grid, StateOp::Types);
|
||||||
next.state = inf / K1 + ill / K2;
|
next.state = inf / K1 + ill / K2;
|
||||||
|
// Calculate based on states
|
||||||
} else {
|
} else {
|
||||||
let (sum, states) = current.neighbor_count(&grid, StateOp::States);
|
let (sum, states) = current.neighbor_count(&grid, StateOp::States);
|
||||||
next.state = sum / (9 - states) + G;
|
next.state = sum / (9 - states) + G;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Clamp state to maximum
|
||||||
if next.state >= Q {
|
if next.state >= Q {
|
||||||
next.state = Q - 1;
|
next.state = Q - 1;
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,10 @@
|
|||||||
|
// Display settings
|
||||||
pub const BRIGHTNESS: &str =
|
pub const BRIGHTNESS: &str =
|
||||||
"$@B%8&WM#*oahkbdpqwmZO0QLCJUYXzcvunxrjft/\\|()1{}[]?-_+~<>i!lI;:,\"^`'. ";
|
"$@B%8&WM#*oahkbdpqwmZO0QLCJUYXzcvunxrjft/\\|()1{}[]?-_+~<>i!lI;:,\"^`'. ";
|
||||||
pub const HEIGHT: u32 = 25; // Max: 35
|
pub const HEIGHT: u32 = 25; // Max: 35
|
||||||
pub const WIDTH: u32 = 25; // Max: 145
|
pub const WIDTH: u32 = 25; // Max: 145
|
||||||
pub const FPS: u32 = 10;
|
pub const FPS: u32 = 10;
|
||||||
|
// Game settings
|
||||||
pub const K1: u32 = 2;
|
pub const K1: u32 = 2;
|
||||||
pub const K2: u32 = 3;
|
pub const K2: u32 = 3;
|
||||||
pub const G: u32 = 35;
|
pub const G: u32 = 35;
|
||||||
@ -14,11 +16,14 @@ use cell::*;
|
|||||||
use std::{thread, time::Duration};
|
use std::{thread, time::Duration};
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
|
// Initialize grid randomly
|
||||||
let mut grid = init_grid(None);
|
let mut grid = init_grid(None);
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
|
// Display current generation
|
||||||
print!("{esc}[2J{esc}[1;1H", esc = 27 as char);
|
print!("{esc}[2J{esc}[1;1H", esc = 27 as char);
|
||||||
display_grid(&grid);
|
display_grid(&grid);
|
||||||
|
// Calculate next generation and wait
|
||||||
update_grid(&mut grid);
|
update_grid(&mut grid);
|
||||||
thread::sleep(Duration::from_millis(1000 / (FPS as u64)));
|
thread::sleep(Duration::from_millis(1000 / (FPS as u64)));
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user