Basis: een volgende rastertoestand¶
Een raster stelt bezette (1) en lege (0) vakken voor. Bereken een volgende toestand zonder het invoerbord onderweg te veranderen. Gebruik een rechthoekige lijst van lijsten. Coördinaten buiten het bord tellen als 0 en worden nooit geschreven.
Voorbeeld en interfaces¶
Bij een 5x5-blinker wordt de verticale lijn horizontaal:
00000 00000
00100 00000
00100 -> 01110
00100 00000
00000 00000
Werk in deze volgorde: count_neighbors, next_cell, next_generation. De laatste functie is functiecompositie: zij gebruikt de eerste twee.
1. Buren tellen¶
Ontwerp de functie. Loop over de acht relatieve posities, tel buiten het bord als 0 en test een hoek, rand en binnen-cel.
Tussenstap. Voor bord[0][0] kijk je naar de acht posities rond de hoek. Alleen (0, 1) en (1, 0) liggen binnen dit bord; de waarden daar zijn 1 en 0, dus de telling is 1. Schrijf dit eerst als een zin op en vertaal het daarna naar je lus.
def count_neighbors(board, row, col):
# loop over de acht relatieve buurposities
# tel buiten het bord als 0
pass
bord = [[1, 1, 0, 0, 0], [0, 0, 1, 0, 0], [0, 0, 0, 1, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0]]
assert count_neighbors(bord, 0, 0) == 1
assert count_neighbors(bord, 0, 2) == 2
assert count_neighbors(bord, 2, 2) == 2
2. De regel voor één cel¶
Schrijf next_cell(board, row, col). Een levende cel blijft leven met twee of drie buren. Een dode cel wordt levend met precies drie buren. Anders is de uitkomst 0.
def next_cell(board, row, col):
# gebruik count_neighbors en de vier regels hierboven
pass
3. Een volledige generatie¶
Gebruik deze gegeven kopieerfunctie. Bereken elke cel uit board en schrijf alleen naar result. Voeg assertions toe voor de blinker en het onveranderde invoerbord.
def copy_board(board):
result = []
for row in board:
result = result + [row[:]]
return result
def next_generation(board):
result = copy_board(board)
# bereken elke cel uit board en schrijf naar result
pass
blinker = [[0, 0, 0, 0, 0], [0, 0, 1, 0, 0], [0, 0, 1, 0, 0], [0, 0, 1, 0, 0], [0, 0, 0, 0, 0]]
verwacht = [[0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 1, 1, 1, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0]]
origineel = copy_board(blinker)
assert next_generation(blinker) == verwacht
assert blinker == origineel
4. Korte functiecompositie¶
Maak generaties(board, aantal) door next_generation herhaald toe te passen.
Controleer eerst je tussenstap: na één toepassing op de verticale blinker verwacht je een horizontale rij levende cellen in de middelste rij. Controleer daarna pas dat twee generaties weer gelijk zijn aan het oorspronkelijke bord.
def generaties(board, aantal):
huidig = board
for _ in range(aantal):
huidig = next_generation(huidig)
return huidig
assert generaties(blinker, 2) == blinker