gameoflife
you can run this locally with the following command
go run github.com/dfirebaugh/tortuga/examples/gameoflife
package main
import (
"fmt"
"math/rand"
"github.com/dfirebaugh/tortuga"
"github.com/dfirebaugh/tortuga/pkg/component"
"github.com/dfirebaugh/tortuga/pkg/math/geom"
)
type cart struct {
}
var (
game tortuga.Console
cells []*cell
generation = 0
tick = 0
)
func (c cart) Update() {
if tick%5 == 0 {
generation += 1
for _, cell := range cells {
cell.iteration()
}
for _, cell := range cells {
cell.isAlive = cell.nextGen
}
}
tick++
}
func (c cart) Render() {
game.Clear()
geom.MakeRect(0, 0, float64(game.GetScreenWidth()), float64(game.GetScreenHeight())).
Filled(game.GetDisplay(), game.Color(0))
game.PrintAt(fmt.Sprintf("gen: %d", generation), 10, 25, 2)
for _, cell := range cells {
cell.Render()
}
}
type cell struct {
geom.Rect
isAlive bool
component.Coordinate
nextGen bool
}
func (c *cell) Update() {}
func (c cell) Render() {
if !c.isAlive {
return
}
c.Filled(game.GetDisplay(), game.Color(5))
}
func (c *cell) iteration() {
if !c.isAlive {
c.nextGen = c.shouldReproduce()
return
}
c.nextGen = !c.shouldDie()
}
func (c *cell) shouldDie() bool {
if c.isUnderpopulated() || c.isOverpopulated() {
return true
}
return false
}
func (c cell) isOverpopulated() bool {
return c.getAliveNeighborCount() > 3
}
func (c cell) isUnderpopulated() bool {
return c.getAliveNeighborCount() < 2
}
func (c cell) shouldReproduce() bool {
return c.getAliveNeighborCount() == 3
}
func (c cell) getAliveNeighborCount() int {
x := c.X
y := c.Y
potential := []component.Coordinate{
{Y: y, X: x - 1}, //left
{Y: y, X: x + 1}, //right
{Y: y - 1, X: x}, //up
{Y: y + 1, X: x}, //down
{Y: y - 1, X: x - 1}, //left top diagnal
{Y: y + 1, X: x + 1}, //right bottom diagnal
{Y: y - 1, X: x + 1}, // left bottom diagnal
{Y: y + 1, X: x - 1}, // right top diagnal
}
neighbors := []bool{}
for _, n := range potential {
if n.X < 0 || n.Y < 0 || n.X > float64(game.GetScreenWidth()) || n.Y > float64(game.GetScreenHeight()) {
continue
}
if game.GetScreenWidth()*int(n.Y)+int(n.X) >= len(cells) {
continue
}
if cells[game.GetScreenWidth()*int(n.Y)+int(n.X)].isAlive {
neighbors = append(neighbors, true)
}
}
return len(neighbors)
}
func main() {
game = tortuga.New()
game.SetScaleFactor(3)
game.SetFPSEnabled(true)
for y := 0; y < game.GetScreenHeight(); y++ {
for x := 0; x < game.GetScreenWidth(); x++ {
c := &cell{}
c.X = float64(x)
c.Y = float64(y)
c.Rect = geom.MakeRect(c.X, c.Y, 1, 1)
c.isAlive = rand.Intn(100) < 25
cells = append(cells, c)
}
}
game.Run(cart{})
}