Cellular Automata
Did you manage to build the environment?
Here's one version of the code:
environment = []
for h in range(height):
row = []
for w in range(width):
row.append(fuel_amount)
environment.append(row)
def print_environment():
for h in range(height):
for w in range(width):
print(environment[h][w], end=" ")
print("")
print("")
print_environment()
Note that we've turned the code to check the environment into a function, that way we can call it from wherever we like when we need to output the 2D list.
We're going to use the fuel_amount in each cell to indicate whether it is, is not, or has been on fire. Let's start our fire:
environment[fire_start_y][fire_start_x] -= 1
print_environment()
i.e. we set one of the cells to a value of
fuel_amount - 1
. Any cell with a value between fuel_amount - 1
and
1
will be on fire, and we'll reduce the amount of fuel in burning cells by one each time step iteration.
We're now in a position that we can start the model. We'll need a loop of iterations to represent time steps (we'll also add a stopping condition in a bit), and within the loop we'll need to check each cell. Any cell next to a cell that is on fire, will become on fire next iteration. Here's the algorithm:
# Loop through number_of_iterations
# Loop through height with variable h
# Loop through width with variable w
# Check values around environment[h][w] for fire
# If fire found, and value in [h][w] > 1, reduce value by 1.
Remember that when looping through a 2D list, you can look at the current cell with
environment[h][w]
, and a neighbouring cell, for example up and left of it, with
environment[h-1][w-1]
.
Remember, however, that in the Core course we looked at boundary problms, and here we have one again. If we do:
for h in range(height):
for w in range(width):
fire = False
if (environment[h-1][w-1] < fuel_amount): fire = True
if (fire == True) & (environment[h][w] > 0):
environment[h][w] -= 1
the code will break at the first cell [0][0]
as the neighbour will be at position [-1][-1]
. We saw that there were three
potential solutions to this issue: a torus world (going off one side comes back on the other); special boundary rules; or ignoring the edge cells.
Which is simplest and most reasonable for this abstract fire model? Have a go at implementing the iterations. Note the algorithm has an additional
problem – once you've got the code working, can you see what it is?