1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
|
use crate::level_gen::util::rand_initialize;
use crate::types::Dimensions;
use rand::Rng;
pub struct Params {
chance_to_start_alive: f64,
dimensions: Dimensions,
birth_limit: i32,
death_limit: i32,
steps: usize,
}
impl Default for Params {
fn default() -> Self {
Params {
chance_to_start_alive: 0.45,
dimensions: Dimensions { w: 80, h: 20 },
birth_limit: 4,
death_limit: 3,
steps: 2,
}
}
}
pub fn generate<R: Rng + ?Sized>(
params: &Params,
rand: &mut R,
) -> Vec<Vec<bool>> {
let mut cells =
rand_initialize(¶ms.dimensions, rand, params.chance_to_start_alive);
for _ in 0..params.steps {
step_automata(&mut cells, params);
}
cells
}
fn step_automata(cells: &mut Vec<Vec<bool>>, params: &Params) {
let orig_cells = (*cells).clone();
for x in 0..(params.dimensions.h as usize) {
for y in 0..(params.dimensions.w as usize) {
let nbs = num_alive_neighbors(&orig_cells, x as i32, y as i32);
if orig_cells[x][y] {
if nbs < params.death_limit {
cells[x][y] = false;
} else {
cells[x][y] = true;
}
} else {
if nbs > params.birth_limit {
cells[x][y] = true;
} else {
cells[x][y] = false;
}
}
}
}
}
const COUNT_EDGES_AS_NEIGHBORS: bool = true;
fn num_alive_neighbors(cells: &Vec<Vec<bool>>, x: i32, y: i32) -> i32 {
let mut count = 0;
for i in -1..2 {
for j in -1..2 {
if i == 0 && j == 0 {
continue;
}
let neighbor_x = x + i;
let neighbor_y = y + j;
if COUNT_EDGES_AS_NEIGHBORS
&& (neighbor_x < 0
|| neighbor_y < 0
|| neighbor_x >= (cells.len() as i32)
|| neighbor_y >= (cells[0].len()) as i32)
{
count += 1;
} else if cells[neighbor_x as usize][neighbor_y as usize] {
count += 1;
}
}
}
count
}
|