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) }