Life Game(ライフゲーム)をpythonで作ってみた!
GitHubではここで
きっかけ
卒業論文のテーマ(基本的には数値解析系のゼミだが、シミュレーションであれば可能)
で迷っていた。
初めは、シフト管理システムがいいかな?(欲してくれてる人がいた)と思ったが、
今は学生でしかできないことをしたほうがいいかな?とも思った。
そんな時にこんな本を見つけて面白そうだと思った次第。
作って動かすALife ―実装を通した人工生命モデル理論入門
ちなみにコードは完全自作です。
上の本はきっかけであって、まだ読んではいません。(これから行き詰まった時に?読む予定)
ルール確認
1,生命のいないところは、
周囲にちょうど3個の生命がある場合に新しく生命が誕生する
2,生命がいるところは、
周囲に2個、または3個の生命がいる場合にのみ、その生命は存在できる。
今後はより複雑にして、現実世界の生命の動きにより近づけるが、
今はまだ、シンプルな、よくあるライフゲームでシミュレーションしてみる。
Plant Uml アクティビティ図
メインとなるコード
main.py
# !/usr/bin/env python3
from pprint import pprint
from StageVisalize import visalize
from Initialize import big_bang
import LifeGameRules
from Stage import Stage
def redraw(stage):
"""
ステージを書き直す
"""
new_stage = Stage()
for y_i in range(1, stage.YMax-1):
for x_j in range(1, stage.XMax-1):
#生命が存在しないとき
if stage[y_i][x_j] == 0:
new_stage[y_i][x_j] = LifeGameRules.rule_1(stage, x_j, y_i)
#生命が存在するとき
elif stage[y_i][x_j] == 1:
new_stage[y_i][x_j] = LifeGameRules.rule_2(stage, x_j, y_i)
return new_stage
def main():
#ステージの設立
generation_stage = Stage()
#初期化
generation_stage = big_bang(generation_stage)
#ゲームスタート
while True:
try:
#可視化
visalize(generation_stage)
#ライフゲームのルールに則り、変化
generation_stage = redraw(generation_stage)
#コマ送り
_ = input()
#ctrl + C で終了
except KeyboardInterrupt:
print('end of game')
break
if __name__ == "__main__":
main()
ルールを記述するコード
LifeGameRules.py
import Around
def rule_1(stage, x_j, y_i):
"""
生命のいないところは、
周囲にちょうど3個の生命がある場合に新しく生命が誕生します。
"""
around_area = Around.get_3_3_around(stage, x_j, y_i)
life_count = Around.key_count(around_area,1)
if (life_count == 3):
return 1
else:
return 0
def rule_2(stage, x_j, y_i):
"""
生命がいるところは、
周囲に2個、または3個の生命がいる場合に、そのまま生命が残ります。
そうでない場合には死んでしまいます。
"""
around_area = Around.get_3_3_around(stage, x_j, y_i)
life_count = Around.key_count(around_area,1)
#周囲のマスだけを数えるために、中央の生命の分だけ一つ減らす。
life_count = life_count -1
if (life_count==3)or(life_count==2):
return 1
else:
return 0
Stage(生命の大地)
Stage.py
class Stage():
"""
生命が生まれる大地
"""
def __init__(self):
#:HACK:以下は改良の余地があるが、なんかみやすいと思っているので、とりあえずこのまま
self.borad = [
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
]
self.XMax = len(self.borad[0])
self.YMax = len(self.borad)
def __call__(self):
return self.borad
def __getitem__(self,indexes):
return self.borad[indexes]
アドバイスや感想等お願いします!
今回のコードは自分なりには結構自身がある方です笑
それでもまだまだ改良の余地はあるので、何かあればお願いします!

