EnsekiTT Blog

EnsekiTTが書くブログです。

PythonとMatplotlibを使って20分でライフゲームを作る話

つまりなにしたの?

Matplotlibで可視化したライフゲームを作った。ただし、初期の入力はコードでいれる必要があって、今回は銀河パターンを入れた。
f:id:ensekitt:20180518002432j:plain

ライフゲームってなに?

1970年ごろにイギリスの数学者John Horton Conwayが考案した人生ではなく生命を簡単なモデルにしたゲームです。
ゲームとはいえ生命(生きているセル)の初期配置を決めるだけで、あとは観察し続ける僕のような一人っ子が割りと好きなタイプの遊び。(偏見

ライフゲームのルール

生命が準拠するルールで、碁盤のような格子があり、一つの格子はセルと呼ばれる。
各セルには8方位にセルがあってその状態(生きているか、死んでいるか)に寄って真ん中のセルの次の世代に置ける挙動が決まる。
セルの生死は次のルールに従う。

この辺はWikipediaから拾ってきた。

  • 誕生

死んでいるセルに隣接する生きたセルがちょうど3つあれば、次の世代が誕生する。

  • 生存

生きているセルに隣接する生きたセルが2つか3つならば、次の世代でも生存する。

  • 過疎

生きているセルに隣接する生きたセルが1つ以下ならば、過疎により死滅する。

  • 過密

生きているセルに隣接する生きたセルが4つ以上ならば、過密により死滅する。
ライフゲーム - Wikipedia

Pythonでの実装方針

  • 銀河パターンでちゃんと動いていることを確認する(テストは銀河でやる)
  • ひたすら眺めていられること(自動的に更新する)
  • ルールを文字通りコードに落として理解しやすいコードにする(最適化しない)

の3点

作った

import copy
import matplotlib.pyplot as plt

HEIGHT = 50
WIDTH = 50
EPOCH = 100

# 現在の世代の環境
env_grid = [[0 for i in range(WIDTH)] for j in range(HEIGHT)]

# 銀河を真ん中に置く
c = 20
for i in range(6):
    env_grid[c+0][c+i] = 1
    env_grid[c+1][c+i] = 1
    
    env_grid[c+i][c+7] = 1
    env_grid[c+i][c+8] = 1

    env_grid[c+i+3][c+0] = 1
    env_grid[c+i+3][c+1] = 1

    env_grid[c+7][c+i+3] = 1
    env_grid[c+8][c+i+3] = 1

# 表示の準備
fig, ax = plt.subplots(1,1, figsize=(8,8))
imgs = ax.imshow(env_grid, cmap="GnBu")

for epoch in range(EPOCH):
    # 次の世代の環境を定義
    new_grid = [[0 for i in range(WIDTH)] for j in range(HEIGHT)] 
    for j in range(1, HEIGHT-1):
        for i in range(1,WIDTH-1):
            center_x = i
            center_y = j
            # 周囲の生存数を数える
            count = 0
            count += env_grid[center_y-1][center_x-1]
            count += env_grid[center_y-1][center_x]
            count += env_grid[center_y-1][center_x+1]
            count += env_grid[center_y][center_x-1]
            count += env_grid[center_y][center_x+1]
            count += env_grid[center_y+1][center_x-1]
            count += env_grid[center_y+1][center_x]
            count += env_grid[center_y+1][center_x+1]

            # 誕生・生存・過疎・過密でセルを更新する
            if (count == 3) and (env_grid[center_y][center_x]==0):
                new_grid[center_y][center_x] = 1
            elif ((count == 3) or (count == 2)) and (env_grid[center_y][center_x]==1):
                new_grid[center_y][center_x] = 1
            elif (count <= 1) and (env_grid[center_y][center_x]==1):
                new_grid[center_y][center_x] = 0
            elif (count >= 4) and (env_grid[center_y][center_x]==1):
                new_grid[center_y][center_x] = 0
    env_grid = copy.copy(new_grid)
    # 表示する
    imgs.set_data(env_grid)
    plt.pause(.01)

動いた

f:id:ensekitt:20180518002234g:plain

やってみてどうだった?

20分で作れるように問題設定を出来たのがよかった。一番時間がかかったのは銀河パターンを描くところ。
眺めているだけで楽しいけど、やっぱりポチポチ生命の場所を入力するのが大変なので
なんかしらのUIを用意したほうが良い。

クリエイティブ・コモンズ・ライセンス
この 作品 は クリエイティブ・コモンズ 表示 4.0 国際 ライセンスの下に提供されています。