Another agent-based simulation example from my side! In this article I will implement Conway’s game of life in Python, using the agent-based modeling framework abm_framework. You can find the framework by clicking the link below.
Conway’s game of life is a good introduction to agent-based modeling and it is also taught at universities for exactly this reason. It is also a good introduction to programming in Python in general.
I have recently shared a range of examples on how you can implement the abm_framework in Python for agent-based modeling. You can find the framework here:
- Link: Word-of-mouth agent-based sales model
- Link: Agent-based segregation model (Python)
- Link: Agent-based SIR model Python example
- Link: Agent-based modeling in Python
- Link: Agent-based simulation in Python
The following section describes the rules of Conway’s game of life. After that I implement the game of life in Python.
Rules of Conway’s game of life
Conceptionally, the game of life consists of a grid. Every grid in the cell is populated by an agent. The agent is either dead or alive. Starting from an initial state the game of life updates iteration upon iteration. During each iteration the following rules apply:
- If an agent is alive and its neighbouring cells contain 2 or 3 living agents, the agent survives until the next round. It is then alive in the next round. Otherwise the agent dies and is dead in the next round.
- If a dead agent has exactly 3 living agents in its neighbourhood, the agent is reborn and is alive in the next round.
These rules are sufficient for modeling Conway’s game of life. The initial state, defined by the agents dead or alive at the beginning of the simulation, is the only input that the simulation needs to run. In this article I run three versions of the model. The first two version have a random intial distribution of living agent cells. The third version has a specific initial seed pattern of living agents. In the first and third version the grid is endless. This means that if you exit the grid to the left, you enter the grid on the right side, and if you exit the grid on the top you enter the grid on the bottom. The second version applies a grid with boundaries, i.e. a grid that is not endless.
Implementing the game of life in Python
Using the abm_framework in Python (made available by me on Github) I implement the model in Python. I create a simulation grid with 100 cells. The initial state (referred to as seed) consists of 50 living agents that are randomly distributed across the grid. The code below implements the endless grid version of the simulation model.
__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")
In a second version of the model I implemented a grid that is not endless. The only adjustment in the code is in the Environment constructor call, setting endless grid argument to False instead of True.
Animation of Conway’s game of life
Below is the animation of Conway’s game of life in Python. The first animation represents the model with an endless grid.
The second animation, displayed below, represents the model with a bounded grid.
Lastly, I run a scenario in which I defined a specific initial model state. The animation can be seen below and represents an endless grid.
You can find various game of life examples by doing a simple Google query. There are also various tools available for specifying your own seed and running the model step by step.
Concluding remarks
In this article I implemented Conway’s game of life in Python, using a framework that I named abm_framework. I ran three scenarios, differing in grid boundary definition (endless vs. not endless) and initial seed (random initial seed vs. specific initial seed). If you want to learn agent-based modeling implementing the game of life in Python could be a good first step for you.
Data scientist focusing on simulation, optimization and modeling in R, SQL, VBA and Python
Leave a Reply