You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
box-o-sand/conway/game_of_life.go

120 lines
2.0 KiB

package conway
import (
"errors"
"fmt"
"math/rand"
"time"
)
func init() {
rand.Seed(time.Now().UTC().UnixNano())
}
type GameOfLife struct {
State *GameState
}
func (game *GameOfLife) Mutate() error {
return game.State.Mutate()
}
func (game *GameOfLife) Checksum() (string, error) {
return game.State.Checksum()
}
func NewGameOfLife(height, width int) *GameOfLife {
return &GameOfLife{
State: NewGameState(height, width),
}
}
func (game *GameOfLife) EvaluateGeneration() error {
height, width := game.State.Height(), game.State.Width()
genScore := NewGenerationScoreCard(height, width)
genScore.Calculate(game.State)
cells, err := genScore.Cells()
if err != nil {
return err
}
for cell := range cells {
score := cell.Value
curState, err := game.State.Get(cell.X, cell.Y)
if err != nil {
return err
}
if curState == 1 {
if score < 2 {
err = game.State.Deaden(cell.X, cell.Y)
if err != nil {
return err
}
continue
}
if score == 2 || score == 3 {
continue
}
if score > 3 {
err = game.State.Deaden(cell.X, cell.Y)
if err != nil {
return err
}
continue
}
} else if curState == 0 {
if score == 3 {
err = game.State.Enliven(cell.X, cell.Y)
if err != nil {
return err
}
continue
} else {
continue
}
}
}
return nil
}
func (game *GameOfLife) ImportState(state *GameState) error {
return game.State.Import(state)
}
func (game *GameOfLife) ImportRandomState() error {
height := game.State.Height()
width := game.State.Width()
if height < 0 || width < 0 {
errStr := fmt.Sprintf("current game has invalid dimensions! %vx%v",
height, width)
return errors.New(errStr)
}
randState := NewGameState(height, width)
cells, err := randState.Cells()
if err != nil {
return err
}
for cell := range cells {
cell.SetValue(rand.Intn(2))
}
return game.ImportState(randState)
}
func (game *GameOfLife) String() string {
return fmt.Sprintf("%s\n", game.State)
}