Python, Game of Life Implementation

Asked

Viewed 64 times

0

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

The code I have at the moment is as follows::

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 is obviously not optimized, the problem is that the expected result is not equal to the one shown.

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

Each cell will interact with its 8 neighbors: vertical, horizontal, diagonal. Consider V as neighbor, and X as the cell we’re checking.

V | V | V
V | X | V
V | V | V
  1. Any cell with less than 2 neighbors will die
  2. Any cell with 2 or 3 neighbors will survive to the next generation
  3. Any living cell with more than 3 neighbors will die
  4. Any dead cell with exactly 3 neighbors becomes alive

Online Implementation

Where could be the error in my code?

1 answer

1


The problem is that you use to count neighbors the same data structure that you are modifying for the next generation - When checking the neighbors of the cells in the line "2", the line "1" that its function checkNeighbors "sees" has been altered, and has cells dead and pathways different than what were on the screen.

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

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

Browser other questions tagged

You are not signed in. Login or sign up in order to post.