-
Notifications
You must be signed in to change notification settings - Fork 0
/
forest_fire_oo.sf
76 lines (61 loc) · 1.65 KB
/
forest_fire_oo.sf
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
#!/usr/bin/ruby
define RED = "\e[1;31m";
define YELLOW = "\e[1;33m";
define GREEN = "\e[1;32m";
define DIRS = [
[-1, -1], [0, -1], [1, -1],
[-1, 0], [1, 0],
[-1, 1], [0, 1], [1, 1],
]
enum (Empty, Tree, Heating, Burning);
define pix = [' ', GREEN + "*", YELLOW + "*", RED + "*"];
class Forest(p=0.01, f=0.001, height, width) {
has coords = [];
has spot = [];
has neighbors = [];
method init {
coords = (0..height ~X 0..width)
spot = height.of { width.of { [true, false].pick ? Tree : Empty } }
self.init_neighbors
}
method init_neighbors {
for i,j in coords {
neighbors[i][j] = gather {
for dir in DIRS {
take(\(spot[i + dir[0]][j + dir[1]] \\ next));
}
}
}
}
method step {
var heat = [];
for i,j in coords {
given (spot[i][j]) {
when Empty { spot[i][j] = Tree if (1.rand < p) }
when Tree { spot[i][j] = Heating if (1.rand < f) }
when Heating { spot[i][j] = Burning; heat << [i, j] }
when Burning { spot[i][j] = Empty }
}
}
for i,j in heat {
neighbors[i][j].each { |ref|
*ref = Heating if (*ref == Tree);
}
}
}
method show {
for i in ^height {
say pix[@spot[i]];
}
}
}
STDOUT.autoflush(true)
var width = Num(`tput cols`)-1
var height = Num(`tput lines`)-1
var forest = Forest(height: height, width: width)
print "\e[2J";
loop {
print "\e[H";
forest.show;
forest.step;
}