Search code examples
pythonconways-game-of-life

Python - Conways Game of life


It seems my process isn't applying to the next iteration. I have deep copies in main, and I think the problem lies within them and when they are called.

Spacing is a little off, my apologies.

Problem is in my results, it prints the first iteration fine with the alive cells. Then the next iterations are blank and shows no change in cells.

LIVING_CELL = 'A'
DEAD_CELL = '.'

#Get the alive cells from the user
def getBoard(rows, cols, boardList):
   myList = [[0]*cols for i in range(rows)]

   while True:

        aliveRows = input("Please enter a row of a cell to turn on (or q to exit): ")
        if aliveRows == 'q':
            break
        aliveCols = input("Please enter a column for that cell: ")
        print()
        myList[int(aliveRows)][int(aliveCols)] = 1
   return myList

#next board cells
def getNxtIter(cols, rows, cur, nxt):
    for i in range(1,rows-1):
        for j in range(1,cols-1):
            nxt[i][j] = getNeighbors(i, j, cur)

#Processing the neighbor cells
def getNeighbors(x, y, boardList):
    nCount = 0
    for j in range(y-1,y+2):
        for i in range(x-1,x+2):
            if not(i == x and j == y):
                if boardList[i][j] != -1:
                    nCount += boardList[i][j]
    if boardList[x][y] == 1 and nCount < 2:
        return 0
    if boardList[x][y] == 1 and nCount > 3:
       return 1
    else:
        return boardList[x][y]

#Printing and forming the actual board
def printBoard(cols, rows, boardList):
    for i in range(rows+2):
        for j in range(cols+2):
            if boardList[i][j] == -1:
                print(DEAD_CELL, end=" ")
            elif boardList[i][j] == 1:
                print(LIVING_CELL, end=" ")
            else:
               print(DEAD_CELL, end=" ")
        print()

def main():
#Getting and validating the number of rows and columns
    x = 1
    while x ==1:

        rows = int(input("Please enter the number of rows: "))
        if rows < 0:
            x = 1
        elif rows> 50:
            x = 1
        else:
            x =0

    n = 1
    while n == 1:
        cols = int(input("Please enter the number of columns: "))
        if cols < 0:
            n = 1
        elif cols > 50:
            n = 1
        else:
            n = 0

    boardList = []
    newBoardList = []
    boardList = getBoard(rows, cols, boardList)
    newBoardList = [x[:] for x in boardList]

    print()

#Getting iterations to run, and validating if <= 0
    a = 1
    while a == 1:
        iterations = int(input("How many iterations should I run? "))+1
        if iterations <= 0:
            a = 1
        else:
            a = 0
    for count in range(iterations):
        print()
        print("Iteration:", count)
        print()
        printBoard(cols, rows, boardList)
        getNxtIter(cols, rows, boardList, newBoardList)
        boardList = [x[:] for x in newBoardList]
        newBoardList = [x[:] for x in boardList]
main()

Solution

  • As you seem to be having problems applying the multiple changes from the other answer, here's a simplified and cleaned up version that I have tested and am certain works in Python 3:

    LIVING_CELL = 'A'
    DEAD_CELL = '.'
    
    #Get the alive cells from the user
    def getBoard(rows, cols):
        myList = [[0]*cols for i in range(rows)]
        while True:
            raw = input('Please enter "row <space> column", of a cell to turn on (RETURN to exit): ')
            if raw == '':
                break
            splitted = raw.split()
            if len(splitted) != 2:
                print("Invalid input")
            else:
                row, col = int(splitted[0]), int(splitted[1])
                if row >= rows or col >= cols:
                    print("Invalid row/column value")
                else:
                    myList[row][col] = 1
                    printBoard(rows, cols, myList)
        return myList
    
    #next board cells
    def getNxtIter(rows, cols, cur, nxt):
        for i in range(rows):
            for j in range(cols):
                nxt[i][j] = getNeighbors(rows, cols, i, j, cur)
    
    #Processing the neighbor cells
    def getNeighbors(rows, cols, x, y, boardList):
        nCount = 0
        for j in range(y-1,y+2):
            for i in range(x-1,x+2):
                if not(i == x and j == y):
                    itest, jtest = i, j
                    if itest == rows:
                        itest = 0
                    if jtest == cols:
                        jtest = 0
                    nCount += boardList[itest][jtest]
        if nCount == 3 or (boardList[x][y] == 1 and nCount == 2):
            return 1
        return 0
    
    #Printing and forming the actual board
    def printBoard(rows, cols, boardList):
        for i in range(rows):
            line = []
            for j in range(cols):
                if boardList[i][j] == 1:
                    line.append(LIVING_CELL)
                else:
                    line.append(DEAD_CELL)
            print("".join(line))
    
    def main():
        #Getting and validating the number of rows and columns
        while True:
            rows = int(input("Please enter the number of rows: "))
            if rows > 0 and rows <= 50:
                break
    
        while True:
            cols = int(input("Please enter the number of columns: "))
            if rows > 0 and rows <= 50:
                break
    
        boardList = getBoard(rows, cols)
        newBoardList = [x[:] for x in boardList]
    
        print()
    
        #Getting iterations to run, and validating if <= 0
        while True:
            iterations = int(input("How many iterations should I run? "))+1
            if iterations > 0:
                break
    
        for count in range(iterations):
            print()
            print("Iteration:", count)
            print()
            printBoard(rows, cols, boardList)
            getNxtIter(rows, cols, boardList, newBoardList)
            boardList, newBoardList = newBoardList, boardList
    
    main()
    

    I improved the performance of the printing code too, it got very slow with big boards.

    I tested it by firing a Glider at a Blinker on a 20x20 board, seems to work fine.