I found online a separate approach using a dictionary of live cells that should accelerate matters greatly, as it only deals in each iteration strictly with those cells that need watching, neglecting the majority of cells that cannot evolve in a given step of the game. For this it relies on the use of the __missing__ method to return zero values for any cell not presently in the dictionary. The (steamlined) code is below. It returns the error
Traceback (most recent call last):
File "<stdin>", line 62, in <module>
File "<stdin>", line 46, in play_game
File "<stdin>", line 18, in check_cell
KeyError: (24, 13)
Which seems to indicate that __missing__ is not working as it should (that Key indeed corresponds to the coordinates of a cell being accessed that is not present in the dictionary up front). I have tried a couple of things by importing defaultdict etc, to no avail. Can anyone help? Thanks in advance.
Code: Select all
import time
class Life(dict):
def __init__(self, *args, **kwargs):
super(Life, self).__init__(*args, **kwargs)
def __missing__(self, *args, **kwargs):
return 0
def check_cell(self, x: int, y: int): #determine if cell lives or dies
x_coords = (x-1, x, x+1)
y_coords = (y-1, y, y+1)
total = 0
for x_coord in x_coords:
for y_coord in y_coords:
total += self[x_coord, y_coord]
live, dead = [], []
cell = self[x, y]
if total == 3 and not cell:
live.append((x, y))
elif total < 3 or total > 4 and cell:
dead.append((x, y))
elif cell:
pass
return live, dead
def queue_cells(self):
cells = []
for x, y in self.keys():
# Add all cell neighbors to the function.
x_coords = (x-1, x, x+1)
y_coords = (y-1, y, y+1)
for x_coord in x_coords:
for y_coord in y_coords:
cells.append((x_coord, y_coord))
# print(cells)
return cells
def play_game(self):
live, dead = [], []
# Create all the transitions for the turn
for x, y in self.queue_cells():
step_live, step_dead = self.check_cell(x, y)
live += step_live
dead += step_dead
# Apply all transitions. Remember that in Life, the state of the board
# doesn't change until every cell is accounted for.
for x, y in dead:
if self[x, y]:
del self[x, y]
for x, y in live:
self[x, y] = 1
game = Life({(25, 15): 1, (26, 15): 1, (25, 16): 1, (24, 16): 1, (25, 17): 1,})
while 1:
# display.fill(0)
game.play_game()
# screen.refresh()
time.sleep(.1)