Thank you for this clear, pythonic and efficient port of the original C# script. I learned a lot from reading it.
def propagate(cell):
to_update = [neighbour for neighbour, _ in cell.get_neighbors()]
# Why putting the neighbors of the collapsed cell in the stack ?
# Other implementations put the collapsed cell in the stack, then iterate over its neighbors
while len(to_update) > 0:
cell = to_update.pop(0)
for neighbour, offset in cell.get_neighbors():
# Usually, other implementations have an "if" statement here: "if neighbour is not collapsed:"
for pattern_index in cell.allowed_patterns:
pattern = Pattern.from_index(pattern_index)
pattern_still_compatible = False
for neighbour_pattern_index in neighbour.allowed_patterns:
neighbour_pattern = Pattern.from_index(neighbour_pattern_index)
if pattern.is_compatible(neighbour_pattern, offset):
pattern_still_compatible = True
break
if not pattern_still_compatible:
cell.allowed_patterns.remove(pattern_index)
# What happens if the cell has now 0 pattern available because of this removal ?
for neigh, _ in cell.get_neighbors():
if neigh not in to_update:
to_update.append(neigh)
# Also, what happens if you put in the stack a neighbor that a has been collapsed ?