Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Game of Life patterns carried out incorrectly

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:

  • I broke up the logic statements in my code to use no and / or statements.
  • I tested my neighbors() function by inserting it into its own program, and setting up some grid configurations.
  • Then I looked at the printed out grid, and I called 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.

like image 429
Luke Taylor Avatar asked Mar 02 '15 14:03

Luke Taylor


1 Answers

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.

like image 78
Isaac Drachman Avatar answered Oct 19 '22 22:10

Isaac Drachman