comp10001-project02/old/part2.py

226 lines
10 KiB
Python
Raw Normal View History

# Title: Project 2 - Determine if a cell starts burning
# Author: Rory Healy
# Date created - 9th May 2019
def get_adjacent_cells(b_grid, wind):
'''Returns a list of cells that are considered adjacent to the cells that
are currently burning.'''
# Note: all_adjacent_cells includes cells that aren't in all_cells_list.
# Hence, adjacent_cells_list is returned once these invalid cells have
# been removed.
all_adjacent_cells = []
adjacent_cells_list = []
all_cells_list = []
burning_cells = []
# Sets up a matrix of cells with their respective (i, j) values.
for row in range(len(b_grid)):
for column in range(len(b_grid)):
all_cells_list.append([row, column])
# Adds all cells around the burning cells to all_adjacent_cells.
for row in range(len(b_grid)):
for column in range(len(b_grid)):
if b_grid[row][column] is True:
all_adjacent_cells.append([row - 1, column - 1])
all_adjacent_cells.append([row - 1, column])
all_adjacent_cells.append([row - 1, column + 1])
all_adjacent_cells.append([row, column + 1])
all_adjacent_cells.append([row + 1, column + 1])
all_adjacent_cells.append([row + 1, column])
all_adjacent_cells.append([row + 1, column - 1])
all_adjacent_cells.append([row, column - 1])
burning_cells.append([row, column])
# Adds cells to all_adjacent_cells based on the wind.
for burning_cell in burning_cells:
if wind == 'N':
row_adjustment = -2
for column_adjustment in [-1, 0, 1]:
all_adjacent_cells.append([burning_cell[0] + row_adjustment,
burning_cell[1] +
column_adjustment])
elif wind == 'NW':
for row_adjustment in [-1, -2]:
for column_adjustment in [-1, -2]:
if (row_adjustment, column_adjustment) != (-1, -1):
all_adjacent_cells.append([burning_cell[0] +
row_adjustment,
burning_cell[1] +
column_adjustment])
elif wind == 'W':
column_adjustment = -2
for row_adjustment in [-1, 0, 1]:
all_adjacent_cells.append([burning_cell[0] + row_adjustment,
burning_cell[1] +
column_adjustment])
elif wind == 'SW':
for row_adjustment in [-1, -2]:
for column_adjustment in [1, 2]:
if (row_adjustment, column_adjustment) != (-1, 1):
all_adjacent_cells.append([burning_cell[0] +
row_adjustment,
burning_cell[1] +
column_adjustment])
elif wind == 'S':
row_adjustment = 2
for column_adjustment in [-1, 0, 1]:
all_adjacent_cells.append([burning_cell[0] + row_adjustment,
burning_cell[1] +
column_adjustment])
elif wind == 'SE':
for row_adjustment in [1, 2]:
for column_adjustment in [1, 2]:
if (row_adjustment, column_adjustment) != (1, 1):
all_adjacent_cells.append([burning_cell[0] +
row_adjustment,
burning_cell[1] +
column_adjustment])
elif wind == 'E':
column_adjustment = 2
for row_adjustment in [-1, 0, 1]:
all_adjacent_cells.append([burning_cell[0] + row_adjustment,
burning_cell[1] +
column_adjustment])
elif wind == 'NE':
for row_adjustment in [-1, -2]:
for column_adjustment in [1, 2]:
if (row_adjustment, column_adjustment) != (-1, 1):
all_adjacent_cells.append([burning_cell[0] +
row_adjustment,
burning_cell[1] +
column_adjustment])
# Removes cells from adjacent_cells_list that don't fit the size of the
# grid, are already in adjacent_cells_list, or are in burning_cells.
for cell in all_adjacent_cells:
if cell in all_cells_list:
if cell not in burning_cells:
if cell not in adjacent_cells_list:
adjacent_cells_list.append(cell)
return adjacent_cells_list
def get_height_impact_model(h_grid, burning_cells):
'''Creates a matrix of the same size as h_grid with the values of each
cell (i, j) equal to the factor by which ignition_factor is affected by
(e.g. [[0.5], [0.5], [2], [1]]). This is used so that the ignition factor
for each cell can be multiplied by this factor that is influenced by the
height.'''
all_cells_list = []
height_impact_list = []
# Sets up a matrix of cells with their respective (i, j) values, and
# generates a black matrix height_impact_list, which is to be filled in
# later.
for row in range(len(h_grid)):
height_impact_list.append([])
for column in range(len(h_grid)):
all_cells_list.append([row, column])
height_impact_list[row].append([])
# Generates a value for each cell based on the relative value of the height
# of that cell to the height of the burning cells- either 0.5, 1, or 2.
for x in range(len(burning_cells)):
# Generates a list of adjacent cells for each burning cell.
burning_cell_x = burning_cells[x]
row = burning_cell_x[0]
column = burning_cell_x[1]
directly_adjacent_cells = []
directly_adjacent_cells.append([row - 1, column - 1])
directly_adjacent_cells.append([row - 1, column])
directly_adjacent_cells.append([row - 1, column + 1])
directly_adjacent_cells.append([row, column + 1])
directly_adjacent_cells.append([row + 1, column + 1])
directly_adjacent_cells.append([row + 1, column])
directly_adjacent_cells.append([row + 1, column - 1])
directly_adjacent_cells.append([row, column - 1])
# Finds the height of the burning cell currently in the loop and
# compares it to the cells surrounding this cell, and assigns the cell
# an ignition multiplication factor.
burning_cell_x_i = burning_cell_x[0]
burning_cell_x_j = burning_cell_x[1]
burning_cell_x_height = h_grid[burning_cell_x_i][burning_cell_x_j]
# Removes cells from directly_adjacent_cells that don't fit the size of
# the grid.
direct_adjacent_cells = []
for cell in directly_adjacent_cells:
if cell in all_cells_list:
direct_adjacent_cells.append(cell)
for cell in direct_adjacent_cells:
cell_i = cell[0]
cell_j = cell[1]
cell_height = h_grid[cell_i][cell_j]
if cell_height < burning_cell_x_height:
height_impact_list[cell_i][cell_j] = 0.5
elif cell_height == burning_cell_x_height:
height_impact_list[cell_i][cell_j] = 1
elif cell_height > burning_cell_x_height:
height_impact_list[cell_i][cell_j] = 2
return height_impact_list
def check_ignition(b_grid, f_grid, h_grid, i_threshold, w_direction, i, j):
'''Returns True or False if a cell at (i, j) will start burning in the next
timestep based on the factors influencing it's likelihood to burn, as
described to the right.'''
# Defines values to be used in this function based on the inputs.
fuel_load = f_grid[i][j]
wind = w_direction
ignition_threshold = i_threshold
input_cell_is_burning = b_grid[i][j]
burning_cells = []
cells_list = []
for row in range(len(b_grid)):
for column in range(len(b_grid)):
if b_grid[row][column] is True:
burning_cells.append([row, column])
for row in range(len(b_grid)):
for column in range(len(b_grid)):
cells_list.append([row, column])
# Gets the cells adjacent to the burning cells, and the impact that the
# height has on the ignition factor of each cell.
adjacent_cells = get_adjacent_cells(b_grid, wind)
height_model = get_height_impact_model(h_grid, burning_cells)
# Adds all cells around the input cell to directly_adjacent_cells. Note
# that directly_adjacent_cells contains cells outside the matrix, whereas
# direct_cells_list does not.
directly_adjacent_cells = []
direct_cells_list = []
directly_adjacent_cells.append([i - 1, j - 1])
directly_adjacent_cells.append([i - 1, j])
directly_adjacent_cells.append([i - 1, j + 1])
directly_adjacent_cells.append([i, j + 1])
directly_adjacent_cells.append([i + 1, j + 1])
directly_adjacent_cells.append([i + 1, j])
directly_adjacent_cells.append([i + 1, j - 1])
directly_adjacent_cells.append([i, j - 1])
# Removes cells from directly_adjacent_cells that don't fit the size of the
# grid.
for cell in directly_adjacent_cells:
if cell in cells_list:
direct_cells_list.append(cell)
# Calculates the ignition factor.
ignition_factor = 0
for cell in direct_cells_list:
if cell in adjacent_cells:
ignition_factor += 1
ignition_factor = height_model[i][j] * ignition_factor
# Determines what to return based on ignition_factor, fuel_load and
# input_cell_is_burning.
if (input_cell_is_burning is True) and (fuel_load > 0):
return True
elif ignition_factor > ignition_threshold:
return True
return False