Created Life.
This commit is contained in:
parent
e1c68d3501
commit
1336ead072
1 changed files with 118 additions and 0 deletions
118
src/main.rs
Normal file
118
src/main.rs
Normal file
|
@ -0,0 +1,118 @@
|
||||||
|
extern crate console;
|
||||||
|
extern crate rand;
|
||||||
|
|
||||||
|
use console::Term;
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let cutoff: f32 = 0.3;
|
||||||
|
let term = Term::stdout();
|
||||||
|
|
||||||
|
let mut game = GameOfLife::new(255, 255, cutoff);
|
||||||
|
game.print_to_console(&term);
|
||||||
|
loop {
|
||||||
|
game.update();
|
||||||
|
if game.print_to_console(&term) == 0 {
|
||||||
|
game = GameOfLife::new(255, 255, cutoff);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct GameOfLife {
|
||||||
|
x: usize,
|
||||||
|
y: usize,
|
||||||
|
playing_field: Vec<Vec<u16>>,
|
||||||
|
/*The lest significant bit of the u16 represents the current state of the cell.
|
||||||
|
The 15 bits to the left represent the 15 past states. This is used to calculate
|
||||||
|
whether there is still interesting movement in the visible playing field.*/
|
||||||
|
}
|
||||||
|
|
||||||
|
impl GameOfLife {
|
||||||
|
pub fn new(x: usize, y: usize, cutoff: f32) -> Self {
|
||||||
|
let mut playing_field = vec![vec![0; y]; x];
|
||||||
|
|
||||||
|
for i in 0..x {
|
||||||
|
for j in 0..y {
|
||||||
|
playing_field[i][j] = random_one_or_zero_with_cutoff_point(cutoff)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Self { x, y, playing_field }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn print_to_console(&self, term: &Term) -> usize {
|
||||||
|
let (x, y) = term.size();
|
||||||
|
term.clear_last_lines(x as usize);
|
||||||
|
let upper_border = (self.x - x as usize) / 2;
|
||||||
|
let left_border = (self.y - y as usize) / 2;
|
||||||
|
|
||||||
|
let mut movement_score: usize = 0;
|
||||||
|
|
||||||
|
for x_iter in upper_border..(self.x - upper_border) {
|
||||||
|
for y_iter in left_border..(self.y - left_border) {
|
||||||
|
if self.playing_field[x_iter][y_iter] & 1 == 1 {
|
||||||
|
print!("#");
|
||||||
|
} else {
|
||||||
|
print!(" ");
|
||||||
|
};
|
||||||
|
movement_score += get_movement_score(self.playing_field[x_iter][y_iter]);
|
||||||
|
}
|
||||||
|
print!("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
return movement_score;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn update(&mut self) {
|
||||||
|
let mut new_field = vec![vec![0; self.y]; self.x];
|
||||||
|
|
||||||
|
for x_iter in 1..self.x - 1 {
|
||||||
|
for y_iter in 1..self.y - 1 {
|
||||||
|
let mut neighbor_count: u8 = 0;
|
||||||
|
|
||||||
|
for n_x_iter in (x_iter - 1)..(x_iter + 2) {
|
||||||
|
for n_y_iter in (y_iter - 1)..(y_iter + 2) {
|
||||||
|
if (n_x_iter, n_y_iter) != (x_iter, y_iter)
|
||||||
|
&& self.playing_field[n_x_iter][n_y_iter] & 1 == 1
|
||||||
|
{
|
||||||
|
neighbor_count += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
match neighbor_count {
|
||||||
|
3 => {
|
||||||
|
new_field[x_iter][y_iter] =
|
||||||
|
self.playing_field[x_iter][y_iter] << 1 | 1;
|
||||||
|
}
|
||||||
|
2 => {
|
||||||
|
new_field[x_iter][y_iter] =
|
||||||
|
self.playing_field[x_iter][y_iter] << 1 | (
|
||||||
|
self.playing_field[x_iter][y_iter] & 1
|
||||||
|
)
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
new_field[x_iter][y_iter] =
|
||||||
|
self.playing_field[x_iter][y_iter] << 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
self.playing_field = new_field
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn random_one_or_zero_with_cutoff_point(cutoff: f32) -> u16 {
|
||||||
|
let rand_num: f32 = rand::random();
|
||||||
|
if rand_num < cutoff {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_movement_score(cell: u16) -> usize {
|
||||||
|
if (cell & 0b0000000001111110) == ((cell & 0b0001111110000000) >> 6) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
Loading…
Reference in a new issue