package main import ( "fmt" "time" ) const ( width = 10 height = 10 ) type Board [][]bool func NewBoard() Board { b := make(Board, height) for i := range b { b[i] = make([]bool, width) } return b } // sets a cell to alive func (b Board) SetAlive(x, y int) { b[y][x] = true } // asks if a cell is alive func (b Board) IsAlive(x, y int) bool { if x < 0 || x >= width || y < 0 || y >= height { return false } return b[y][x] } // finds the next state of the board func (b Board) NextState() Board { next := NewBoard() for y := 0; y < height; y++ { for x := 0; x < width; x++ { aliveNeighbors := b.countAliveNeighbors(x, y) if b.IsAlive(x, y) { next[y][x] = aliveNeighbors == 2 || aliveNeighbors == 3 } else { next[y][x] = aliveNeighbors == 3 } } } return next } // counts the number of alive neighbors for a given cell func (b Board) countAliveNeighbors(x, y int) int { count := 0 for dy := -1; dy <= 1; dy++ { for dx := -1; dx <= 1; dx++ { if dx == 0 && dy == 0 { continue } if b.IsAlive(x+dx, y+dy) { count++ } } } return count } func (b Board) Print() { for y := 0; y < height; y++ { for x := 0; x < width; x++ { if b.IsAlive(x, y) { fmt.Print("O ") } else { fmt.Print(". ") } } fmt.Println() } fmt.Println() } func main() { boards := []Board{ NewBoard(), NewBoard(), NewBoard(), } // glider boards[0].SetAlive(1, 0) boards[0].SetAlive(2, 1) boards[0].SetAlive(0, 2) boards[0].SetAlive(1, 2) boards[0].SetAlive(2, 2) // blinker boards[1].SetAlive(1, 0) boards[1].SetAlive(1, 1) boards[1].SetAlive(1, 2) // r-pentomino boards[2].SetAlive(3, 3) boards[2].SetAlive(4, 3) boards[2].SetAlive(2, 4) boards[2].SetAlive(3, 4) boards[2].SetAlive(3, 5) // iterate through each board for _, board := range boards { for i := 0; i < 10; i++ { board.Print() board = board.NextState() time.Sleep(time.Second / 2) } fmt.Println("---------------") } }