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
86
use rand::prelude::*;
use rand::rngs::ThreadRng;
#[derive(Debug, Default)]
pub struct Generator {
pub map: Vec<usize>,
pub width: usize,
pub height: usize,
pub rng: ThreadRng,
}
impl Generator {
pub fn new() -> Self {
Self::default()
}
pub fn with_size(mut self, width: usize, height: usize) -> Self {
self.map = vec![0; width * height];
self.width = width;
self.height = height;
self
}
pub fn show(&self) {
for i in 0..self.height {
let anchor = i * self.width;
let slice = &self.map[anchor..anchor + self.width];
println!("{:?}", slice);
}
}
pub fn spawn(&mut self, number: usize) -> &mut Self {
let start = self.rng.gen_range(0, self.map.len());
self.map[start] = number;
self.populate(start, 0.5);
self
}
pub fn spawn_repeated(&mut self, number: usize, repeats: usize) -> &mut Self {
for _ in 0..repeats {
self.spawn(number);
}
self
}
pub fn populate(&mut self, start: usize, probability: f64) {
let number = self.map[start];
let candidates = vec![start.saturating_sub(1), start + 1, start.saturating_sub(self.width), start + self.width];
for candidate in candidates {
let remainder = candidate % self.width;
if candidate > 0 && candidate < self.map.len() && remainder > 0 && remainder < self.width {
let should_spawn = self.rng.gen_bool(probability);
if should_spawn {
self.map[candidate] = number;
self.populate(candidate, probability / 2.);
}
}
}
}
}