-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmain.go
130 lines (111 loc) · 2.72 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
package main
import (
"fmt"
"image"
"image/color"
"image/gif"
"math/rand"
"os"
"time"
)
var matrix = []image.Point{
{X: -1, Y: 1},
{X: 0, Y: 1},
{X: 1, Y: 1},
{X: 1, Y: 0},
{X: 1, Y: -1},
{X: 0, Y: -1},
{X: -1, Y: -1},
{X: -1, Y: 0},
}
type Grid map[image.Point]interface{}
func (g Grid) evolve() Grid {
grid := make(map[image.Point]interface{})
for origin := range g {
points := []image.Point{origin}
for _, neighbour := range matrix {
points = append(points, image.Point{
X: origin.X + neighbour.X,
Y: origin.Y + neighbour.Y,
})
}
for _, point := range points {
switch g.countNeighbours(point) {
case 2:
if _, exists := g[point]; exists {
// - Any live cell with two or three live neighbours survives.
grid[point] = nil
}
case 3:
grid[point] = nil
default:
// - Any dead cell with three live neighbours becomes a live cell.
// - All other live cells die in the next generation. Similarly, all other dead cells stay dead.
}
}
}
return grid
}
func (g Grid) countNeighbours(point image.Point) uint {
var neighbours uint
for _, neighbour := range matrix {
if _, exists := g[image.Point{X: point.X + neighbour.X, Y: point.Y + neighbour.Y}]; exists {
neighbours += 1
}
}
return neighbours
}
func createImage(width, height int, grid Grid) *image.Paletted {
var palette = []color.Color{
color.RGBA{0x00, 0x00, 0x00, 0xff}, color.RGBA{0x00, 0x00, 0xff, 0xff},
color.RGBA{0x00, 0xff, 0x00, 0xff}, color.RGBA{0x00, 0xff, 0xff, 0xff},
color.RGBA{0xff, 0x00, 0x00, 0xff}, color.RGBA{0xff, 0x00, 0xff, 0xff},
color.RGBA{0xff, 0xff, 0x00, 0xff}, color.RGBA{0xff, 0xff, 0xff, 0xff},
}
img := image.NewPaletted(image.Rect(0, 0, width, height), palette)
for position := range grid {
img.Set(position.X, position.Y, color.White)
}
return img
}
func main() {
var (
width, height = 1_600, 1_200
iterations = 750
)
start := time.Now()
defer fmt.Printf("time used to calculate 1.000 iterations: %v", time.Since(start).Milliseconds())
example := Grid{}
for i := 0; i < 1_500_000; i++ {
example[image.Point{
X: int(rand.Uint32() % uint32(width)),
Y: int(rand.Uint32() % uint32(height)),
}] = nil
}
series := []Grid{example}
for i := 0; i < iterations; i++ {
series = append(series, series[len(series)-1].evolve())
}
var (
images []*image.Paletted
delays []int
)
for _, serie := range series {
images = append(images, createImage(width, height, serie))
delays = append(delays, 1)
}
f, err := os.OpenFile("game_of_life.gif", os.O_WRONLY|os.O_CREATE, 0600)
if err != nil {
fmt.Println(err)
return
}
defer f.Close()
if err := gif.EncodeAll(f,
&gif.GIF{
Image: images,
Delay: delays,
},
); err != nil {
panic(err)
}
}