Click here to Skip to main content
15,888,984 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
I'm trying to make a quick demo of Conway's Game of life using python. When I run the code I've written below It seems to work, but when used in specific cases, like with an oscillator, everything falls apart.

(I have example outputs below)

What I have tried:

Python
import time
import os

def main():
    oldRows=[["-","-","-","-","-","-","-","-","-","-"],
             ["-","-","-","-","-","-","-","-","-","-"],
             ["-","-","-","-","-","-","-","-","-","-"],
             ["-","-","-","-","+","-","-","-","-","-"],
             ["-","-","-","-","+","-","-","-","-","-"],
             ["-","-","-","-","+","-","-","-","-","-"],
             ["-","-","-","-","-","-","-","-","-","-"],
             ["-","-","-","-","-","-","-","-","-","-"],
             ["-","-","-","-","-","-","-","-","-","-"],
             ["-","-","-","-","-","-","-","-","-","-"]]

    newRows=[["-","-","-","-","-","-","-","-","-","-"],
             ["-","-","-","-","-","-","-","-","-","-"],
             ["-","-","-","-","-","-","-","-","-","-"],
             ["-","-","-","-","-","-","-","-","-","-"],
             ["-","-","-","-","-","-","-","-","-","-"],
             ["-","-","-","-","-","-","-","-","-","-"],
             ["-","-","-","-","-","-","-","-","-","-"],
             ["-","-","-","-","-","-","-","-","-","-"],
             ["-","-","-","-","-","-","-","-","-","-"],
             ["-","-","-","-","-","-","-","-","-","-"]]

    printBoard(oldRows)
    for i in range(5):
        cycle(oldRows, newRows)
        oldRows=newRows
        time.sleep(.2)
        os.system('clear')
    cycle(oldRows, newRows)


def printBoard(rows):
    print("______________________________")
    for r in range(len(rows)):
        for i in range(len(rows)):
            print(" " + rows[r][i] + " ", end="")
        print("")
    print("______________________________")


def checkPop(oldRows, r, i):
    popCount = 0

    # check the top row
    if (r != 0):
        if (i != 0):
            if (oldRows[r-1][i-1] == "+"):
                popCount+=1
        if (oldRows[r-1][i] == "+"):
                popCount+=1
        if (i != len(oldRows)-1):
            if (oldRows[r-1][i+1] == "+"):
                popCount+=1

    # check the middle row minus the center
    if (i != 0):
        if (oldRows[r][i-1] == "+"):
            popCount+=1
    if (i != len(oldRows)-1):
        if (oldRows[r][i+1] == "+"):
            popCount+=1

    # check bottom row
    if (r != len(oldRows)-1):
        if (i != 0):
            if (oldRows[r+1][i-1] == "+"):
                popCount+=1
        if (oldRows[r+1][i] == "+"):
            popCount+=1
        if (i != len(oldRows)-1):
            if (oldRows[r+1][i+1] == "+"):
                popCount+=1
    #print("(" + str(r) + "," + str(i) + ") p = " + str(popCount))
    return popCount


def checkBirth(oldRows, r, i):
    if (checkPop(oldRows, r, i) == 3):
        return True
    else:
        return False


def cycle(oldRows, newRows):
    for r in range(len(oldRows)):
        for i in range(len(oldRows)):

            # if the cell starts already dead
            if (oldRows[r][i] == "-"):
                # see if there are 3 live cells around it to bring it to life
                if checkBirth(oldRows, r, i):
                    newRows[r][i] = "+"
                else:
                    newRows[r][i] = "-"
            else:
                # kill if lack of population
                if (checkPop(oldRows, r, i) < 2):
                    newRows[r][i] = "-"

                # kill due to over crowding
                elif (checkPop(oldRows, r, i) > 3):
                    newRows[r][i] = "-"

                # live
                else:
                    newRows[r][i] = "+"
    printBoard(newRows)


if __name__ == "__main__":
    main()


Here's what happens when I run it ("-" is a dead cell and "+" is a live cell):

**Expected Output:**

Gen 1:

...- - + - - ...
...- - + - - ...
...- - + - - ...

Gen 2:

...- - - - -...
...- + + + -...
...- - - - -...

Gen 3:

...- - + - - ...
...- - + - - ...
...- - + - - ...

etc....


**Actual Output:**

Gen 1:

...- - + - - ...
...- - + - - ...
...- - + - - ...

Gen 2:

...- - - - -...
...- + + + -...
...- - - - -...

Gen 3:

...- - + + - ...
...- + - + - ...
...- - - - - ...

Gen 4:

...- - + + - ...
...- - + + - ...
...- - - - - ...
Posted
Updated 3-Nov-16 10:55am

1 solution

I think the problem is here:
Python
oldRows=newRows

You need to swap both boards.

Advice:
- you can simplify tour code by making the board bigger than the part displayed (1 row and column around) this way you code do not have to handle the boarders.
- If you want be serious about the game of life, you need to store initial patterns on more efficient format. RLE is a commonly used format.
Run-length encoding - Wikipedia[^]
Examples (from another language: HP Prime):
Python
RLEMap (1, 1, "3o!"); // Blinker
RLEMap (13, 5, "bo$3o$obo$3o$bo!"); // Pulsar
RLEMap (1, 6, "b3o$3o!"); // Toad
RLEMap (30, 5, "bo$3o$obo$3o$bo!"); // Pulsar
RLEMap (1, 17, "24bo11b$22bobo11b$12b2o6b2o12b2o$11bo3bo4b2o12b2o$2o8bo5bo3b2o14b$2o8bo3bob2o4bobo11b$10bo5bo7bo11b$11bo3bo20b$12b2o!"); // Glider Canon


You should learn to use the debugger as soon as possible. Rather than guessing what your code is doing, It is time to see your code executing and ensuring that it does what you expect.

The debugger allow you to follow the execution line by line, inspect variables and you will see that there is a point where it stop doing what you expect.
Debugger - Wikipedia, the free encyclopedia[^]

The debugger is here to show you what your code is doing and your task is to compare with what it should do.
When the code don't do what is expected, you are close to a bug.
 
Share this answer
 
v2

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900