3
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

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

Last updated at Posted at 2019-06-30

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

GitHubではここで

きっかけ

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

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

そんな時にこんな本を見つけて面白そうだと思った次第。
作って動かすALife ―実装を通した人工生命モデル理論入門

alt

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

ルール確認

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

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

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

Plant Uml アクティビティ図

X93DYi8m4CVlUOgGq-v25-gzuisBDnyWf7GQ1jAqfAb5fUzkCfL6CEXSGluVFvWvZ5uvFtM63U55ZxtbdKBxFrpvdV4mFt-_l2ZsNDIePQsi5b4cgKKtUgd1WbEnAGDC0zc9ra0hPKHAq_V32gN9jmcSGz9aq-A2ep9u0x7bekoWSMhccxR-i_nSfgegVYxZmyXUM6wnPo5jbMf4SPC1MIO-VScnCB-VxYDcjxdV-pdtvIeK.png

メインとなるコード

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]

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

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

3
3
4

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?