Skip to content

Instantly share code, notes, and snippets.

@pinscript
Created August 8, 2016 20:21
Show Gist options
  • Save pinscript/414605b155ba43ca47b351d3948d80ea to your computer and use it in GitHub Desktop.
Save pinscript/414605b155ba43ca47b351d3948d80ea to your computer and use it in GitHub Desktop.
Game of life
package main
import (
"fmt"
"flag"
"time"
"github.com/fatih/color"
)
type matrix [][]bool
var (
current matrix
size int
)
// Initialize a new matrix
func NewMatrix(size int) matrix {
m := make(matrix, size)
for y := 0; y < size; y++ {
m[y] = make([]bool, size)
}
return m
}
func render() {
// "clear" screen
for i := 0; i < 50; i++ {
//fmt.Println("")
}
red := color.New(color.FgGreen, color.Bold)
white := color.New(color.FgWhite)
for y := 0; y < size; y++ {
for x := 0; x < size; x++ {
if current[y][x] {
red.Printf("#")
} else {
white.Printf(".")
}
}
fmt.Printf("\n")
}
}
func tick() matrix {
// initialize next world
next := NewMatrix(size)
// calculate neighbours
for y := 0; y < size - 1; y++ {
for x := 0; x < size - 1; x++ {
neighbours := 0
if y > 0 && current[y-1][x] {
// above
neighbours += 1
}
if current[y+1][x] {
// below
neighbours += 1
}
if x > 0 && current[y][x-1] {
// left
neighbours += 1
}
if current[y][x+1] {
// right
neighbours += 1
}
// diagonally top right
if y > 0 && current[y-1][x+1] {
neighbours += 1
}
// diagonally top left
if y > 0 && x > 0 && current[y-1][x-1] {
neighbours += 1
}
// diagonally bottom right
if current[y+1][x+1] {
neighbours += 1
}
// diagonally bottom left
if x > 0 && current[y+1][x-1] {
neighbours += 1
}
// Any live cell with fewer than two live neighbours dies, as if caused by under-population.
if current[y][x] && neighbours < 2 {
next[y][x] = false
}
// Any live cell with two or three live neighbours lives on to the next generation.
if current[y][x] && (neighbours == 2 || neighbours == 3) {
// live on
next[y][x] = true
}
// Any live cell with more than three live neighbours dies, as if by over-population.
if current[y][x] && neighbours > 3 {
next[y][x] = false
}
// Any dead cell with exactly three live neighbours becomes a live cell, as if by reproduction.
if !current[y][x] && neighbours == 3 {
next[y][x] = true
}
}
}
return next
}
func main() {
flag.IntVar(&size, "size", 5, "Size of current")
flag.Parse()
current = NewMatrix(size)
// seed
current[2][2] = true
current[3][3] = true
current[3][4] = true
current[1][4] = true
current[2][4] = true
for {
current = tick()
render()
time.Sleep(500 * time.Millisecond)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment