-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathversion-a4.bal
107 lines (93 loc) · 3.07 KB
/
version-a4.bal
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
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
import ballerina/io;
const int GRID_SIZE_Y = 5;
const int GRID_SIZE_X = 5;
type Coord record {|
readonly int x;
readonly int y;
|};
type CoordSet table<Coord> key (x, y);
const string LIVE_CELL_REPRESENTATION = "■";
const string DEAD_CELL_REPRESENTATION = "·";
public function main() {
int generation = 1;
// current generation (1) with seed
CoordSet aliveCells = table [
{x:2, y:1},
{x:2, y:2},
{x:2, y:3}
];
while true {
print(aliveCells, generation);
final CoordSet nextAliveCells = table[];
foreach int y in 0..<GRID_SIZE_Y {
foreach int x in 0..<GRID_SIZE_X {
final boolean currentCellState = aliveCells[x, y] is Coord;
final Coord[] neighbours = neighboursOf({x, y});
final int numberOfLiveNeighbours =
neighbours.reduce(function (int accu, Coord c) returns int {
return aliveCells[c.x, c.y] is Coord ? accu + 1 : accu;
}, 0);
if willBeAlive(currentCellState, numberOfLiveNeighbours) {
nextAliveCells.add({x, y});
}
}
}
aliveCells = nextAliveCells.clone();
generation += 1;
final string input = io:readln("Enter q to quit: ");
if input == "q" {
break;
}
}
}
# Calculate all valid neighbour cell coordinates of `cell`.
#
# + c - The coordinates of a cell which neighbours are looked for
# + return - An array of all valid neighbour cell coordinates
isolated function neighboursOf(Coord c) returns Coord[] {
return
from int x in [c.x-1, c.x, c.x+1]
let int max_index_x = GRID_SIZE_X - 1
where x >= 0 && x <= max_index_x
from int y in [c.y-1, c.y, c.y+1]
let int max_index_y = GRID_SIZE_Y - 1
where y >= 0 && y <= max_index_y
where !(x == c.x && y == c.y)
select {x, y}
;
}
# Calculate the next cell state based on the number of live neighbours.
#
# + cellState - The current state
# + liveNeighbours - The number of live neighbours
# + return - The next state
isolated function willBeAlive(boolean cellState, int liveNeighbours) returns boolean {
match cellState {
true => {
match liveNeighbours {
2|3 => { return true; }
_ => { return false; }
}
}
_ => {
match liveNeighbours {
3 => { return true; }
_ => { return false; }
}
}
}
}
# Visualize the grid by printing it to the screen.
#
# + aliveCells - The cells that are alive
# + generation - The generation number used in the header
isolated function print(CoordSet aliveCells, int generation) {
io:println("===");
io:println(string`generation: ${generation}`);
foreach int y in 0..<GRID_SIZE_Y {
foreach int x in 0..<GRID_SIZE_X {
io:print(aliveCells[x, y] is Coord ? LIVE_CELL_REPRESENTATION : DEAD_CELL_REPRESENTATION);
}
io:println();
}
}