ライフゲームとは
こんな感じのやつ?
実際のライフゲームとはちょっと違うのかな?
侵略ゲームとも呼ばれてるみたいです。
Wikipedia ライフゲーム
実際の定義はこちら。多分僕が作りたいものはライフゲームとは違うっぽい。
作ってみよう
普段はpythonを書くことが多いので今回もpythonを採用
python楽です(^q^)
コードはこちら
動作確認はUbuntu14.04+Python3.5でしております。
ちょっとした解説
Pythonは関数型で書きやすいのでfor文とかif文が減らせて本当に書きやすい
最初はオブジェクト指向で書こうと思ったけど、
リスト内包表記と関数組み合わせるだけでけっこうイケそうだったので、
今回はクラスは作りませんでした。
def next_state(f, i, j):
s = f[i][j]
e = environment(f, i, j)
if all(map(lambda x: x == s, e)):
return s
else:
num_friend = len(list(filter(lambda x: x == s, e)))
num_enemy = len(list(filter(lambda x: x != s, e)))
prob = 50 + (num_friend - num_enemy) * 6
alive = random.randint(0, 100) < prob
if alive:
return FRIEND if s == FRIEND else ENEMY
else:
return ENEMY if s == FRIEND else FRIEND
メインのロジックがこちら
一つのセルの周り8セル分の現在の環境を取得し、次ステップの状態を決めています。
周りに味方が多いほど生き残りやすく、敵が多いほど死にやすくなってます。
lambdaを使えばらくちんらくちん(^q^)
画像に出力
最終的にはGIF動画で戦いの様子を出力します。
def output_field(f, step):
f = list(filter(lambda x: not all(list(map(lambda e: e == '*', x))) , f))
f = list(map(lambda x: list(filter(lambda e: e != '*', x)), f))
f = list(map(lambda x: list(map(object2color ,x)) ,f))
arr = np.array(f, dtype=np.int8)
image = Image.fromarray(arr.astype('uint8'))
image.save('./tmp/' + '%07d.png' % step)
このコードで2次元配列をRGB値に変換し、tmpディレクトリに出力しています。
最終的にはImageMagickでGIFに変換し、outputディレクトリに出力しております。
2次元配列を扱っているので、lambdaが二重になっています。
lambdaがあればらくちんらくちん(^q^)
試しに遊んでみた
おお、いい感じですね。
パラメータとか工夫しないと一定の状態で収束してしまいますね。
司令官セルを作って周り○マスの勝率に補正をかけたりするとかおもしろいかも。
Wikipediaのルールとは少し違う、オリジナルの実装なので、ライフゲームとは言えないかもしれませんが、個人的には満足してます。
感想
Lispで最近遊んでいたおかげで、lambdaが使いやすくなった(というより使おうとすることが増えた)
lambdaがあればらくちんらくちん(^q^)