Python, Game of Life Implementation

0

I noticed that there is already a question related to this question, but my implementation will be different.

The code I have at the moment is the following:

import sys, pygame
pygame.init()

size = width, height = 125, 125

black = 0,0,0
white = 255,255,255

geracao = 0


pixelarray = [[0 for x in range(width)] for y in range(height)] 

screen = pygame.display.set_mode(size)

def drawPixelAt(x,y, color = black, surface = screen):
    surface.set_at((x,y), color )

def getPixelAt(x,y, surface = screen):
    return surface.get_at((x,y))


def drawPixelArray():
    for i in range(height):
        for j in range(width):
            if(pixelarray[i][j] == "X"):
                drawPixelAt(j,i)


def printMatrix():

    quadro = "\n"

    for i in range(height):
        for j in range(width):
            quadro += " " + str(pixelarray[i][j])
        quadro += "\n"

    print(quadro)

def checkNeighbours(x,y):
    vizinhos = 0
    # posicao inicial
    posX = x -1
    posY = y -1



    for i in range(3):
        for j in range(3):          
            finalX = posX + j
            finalY = posY + i

            if( finalX < 0 ):
                finalX+=1 # avanca para a proxima posicao
            if( finalY < 0 ):
                finalY+=1 # avanca para a proxima posicao

            if( finalX > pixelarray.__len__() -1 or finalY > pixelarray.__len__() -1):
                break # salta este laco, nao e preciso verificar uma coisa que nao existe

            # verifica se a posicao que se esta a verificar nao e o centro
            if( finalX != x or finalY != y):
                #pixelarray[finalY][finalX] = "-"
                # se tem um vizinho
                if(pixelarray[finalY][finalX] == "X"):
                    vizinhos+=1
    #print("Tem {0} vizinhos".format(vizinhos))
    return vizinhos

def makeLife():
    # percorre toda a matriz
    for i in range(pixelarray.__len__()):        
        for j in range(pixelarray.__len__()):
            vizinhos = checkNeighbours(j,i)

            if( pixelarray[i][j] == 0):
                if(vizinhos == 3):
                    pixelarray[i][j] = "X"
            else:
                if( vizinhos < 2):
                    pixelarray[i][j] = 0

                if(vizinhos == 2 or vizinhos == 3):
                    pixelarray[i][j] = "X"

                if(vizinhos > 3):
                    pixelarray[i][j] = 0


    global geracao 
    geracao += 1
    print("{0} Geração".format(geracao))


pixelarray[0][1] = "X"
pixelarray[1][0] = "X"
pixelarray[2][0] = "X"
pixelarray[2][1] = "X"
pixelarray[1][2] = "X"
pixelarray[0][1] = "X"
pixelarray[0][2] = "X"



while 1:
    screen.fill(white)

    for event in pygame.event.get():
        if event.type == pygame.QUIT: sys.exit()

        elif event.type == pygame.KEYDOWN:
            #if event.key == pygame.K_UP:
            #makeLife()
            if event.key == pygame.K_g:
                pygame.display.set_mode(size)
            if event.key == pygame.K_f:
                    pygame.display.set_mode(size, pygame.FULLSCREEN)


    makeLife()

    drawPixelArray()

    pygame.display.flip()

The code obviously is not optimized, the problem is that the expected result is not the same as the one presented.

For those who do not know the Game of Life is based on the following rules:

Each cell will interact with its 8 neighbors ie vertical, horizontal, diagonal. Consider V as a neighbor, and X as the cell we are checking.

V | V | V
V | X | V
V | V | V
  • Any cell with less than 2 neighbors will die
  • Any cell with 2 or 3 neighbors will come to the next generation
  • Any living cell with more than 3 neighbors will die
  • Any dead cell with exactly 3 neighbors becomes alive
  • Online Implementation

    Where could the error be in my code?

        
    asked by anonymous 09.03.2018 / 16:19

    1 answer

    1

    The problem is that you use to tell neighbors the same data structure you are modifying for the next generation - When you check the cell neighbors on line 2, the line "1" that your checkNeighbors "sees" function has already changed, and has different path and dead cells than were on the screen.

    You have to tell neighbors based on a "photo" of this generation - and create living or dead cells in a separate structure.

    You can use copy.deepcopy of module copy of the default library to copy its pixelArray structure. The function that checks the neighbors has to use a copy made before you create the cells for the next generation.

        
    09.03.2018 / 19:17