gol/gol/arena.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
}