82 lines
1.3 KiB
Go
82 lines
1.3 KiB
Go
package gol
|
|
|
|
import (
|
|
"bytes"
|
|
"os"
|
|
"sync"
|
|
)
|
|
|
|
type Arena [][]bool
|
|
|
|
func New(ysize, xsize int) Arena {
|
|
arena := make([][]bool, ysize)
|
|
for i := range ysize {
|
|
arena[i] = make([]bool, xsize)
|
|
}
|
|
return arena
|
|
}
|
|
|
|
// bufPool
|
|
var bufPool = sync.Pool{
|
|
New: func() any {
|
|
return new(bytes.Buffer)
|
|
},
|
|
}
|
|
|
|
var (
|
|
spriteOn = ([]byte)("\ue0b6\ue0b4")
|
|
spriteOff = ([]byte)("\u2022\u2022")
|
|
)
|
|
|
|
func (a Arena) PrintMe() {
|
|
b := bufPool.Get().(*bytes.Buffer)
|
|
b.Reset()
|
|
|
|
for i := range len(a) {
|
|
for j := range len(a[0]) {
|
|
if a[i][j] {
|
|
b.Write(spriteOn)
|
|
} else {
|
|
b.Write(spriteOff)
|
|
}
|
|
}
|
|
b.WriteRune('\n')
|
|
}
|
|
os.Stdout.Write(b.Bytes())
|
|
bufPool.Put(b)
|
|
}
|
|
|
|
func (a Arena) NextGen(to Arena) {
|
|
for y := range len(a) {
|
|
for x := range len(a[0]) {
|
|
to[y][x] = a.life(x, y)
|
|
}
|
|
}
|
|
}
|
|
|
|
func (a Arena) life(x, y int) bool {
|
|
neighbours := a.countNeighbours(x, y)
|
|
iAmAlive := a[y][x]
|
|
return neighbours == 3 || (iAmAlive && neighbours == 2)
|
|
}
|
|
|
|
func (a Arena) countNeighbours(x, y int) int {
|
|
ysize := len(a)
|
|
xsize := len(a[0])
|
|
|
|
count := 0
|
|
for dy := -1; dy <= 1; dy++ {
|
|
for dx := -1; dx <= 1; dx++ {
|
|
if dx == 0 && dy == 0 {
|
|
continue
|
|
}
|
|
ny := (y + dy + ysize) % ysize
|
|
nx := (x + dx + xsize) % xsize
|
|
if a[ny][nx] {
|
|
count++
|
|
}
|
|
}
|
|
}
|
|
return count
|
|
}
|