Conway의 Python 인생 게임

또 다른 에이전트 기반 시뮬레이션 예시! 이 기사에서는 에이전트 기반 모델링 프레임워크 abm_framework 를 사용하여 Python에서 Conway의 인생 게임을 구현할 것 입니다. 프레임워크는 아래 링크를 클릭하면 찾을 수 있습니다.

Conway의 인생 게임은 에이전트 기반 모델링에 대한 좋은 소개이며 바로 이러한 이유로 대학에서도 가르치고 있습니다. 또한 일반적으로 Python 프로그래밍에 대한 좋은 소개입니다.

최근 에 에이전트 기반 모델링을 위해 Python에서 abm_framework 를 구현하는 방법에 대한 다양한 예를 공유했습니다. 여기에서 프레임워크를 찾을 수 있습니다.

다음 섹션에서는 Conway의 인생 게임 규칙을 설명합니다. 그 후 저는 Python으로 인생 게임을 구현합니다.

Conway의 인생 게임 규칙

개념적으로 인생 게임은 그리드로 구성됩니다. 셀의 모든 그리드는 에이전트에 의해 채워집니다. 에이전트는 죽거나 살았습니다. 초기 상태에서 시작하여 삶의 게임은 반복할 때 반복을 업데이트합니다. 각 반복 동안 다음 규칙이 적용됩니다.

  • 에이전트가 살아 있고 인접한 세포에 2~3개의 살아있는 에이전트가 있는 경우 에이전트는 다음 라운드까지 생존합니다. 그런 다음 다음 라운드에서 살아 있습니다. 그렇지 않으면 에이전트가 죽고 다음 라운드에서 죽습니다.
  • 죽은 에이전트의 이웃에 정확히 3개의 살아있는 에이전트가 있는 경우 에이전트는 다시 태어나고 다음 라운드에서 살아 있습니다.

이러한 규칙은 Conway의 인생 게임을 모델링하는 데 충분합니다. 시뮬레이션 시작 시 에이전트에 의해 정의된 초기 상태는 시뮬레이션을 실행하는 데 필요한 유일한 입력입니다. 이 기사에서는 세 가지 버전의 모델을 실행합니다. 처음 두 버전에는 살아있는 에이전트 세포의 무작위 초기 분포가 있습니다. 세 번째 버전에는 살아있는 에이전트의 특정 초기 종자 패턴이 있습니다. 첫 번째와 세 번째 버전에서 그리드는 끝이 없습니다. 즉, 왼쪽 그리드에서 나가면 오른쪽 그리드로 들어가고 상단 그리드에서 나가면 하단 그리드로 들어갑니다. 두 번째 버전은 경계가 있는 그리드, 즉 무한하지 않은 그리드를 적용합니다.

파이썬으로 인생 게임 구현하기

Python 에서 abm_framework (Github에서 사용 가능)를 사용하여 Python에서 모델을 구현합니다. 100개의 셀이 있는 시뮬레이션 그리드를 만듭니다. 초기 상태(시드라고 함)는 그리드에 무작위로 분포된 50개의 살아있는 에이전트로 구성됩니다. 아래 코드는 시뮬레이션 모델 의 무한 그리드 버전을 구현합니다 .

__author__ = "Linnart Felkl"
__email__ = "LinnartSF@gmail.com"

if __name__ == "__main__":

    print("demo starts")

    import sys
    from pathlib import Path
    file = Path(__file__).resolve()
    parent, root = file.parent, file.parents[1]
    sys.path.append(str(root))

    # remove the current file's directory from sys.path, unless already removed
    try:
        sys.path.remove(str(parent))
    except ValueError:
        pass

    import data
    import stats
    import config
    import framework
    import random
    import animation

    # setup database manager and connection
    db = data.Database("sqlite3", config.path_databasefile)
    db_manager = data.Manager(db)
    
    # create an empty environment
    env = framework.Environment(1, True, 10, 10, db_manager) # Environment constructor implicitly resets environment table in database

    # create initial population of healthy humans
    attrs = ["life_t0","life_t1"]
    datatypes = ["INTEGER","INTEGER"]
    pops = framework.Populations(amount = 1, env = env, db_manager = db_manager, attributes = attrs, datatypes = datatypes)
    pops.add_population(name = "units", 
                        size = 100, 
                        attributes = attrs, 
                        datatypes = datatypes, 
                        initialvals = [0, 0]
                        )
   
    # set seed of simulation (number of agents alive and their pattern)
    agents = pops.get_agents()
    random.shuffle(agents)
    for i in range(50):
        agents[i].set_attr_value("life_t0",1)

    # setup simulation
    sim = framework.Simulation(50)

    # make sure that environment and agents tables in database are setup at this time
    pops.write_env_to_db(sim.Iteration)
    pops.write_agents_to_db(sim.Iteration)

    # execute simulation run; with centralized simulation control
    while sim.run():
        
        for agent in agents:

            # get that agents neighbourhood
            neighbours = env.get_neighbourhood(agent, mode = "moore", radius = 1)

            _neighbours_alive = 0
            for neighbour in neighbours:
                
                if neighbour.get_attr_value("life_t0") == 1: 
                    _neighbours_alive  += 1

            if agent.get_attr_value("life_t0") == 1: 

                if _neighbours_alive == 2 or _neighbours_alive == 3: 
                    
                    agent.set_attr_value("life_t1", 1)

                else:

                    agent.set_attr_value("life_t1", 0)

            elif _neighbours_alive == 3:

                agent.set_attr_value("life_t1", 1)

            else:

                agent.set_attr_value("life_t1", 0)
                
        # update results in database, for agents and for environment
        pops.write_agents_to_db(sim.Iteration)
        pops.write_density_to_db(sim.Iteration)

        # update attributes for next round
        for agent in agents:

            agent.set_attr_value("life_t0", agent.get_attr_value("life_t1"))
    
    # get dataframes with simulation results
    density_df = db_manager.get_densitydf()

    # visualize simulation data
    stats.set_fontsizes(8,10,12)

    animation.animate_density(
        df = density_df,
        filename = "gol_randomendless",
        attr = "life_t1",
        defaultsize = 50,
        color = "black",
        tpf = 0.30
    )

    # end program
    db.close()
    print("demo ends")

모델의 두 번째 버전에서는 무한하지 않은 그리드를 구현했습니다. 코드에서 유일한 조정은 환경 생성자 호출에서 무한 그리드 인수를 True 대신 False로 설정하는 것입니다.

Conway의 인생 게임 애니메이션

아래는 Python에서 Conway의 인생 게임의 애니메이션입니다. 첫 번째 애니메이션은 무한 그리드로 모델을 나타냅니다.

아래에 표시된 두 번째 애니메이션은 경계가 있는 그리드가 있는 모델을 나타냅니다.

마지막으로 특정 초기 모델 상태를 정의한 시나리오를 실행합니다. 애니메이션은 아래에서 볼 수 있으며 끝없는 그리드를 나타냅니다.

간단한 Google 쿼리를 수행하면 다양한 삶의 게임 예를 찾을 수 있습니다. 또한 자신의 시드를 지정하고 모델을 단계별로 실행하는 데 사용할 수 있는 다양한 도구가 있습니다.

끝 맺는 말

이 기사에서는 abm_framework 라는 프레임워크를 사용하여 Python으로 Conway의 인생 게임을 구현 했습니다 . 그리드 경계 정의(무한 대 무한 아님)와 초기 시드(임의의 초기 시드 대 특정 초기 시드)가 다른 세 가지 시나리오를 실행했습니다. Python으로 인생 게임을 구현하는 에이전트 기반 모델링을 배우고 싶다면 좋은 첫 번째 단계가 될 수 있습니다.

You May Also Like

Leave a Reply

Leave a Reply

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다

이 사이트는 스팸을 줄이는 아키스밋을 사용합니다. 댓글이 어떻게 처리되는지 알아보십시오.