こちらは Go4 Advent Calendar 2019 12日目の記事です。
この記事ではGoでライフゲームを実装したコードの紹介とその解説をおこないます。
Motivation
最近Twitter上でセル・オートマトンというのを発見しまして、言葉では表現しづらいのですが、物凄く心に響くものがありました。ロマンを感じた。
自分もやってみたいなと思い調べてみると、代表的な実装例としてライフゲーム(Game of Life)があるというのを知りました。
すでにGoを含め色々な言語で実装したものがネット上には溢れていたのでN番煎じではありますが、やりたいのでやってみました。
Output
Repository: mqtsuo02/go-game-of-life
Design
CLIの動作は下記のような流れとしました。
RUN→セルをランダムに初期化→輪廻転生→任意のキー押下で終了
Code
main.go (click to open)
package main
import (
"bufio"
"fmt"
"math/rand"
"os"
"time"
)
const (
width = 60
height = 20
lifespan = 100
duration = 100
clear = "\033[2J"
head = "\033[1;1H"
)
type cells [width + 2][height + 2]int
var cs, ncs cells
func main() {
initialize()
for i := 0; i < lifespan; i++ {
render()
update()
time.Sleep(100 * time.Millisecond)
}
end()
}
func initialize() {
fmt.Print(clear)
rand.Seed(time.Now().UnixNano())
for y := 1; y < height+1; y++ {
for x := 1; x < width+1; x++ {
cs[x][y] = rand.Intn(2)
}
}
}
func render() {
var screen string
for y := 0; y < height+2; y++ {
for x := 0; x < width+2; x++ {
c := " "
if cs[x][y] == 1 {
c = "▉"
}
screen += c
}
screen += "\n"
}
fmt.Print(head)
fmt.Print(screen)
}
func update() {
for y := 1; y < height+1; y++ {
for x := 1; x < width+1; x++ {
ncs[x][y] = 0
cnt := cs[x-1][y-1] + cs[x][y-1] + cs[x+1][y-1] + cs[x-1][y] + cs[x+1][y] + cs[x-1][y+1] + cs[x][y+1] + cs[x+1][y+1]
if cnt == 2 && cs[x][y] == 1 || cnt == 3 {
ncs[x][y] = 1
}
}
}
cs = ncs
}
func end() {
fmt.Print("Press any key to end. ")
bufio.NewScanner(os.Stdin).Scan()
fmt.Print(clear)
fmt.Print(head)
}
設計にあたっては下記のサイトを参考にさせていただきました。
Explanation
処理の流れとしては以下です。
- 初期化
- forループ
- 描画
- 状態判定
- スリープ
- 入力待ち
- 終了
初期化
初期化ではターミナルのクリアと二次元配列にランダムで 0 | 1 を代入する処理を行っています。
描画
描画では二次元配列の内容をもとに文字列を生成し、ターミナルのカーソルを頭に合わせたうえでfmt.Printしている感じです。
状態判定
状態判定では対象セルの周囲のセルをカウントして、それに合わせて次の状態を決定しています。ここで集計しやすいように二次元配列の型をintにしています。(はじめはboolでやっていた)
まだやってないことリスト
- 世界を上下左右でぶったぎっているので、繋げてあげたい
- 文字列で表現しているのでセルが縦長。図形的に解決したい
- ライフゲームでおなじみのグライダー銃を打つ機能を追加したい
Thank you
以上です。ここまで読んでいただき、ありがとうございました。
これをきっかけにセル・オートマトンの世界を楽しんでいきたいと思います。
2019年のアドベントカレンダーは3つ参加してます。よかったら他の記事も見てください。
- Next.js Advent Calendar 2019 3日目 …… Next.jsをつかってSPAをSSRしてみた感想
- React Advent Calendar 2019 7日目 …… Reactの歴史
- Go4 Advent Calendar 2019 12日目 …… Goでライフゲームを実装してみた (この記事)