-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmain.go
152 lines (136 loc) · 2.83 KB
/
main.go
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
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
package main
import (
"fmt"
"time"
)
// Global Variables, no need to interfere
var cells [][]int
var final [][]int
// User defined parameters
var size int
var fps int
func init() {
size = 20 // Size of frame
cells = make([][]int, size)
final = make([][]int, size)
for i := range cells {
cells[i] = make([]int, size)
final[i] = make([]int, size)
}
// The Glider Pattern (https://conwaylife.com/wiki/Glider)
cells[5][5] = 1
cells[5][6] = 1
cells[5][4] = 1
cells[4][6] = 1
cells[3][5] = 1
}
func main() {
fps = 5 // Rate at which simulation runs
EventLoop(fps)
}
func Tick() {
// A Tick is ran once per frame
// Logic
// Check each cell for the following
// 1) Any live cell with fewer than two live neighbours dies.
// 2) Any live cell with more than three live neighbours dies.
// 3) Any live cell with two or three live neighbours lives, unchanged, to the next generation.
// 4) Any dead cell with exactly three live neighbours will come to life.
for i := 0; i < size; i++ {
for j := 0; j < size; j++ {
// Count the number of neighboring cells
count := 0
if i != 0 {
if cells[i-1][j] == 1 {
count++
}
}
if i != size-1 {
if cells[i+1][j] == 1 {
count++
}
}
if j != 0 {
if cells[i][j-1] == 1 {
count++
}
}
if j != size-1 {
if cells[i][j+1] == 1 {
count++
}
}
if i != 0 && j != 0 {
if cells[i-1][j-1] == 1 {
count++
}
}
if i != size-1 && j != size-1 {
if cells[i+1][j+1] == 1 {
count++
}
}
if i != 0 && j != size-1 {
if cells[i-1][j+1] == 1 {
count++
}
}
if i != size-1 && j != 0 {
if cells[i+1][j-1] == 1 {
count++
}
}
// Once total neighboring cells are calculated, find cell state
if count < 2 && cells[i][j] == 1 {
final[i][j] = 0
}
if (count >= 2 && count <= 3) && cells[i][j] == 1 {
final[i][j] = 1
}
if count > 3 && cells[i][j] == 1 {
final[i][j] = 0
}
if count == 3 && cells[i][j] == 0 {
final[i][j] = 1
}
}
}
// Copy the generated frame to current frame for next Tick
for i := range cells {
copy(cells[i], final[i])
}
printCells()
}
func printCells() {
fmt.Print("\n\n\n\n\n") // Some new lines, for rendering next frame
// Print the resulting frame
for i := 0; i < size; i++ {
for j := 0; j < size; j++ {
if final[i][j] == 1 {
fmt.Print("▓")
}
if final[i][j] == 0 {
fmt.Print("░")
}
}
fmt.Print("\n")
}
}
func EventLoop(fps int) {
// Runs an Event Loop that triggers a Tick at the specified fps
loop := time.NewTicker(time.Duration(1000/fps) * time.Millisecond)
quit := make(chan struct{})
go func() {
for {
select {
case <-loop.C:
Tick() // No goroutines are used in Ticks in order to prevent data mismatch across ticks
case <-quit:
loop.Stop()
return
}
}
}()
for {
}
}