-
Notifications
You must be signed in to change notification settings - Fork 0
/
step8.go
167 lines (147 loc) · 3.81 KB
/
step8.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
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
package main
import (
"fmt"
"math/rand"
"time"
)
const (
totalRows = 3
totalColumns = 5
)
type Universe [][]bool // "Use slices rather than arrays so that a universe
// "can be shared with, and modified by, functions or methods."
// (without using pointers)
func NewUniverse() Universe {
//type //length & capacity
u := make(Universe, totalRows)
for row := range u { // for i := 0; i < len(u); i++ {
u[row] = make([]bool, totalColumns) // set each element in u equal to a slice of booleans,
// with a length of totalColumns
}
return u
}
// add a Show method to universe
// Go doesn't have classes, but you can add methods to types.
// You can associate the method with the type by using a receiver.
func (u Universe) Show() {
str := ""
for row := range u {
for col := range u[row] {
if (u[row][col]) {
str += "*"
} else {
str += "-"
}
}
str += "\n"
}
// fmt.Print("\x0c")
fmt.Print("\033[2J", str)
}
func (u Universe) Seed() {
for row := range u {
for col := range u[row] {
r := 1 + rand.Intn(4) // create a random integer, minimum 1 and maximum 4
if r == 1 {
u[row][col] = true
} else {
u[row][col] = false
}
}
}
}
// func (u Universe) Seed2() {
// for i := 0; i < (width * height / 4); i++ {
// u.Set(rand.Intn(width), rand.Intn(height), true)
// }
// }
func (u Universe) Set(col, row int, b bool) {
u[row][col] = b
}
func (u Universe) Alive(col, row int) bool {
// "A complication arises when the cell is outside of the universe.
// "Is (-1, -1) dead or alive?"
// Solution: Wrap around!
// If y is less than 0, add the height to it.
// "If y exceeds the height of the grid, you can turn to the modulus operator
// "Use % to divide y by height and keep the remainder.
// "The same goes for x and width."
col = (col + totalColumns) % totalColumns // Why does this work?
row = (row + totalRows) % totalRows // Think if you had 100 rows, and you were passed 150
// 150 + 100 = 250
// 250 % 100 = 50
return u[row][col]
}
func (u Universe) CountAlives() int {
count := 0
for row := range(u) {
for col := range(u[row]) {
if u.Alive(col, row) {
count++
}
}
}
return count
}
func (u Universe) Neighbors(col, row int) int {
count := 0
for i := row - 1; i <= row + 1; i++ {
for j := col - 1; j <= col + 1; j++ {
if i == row && j == col {
continue;
}
if u.Alive(j, i) {
count += 1
}
}
}
return count
}
// func (u Universe) Next1(col, row int) bool {
// // A live cell with fewer than 2 live neighbors dies (isolation)
// // A live cell with 2 or 3 live neighbors lives on (community!)
// // A live cell with more than 3 live neighbors dies (overcrowding)
// // A dead cell with exactly three live neighbors becomes a live cell (birth)
// isAlive := u.Alive(col, row)
// livingNeighbors := u.Neighbors(col, row)
// var livesOn bool
// if !isAlive {
// if livingNeighbors == 3 {
// livesOn = true
// }
// } else {
// switch {
// case livingNeighbors < 2:
// livesOn = false
// case livingNeighbors == 2 || livingNeighbors == 3:
// livesOn = true
// case livingNeighbors > 3:
// livesOn = false
// }
// }
// return livesOn
// }
func (u Universe) Next(col, row int) bool {
n := u.Neighbors(col, row)
return n == 3 || n == 2 && u.Alive(col, row)
}
// "Update the state of the next universe (b)
// "From the current universe (a)."
func Step(a, b Universe) {
for row := 0; row < totalRows; row++ {
for col := 0; col < totalColumns; col++ {
b.Set(col, row, a.Next(col, row))
}
}
}
func main() {
rand.Seed(time.Now().UnixNano())
a, b := NewUniverse(), NewUniverse()
a.Seed()
for i := 0; i < 5; i++ {
Step(a, b)
a.Show()
time.Sleep(time.Second) // We use the Sleep function from the `time` package to slow down the animation
a, b = b, a
}
}