1

I'm trying to make the Conway Game of Life in Python with pygame. I'm running into an issue but I'm not quite sure of the nature of it. The first turn of the game seems to go smoothly, but the second turn activates way too many cells, and then it seems to be slow-spreading chaos from that point on. Here is the code.

comp.py:

import pygame
import stage

class Node:

    onoff = False

    def __init__(self,x,y):
        self.x = x
        self.y = y

    def pos(self,x,y):
        self.x = x
        self.y = y
        self.n1 = [x,(y-1)]
        self.n2 = [(x+1),(y-1)]
        self.n3 = [(x+1),y]
        self.n4 = [(x+1),(y+1)]
        self.n5 = [x,(y+1)]
        self.n6 = [(x-1),(y+1)]
        self.n7 = [(x-1),y]
        self.n8 = [(x-1),(y-1)]
        
    def nCount(self): #neighbor counter
        ns = 0
        counter = {
            True: 1,
            False: 0
        }
        try:
            ns += counter[stage.stage1.bg[self.n1[0]][self.n1[1]].onoff]
            ns += counter[stage.stage1.bg[self.n2[0]][self.n2[1]].onoff]
            ns += counter[stage.stage1.bg[self.n3[0]][self.n3[1]].onoff]
            ns += counter[stage.stage1.bg[self.n4[0]][self.n4[1]].onoff]
            ns += counter[stage.stage1.bg[self.n5[0]][self.n5[1]].onoff]
            ns += counter[stage.stage1.bg[self.n6[0]][self.n6[1]].onoff]
            ns += counter[stage.stage1.bg[self.n7[0]][self.n7[1]].onoff]
            ns += counter[stage.stage1.bg[self.n8[0]][self.n8[1]].onoff]
        except IndexError as error:
            pass
        if (ns > 3):
            ns = 3
        return ns
        
    onImg = pygame.image.load("C:\\Users\\#####\\PythonScripts\\conway\\tiles\\light2.png")
    offImg = pygame.image.load("C:\\Users\\#####\\PythonScripts\\conway\\tiles\\dark.png")

stage.py:

import comp

class Stage:
    
    bg = [[comp.Node(0,0) for _ in range(100)] for _ in range(100)]

    def drawNodes(self):
        for i in range(100):
            for j in range(100):
                self.bg[i][j].pos(i,j)

stage1 = Stage()

systems.py:

import pygame
import comp
import stage

pygame.init()

win = pygame.Surface((100,100))

screen = pygame.display.set_mode((500,500))

def ruleFilter(node):
    n = {
        0: False,
        1: False,
        2: True,
        3: False
    }
    node.onoff = n[node.nCount()]

def turn(bg,x=100,y=100):
    for i in range(x):
        for j in range(y):
            ruleFilter(bg[i][j])
    for i in range(x):
        for j in range(y):
            if (bg[i][j].onoff == True):
                win.blit(bg[i][j].onImg,(i,j))
            else:
                win.blit(bg[i][j].offImg,(i,j))


# Here is the main loop. Two nodes have been turned on to initiate the algorithm.

run = True

stage.stage1.drawNodes()
stage.stage1.bg[10][10].onoff = True
stage.stage1.bg[10][11].onoff = True

while run==True:
    for event in pygame.event.get():
        if event.type==pygame.QUIT:
            run=False
    
    turn(stage.stage1.bg)
    
    win2 = pygame.transform.scale(win,(500,500))
    
    for x in range(100):
        for y in range(100):
            screen.blit(win2,(x,y))
    
    pygame.display.flip()
    
    pygame.time.delay(100)

pygame.quit()

Pay no attention to the ugly bars to the top and left of the screen...that's an issue for the future. :)

wobbysobby
  • 13
  • 4
  • 2
    Are you altering the node's state during the calculation of the new state? That is a common way of getting the wrong result. You need to calculate the new state for every node before you update the state of any of them. – khelwood Feb 04 '22 at 15:24
  • If you get an IndexError in your nCount method, you will miss checking any neighbours in the rest of the try block. – khelwood Feb 04 '22 at 15:26
  • Ah, that makes sense! Thank you, I will go over my code with this new advice. I am admittedly rusty on exception handling. – wobbysobby Feb 04 '22 at 15:29

0 Answers0