ライフゲームをコーディング
モチベーション
あたらしい人工知能の教科書 プロダクト/サービス開発に必要な基礎知識
- 作者: 多田智史
- 出版社/メーカー: 翔泳社
- 発売日: 2017/01/10
- メディア: Kindle版
- この商品を含むブログを見る
この本読んでます。知っていることから知らないこと、新しい知識がいっぱいつまっていて読み応えは十分。 そのなかでライフゲームというゲーム?があることを初めて知りました。ルールは以下の通りです。
大きなグリッド内で一マスの生物が生きている、もしくは死んでいる状態で存在している。 隣り合う8つのマスの状態でそのマスの次の生存状態がきまる - 死んでいるマスの周りで3つの生きているマスがいると、次にそのますは生きている状態になる - 生きているマスの周りで生きているマスが1つ以下だと、次にそのマスは過疎で死ぬ - 生きているマスの周りで生きているますが4つ以上だと、次にそのますは過密で死ぬ
それ、Pythonでやってみましょう!
コーディング
import numpy as np import random import matplotlib.pyplot as plt import matplotlib.animation as animation import matplotlib.patches as patches %matplotlib inline from IPython.display import HTML class Seizon(): def __init__(self): self.h = 50 self.v = 50 self.space = [[0 for i in range(self.h)] for j in range(self.v)] self.cycles=15 self.start_val = 0 self.rectPtrn = [] def nextage(self, x, y): a_cell = 0 for i in [-1, 0, 1]: for j in [-1, 0, 1]: if x+i < 0 or x+i > self.h - 1 or \ y+j < 0 or y+j > self.v - 1 or (i==0 and j==0): pass elif self.space[x+i][y+j] == 1: a_cell += 1 if self.space[x][y]==0: if a_cell == 3: return 1 return 0 if self.space[x][y]==1: if a_cell == 2: return 1 return 0 def check_life(self): for i in range(self.v): for j in range(self.h): test = self.nextage(i,j) self.space[i][j] = test def random_set(self, d=2): c = 0 for i in range(self.v): for j in range(self.h): self.space[i][j] = random.randint(0,99) % 2 c += self.space[i][j] self.start_val = c def calc_alives(self): c = 0 for i in self.space: for j in i: c += j return c def pickRect(self): h = 0 v = 0 getRect = [] for i in self.space: v = 0 h += 1 for j in i: v += 1 if j == 1: getRect.append([v,h]) self.rectPtrn.append(getRect) def __main__(self): self.random_set() for t in range(self.cycles): val = self.calc_alives() print str(t) + " : trial ", print val * 1.0 /self.start_val, val self.pickRect() self.check_life() print len(self.rectPtrn) sz = Seizon() sz.__main__()
出力
0 : trial 1.0 1236 1 : trial 0.532362459547 658 2 : trial 0.366504854369 453 3 : trial 0.25 309 4 : trial 0.155339805825 192 5 : trial 0.0873786407767 108 6 : trial 0.0647249190939 80 7 : trial 0.0493527508091 61 8 : trial 0.0404530744337 50 9 : trial 0.0364077669903 45 10 : trial 0.037216828479 46 11 : trial 0.0380258899676 47 12 : trial 0.037216828479 46 13 : trial 0.0355987055016 44 14 : trial 0.0364077669903 45
ランダムで50%程度のマスカラ始めた場合、10回前後で大体3.5%で生き残り続けるようですね。この値は最初の配置で変わるようですが、3~4%ぐらいのようです。では実際どんな感じで生きているんでしょうか。アニメーションを使ってみてみましょう。
アニメーションをつかって可視化
fig = plt.figure() ax = plt.gca() ax.set_xlim(1,50) ax.set_ylim(1,50) #ax.set_aspect(1) def init(): return [] def animated(i): plt.cla() patches = [] print i, len(sz.rectPtrn[i]) for r in sz.rectPtrn[i]: #for r in [[1, 1], [2,2], [3,3]]: patches.append(ax.add_patch(plt.Rectangle((r[0],r[1]), 1, 1, fc="Blue"))) return patches ani = animation.FuncAnimation(fig, animated, frames=sz.cycles, init_func=init, interval=1000, blit=True) HTML(ani.to_html5_video())
こんなんが出ました。面白いですね。きまった型になってそのままキープしている様子がうかがえます。