Life Game(ライフゲーム)をpythonで作ってみた！メモ

#Life Game(ライフゲーム)をpythonで作ってみた！

##[GitHubではここで](https://github.com/MineOwl/LifeGame/tree/master/LIFEGAME1)

##きっかけ
卒業論文のテーマ（基本的には数値解析系のゼミだが、シミュレーションであれば可能）
で迷っていた。

初めは、シフト管理システムがいいかな？（欲してくれてる人がいた）と思ったが、
今は学生でしかできないことをしたほうがいいかな？とも思った。


そんな時にこんな本を見つけて面白そうだと思った次第。
[作って動かすALife ―実装を通した人工生命モデル理論入門 ](https://www.amazon.co.jp/%E4%BD%9C%E3%81%A3%E3%81%A6%E5%8B%95%E3%81%8B%E3%81%99ALife-%E2%80%95%E5%AE%9F%E8%A3%85%E3%82%92%E9%80%9A%E3%81%97%E3%81%9F%E4%BA%BA%E5%B7%A5%E7%94%9F%E5%91%BD%E3%83%A2%E3%83%87%E3%83%AB%E7%90%86%E8%AB%96%E5%85%A5%E9%96%80-%E5%B2%A1-%E7%91%9E%E8%B5%B7/dp/4873118476/ref=asc_df_4873118476/?tag=jpgo-22&linkCode=df0&hvadid=295686767484&hvpos=1o1&hvnetw=g&hvrand=11004231614624861112&hvpone=&hvptwo=&hvqmt=&hvdev=c&hvdvcmdl=&hvlocint=&hvlocphy=1009288&hvtargid=pla-525151001479&psc=1&th=1&psc=1)

![alt](https://images-na.ssl-images-amazon.com/images/I/516dQmDuT3L._SX350_BO1,204,203,200_.jpg)

ちなみにコードは完全自作です。
上の本はきっかけであって、まだ読んではいません。（これから行き詰まった時に？読む予定）


##ルール確認
1,生命のいないところは、
　　　周囲にちょうど３個の生命がある場合に新しく生命が誕生する

2,生命がいるところは、
　　　周囲に２個、または３個の生命がいる場合にのみ、その生命は存在できる。

今後はより複雑にして、現実世界の生命の動きにより近づけるが、
今はまだ、シンプルな、よくあるライフゲームでシミュレーションしてみる。

##Plant Uml アクティビティ図


![X93DYi8m4CVlUOgGq-v25-gzuisBDnyWf7GQ1jAqfAb5fUzkCfL6CEXSGluVFvWvZ5uvFtM63U55ZxtbdKBxFrpvdV4mFt-_l2ZsNDIePQsi5b4cgKKtUgd1WbEnAGDC0zc9ra0hPKHAq_V32gN9jmcSGz9aq-A2ep9u0x7bekoWSMhccxR-i_nSfgegVYxZmyXUM6wnPo5jbMf4SPC1MIO-VScnCB-VxYDcjxdV-pdtvIeK.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/415059/a51a3bef-dce1-7465-307f-3909e505faee.png)


##メインとなるコード

```python: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()

```

##ルールを記述するコード


```python:LifeGameRules.py
import Around


def rule_1(stage, x_j, y_i):
    """
    生命のいないところは、
    周囲にちょうど３個の生命がある場合に新しく生命が誕生します。
    """
    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):
    """
    生命がいるところは、
    周囲に２個、または３個の生命がいる場合に、そのまま生命が残ります。 
    そうでない場合には死んでしまいます。
    """
    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（生命の大地)

```python: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]

```


##アドバイスや感想等お願いします！

今回のコードは自分なりには結構自身がある方です笑
それでもまだまだ改良の余地はあるので、何かあればお願いします！