Skip to content

Instantly share code, notes, and snippets.

@samclane
Created December 6, 2022 14:09
Show Gist options
  • Save samclane/ea505aece267319b9a8c223208e9eaa3 to your computer and use it in GitHub Desktop.
Save samclane/ea505aece267319b9a8c223208e9eaa3 to your computer and use it in GitHub Desktop.
An attempt at creating the "firefighter cellular automata" as described by ChatGPT
"""
Sure, here is a ruleset for a 2d cellular automaton with 6 states that can be used to simulate fire:
Each cell in the grid is in one of six states: "empty", "tree", "burning", "ash", "smoke", and "firefighter".
At each step in the simulation, the state of each cell is updated based on the states of its neighbors according to the following rules:
If a cell is empty and has exactly 3 tree neighbors, it becomes a tree. Otherwise, it remains empty.
If a cell is a tree and has 2 or more burning neighbors, it becomes burning. Otherwise, it remains a tree.
If a cell is burning and has 1 or more firefighter neighbors, it becomes ash. Otherwise, it becomes smoke.
If a cell is ash, it remains ash.
If a cell is smoke and has 3 or more ash neighbors, it becomes ash. Otherwise, it remains smoke.
If a cell is a firefighter and has 2 or more burning neighbors, it becomes ash. Otherwise, it remains a firefighter.
The simulation continues by repeating this process for each step in time.
This ruleset is more complex than the previous ones, as it introduces the concept of different types of cells and their interactions. In this ruleset, empty cells can become trees if they have exactly 3 tree neighbors, and trees can become burning if they have 2 or more burning neighbors. Burning cells can become ash if they have 1 or more firefighter neighbors, or they can become smoke if they do not. Smoke cells can become ash if they have 3 or more ash neighbors, and firefighters can become ash if they have 2 or more burning neighbors.
This ruleset can be used to simulate the spread of a forest fire, with trees representing the trees in the forest, burning cells representing the fire, smoke representing the smoke from the fire, ash representing the remains of burned trees, and firefighters representing the efforts to contain and extinguish the fire. The simulation can be modified and extended in many ways to create different scenarios and behaviors, such as different types of trees, different firefighting strategies, and so on. Experimentation and exploration are key to finding interesting and complex behavior in cellular automata.
"""
import cellpylib as cpl
import random
WIDTH = 120
HEIGHT = 120
cellular_automaton = cpl.init_simple2d(WIDTH, HEIGHT)
# encode states
empty = 0
tree = 1
firefighter = 2
ash = 3
smoke = 4
burning = 5
# start a 10x10 fire in the middle of the grid
cellular_automaton[:, WIDTH//2-5:WIDTH//2+5, HEIGHT//2-5:HEIGHT//2+5] = burning
# sprinkle trees randomly throughout the grid
for x in range(WIDTH):
for y in range(HEIGHT):
if random.random() < .8:
cellular_automaton[:, x, y] = tree
# sprinkle firefighters randomly throughout the grid
for x in range(WIDTH):
for y in range(HEIGHT):
if random.random() < .1:
cellular_automaton[:, x, y] = firefighter
def firefighter_rule(neighbourhood, count, t):
"""
Each cell in the grid is in one of six states: "empty", "tree", "burning", "ash", "smoke", and "firefighter".
At each step in the simulation, the state of each cell is updated based on the states of its neighbors according to the following rules:
If a cell is empty and has exactly 3 tree neighbors, it becomes a tree. Otherwise, it remains empty.
If a cell is a tree and has 2 or more burning neighbors, it becomes burning. Otherwise, it remains a tree.
If a cell is burning and has 1 or more firefighter neighbors, it becomes ash. Otherwise, it becomes smoke.
If a cell is ash, it remains ash.
If a cell is smoke and has 3 or more ash neighbors, it becomes ash. Otherwise, it remains smoke.
If a cell is a firefighter and has 2 or more burning neighbors, it becomes ash. Otherwise, it remains a firefighter.
The simulation continues by repeating this process for each step in time.
"""
# count the number of tree neighbours by getting the number of 1s in the neighbourhood
tree_neighbours = (neighbourhood == tree).sum()
# do the same for the other states
burning_neighbours = (neighbourhood == burning).sum()
ash_neighbours = (neighbourhood == ash).sum()
# smoke_neighbours = (neighbourhood == smoke).sum()
firefighter_neighbours = (neighbourhood == firefighter).sum()
# empty_neighbours = (neighbourhood == empty).sum()
# apply the rules of the game
if neighbourhood[1, 1] == empty and tree_neighbours == 3:
return tree
elif neighbourhood[1, 1] == tree and burning_neighbours >= 2:
return burning
elif neighbourhood[1, 1] == burning and firefighter_neighbours >= 1:
return ash
elif neighbourhood[1, 1] == burning and firefighter_neighbours == 0:
return smoke
elif neighbourhood[1, 1] == ash:
return ash
elif neighbourhood[1, 1] == smoke and ash_neighbours >= 3:
return ash
elif neighbourhood[1, 1] == smoke and ash_neighbours < 3:
return smoke
elif neighbourhood[1, 1] == firefighter and burning_neighbours >= 2:
return ash
else:
return firefighter
# evolve the cellular automaton for 60 time steps
cellular_automaton = cpl.evolve2d(cellular_automaton, timesteps=60, neighbourhood='Moore',
apply_rule=firefighter_rule, memoize='recursive')
cpl.plot2d_animate(cellular_automaton, save=True, colormap='cividis', interval=2000)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment