My Conway's game of life implementation in Python doesn't seem to follow the rules correctly, and I can't figure out what could be wrong. When I put a final configuration into Golly, it continues past what mine did.
I first identified the program by putting a configuration at which my program stopped into Golly, and then noticing that it could be carried further.
I also put an entire small board from my game into Golly, and it progressed much differently from my configuration. Golly is a game of life simulator that's widely used.
I've tried several different things to fix my problem:
and
/ or
statements.neighbors()
function by inserting it into its own program, and setting up some grid configurations.neighbors()
on a certain position. It worked perfectly.Looking at my code, I can't see why it's not working. I don't get errors, it works, it just works wrong. The patterns progress much differently than how they should. This is also the first > 100 line program that I have written without following a tutorial even loosely, so forgive me if the answer is obvious.
The relevant code is as follows:
#Function to find number of live neighbors
def neighbors(row, column):
adjacents = 0
#Horizontally adjacent
if row > 0:
if board[row-1][column]:
adjacents += 1
if column > 0:
if board[row][column-1]:
adjacents += 1
if row < thesize-1:
if board[row+1][column]:
adjacents += 1
if column < thesize-1:
if board[row][column+1]:
adjacents += 1
#Diagonally adjacent
if row > 0 and column > 0:
if board[row-1][column-1]:
adjacents += 1
if row < thesize-1 and column < thesize-1:
if board[row+1][column+1]:
adjacents += 1
if row > 0 and column < thesize-1:
if board[row-1][column+1]:
adjacents += 1
if row < thesize-1 and column > 0:
if board[row+1][column-1]:
adjacents += 1
#Return the final count (0-8)
return adjacents
This seems to work perfectly to return how many of the 8 neighbors of any given cell are alive. This next bit is the logic part, where I think the problem is. It changes the array according to the rules of the game.
#Main loop
while 1:
#Manage the rules of the game
for r in range(len(board)):
for c in range(len(board)):
neighborcount = neighbors(r, c)
if board[r][c]:
giveLife(r, c)
if neighborcount < 2 or neighborcount > 3:
board[r][c] = False
elif not board[r][c]:
killRuthlessly(r, c)
if neighborcount == 3:
board[r][c] = True
Finally, the part that turns squares on and off visually, on the pygame screen. This is tested, and appears to work well, I just thought I'd include it in case there's an issue.
for r in range(len(board)):
for c in range(len(board)):
if board[r][c]:
giveLife(r, c)
if not board[r][c]:
killRuthlessly(r, c)
giveLife
is a function that draws a black rectangle at the given position, killRuthlessly
draws a white one. These both seem to work properly.
For the logic that loops through the board and checks adjacent cells, it is turning cells on/off while continuing to check others. It is likely you are reading adjacent cells as live or dead not because they were in the previous time step (which matters), but because you've changed their state as they have been already looped over. Try creating a tmp_board
which copies the current board and to which edits are done. Then copy it back to board
after you've looped over everything.