5
\$\begingroup\$

I've made a game of life in pygame. I need it to get it to run as fast as possible. I've done everything I can think of.

import random,time,json,ujson
import pygame as py
from copy import deepcopy

dwidth=1500
dheight=800
display=py.display.set_mode((dwidth,dheight))
clock=py.time.Clock()

py.init()

black=[0,0,0]
green=[0,255,0]
red=[255,0,0]
gray=[180,180,180]
white=[255,255,255]
blue=[0,0,255]
yellow=[255,255,0]
silver=[200,200,200]
orange=[255,165,0]
darkblue=[0,0,205]

sqsize=2
rnum,cnum=round(dheight/sqsize),round(dwidth/sqsize)
grid=[]
for i in range(rnum):
    grid.append([])
for a in range(rnum):
    for b in range(cnum):
        choice=random.randint(0,100)
        if choice<40:
            grid[a].append(1)
        else:
            grid[a].append(0)
newgrid=ujson.loads(ujson.dumps(grid))
orgrid=ujson.loads(ujson.dumps(grid))
def cneighb(a,b):
    num=0
    if a==0:
        am=rnum-1
    else:
        am=a-1
    if b==0:
        bm=cnum-1
    else:
        bm=b-1
    if a==rnum-1:
        ap=0
    else:
        ap=a+1
    if b==cnum-1:
        bp=0
    else:
        bp=b+1

    num+=grid[am][b]
    num+=grid[am][bp]
    num+=grid[a][bp]
    num+=grid[ap][bp]
    num+=grid[ap][b]
    num+=grid[ap][bm]
    num+=grid[a][bm]
    num+=grid[am][bm]
    return num

exit=False
display.fill(gray)
while not exit:
    for event in py.event.get():
        if event.type==py.QUIT:
            exit=True

    for a in range(rnum):
        for b in range(cnum):
            cn=cneighb(a,b)
            if grid[a][b]==1:
                if cn<2 or cn>3:
                    newgrid[a][b]=0
            else:
                if cn==3:
                    newgrid[a][b]=1
    grid=ujson.loads(ujson.dumps(newgrid))
    for a in range(rnum):
        for b in range(cnum):
            if grid[a][b]==0:
                if orgrid[a][b]!=0:
                    py.draw.rect(display,gray,(b*sqsize,a*sqsize,sqsize,sqsize))
            elif orgrid[a][b]!=1:
                py.draw.rect(display,yellow,(b*sqsize,a*sqsize,sqsize,sqsize))
    orgrid=ujson.loads(ujson.dumps(grid))
    #clock.tick(10)
    py.display.update()

Edit: here's the new version of the code with the recommended suggestion but it made it much slower. Any suggestions?

import random,time,json,ujson
import pygame as py
from copy import deepcopy

dwidth=1500
dheight=800
display=py.display.set_mode((dwidth,dheight))
clock=py.time.Clock()

py.init()

black=[0,0,0]
green=[0,255,0]
red=[255,0,0]
gray=[180,180,180]
white=[255,255,255]
blue=[0,0,255]
yellow=[255,255,0]
silver=[200,200,200]
orange=[255,165,0]
darkblue=[0,0,205]

sqsize=4
rnum,cnum=round(dheight/sqsize),round(dwidth/sqsize)
grid=[]
cgrid=[]
for i in range(rnum):
    grid.append([])
for a in range(rnum):
    for b in range(cnum):
        cgrid.append([a,b])
        choice=random.randint(0,100)
        if choice<=60:
            grid[a].append(1)
        else:
            grid[a].append(0)

newgrid=ujson.loads(ujson.dumps(grid))
orgrid=ujson.loads(ujson.dumps(grid))
def cneighb(a,b):
    num=0
    if a==0:
        am=rnum-1
    else:
        am=a-1
    if b==0:
        bm=cnum-1
    else:
        bm=b-1
    if a==rnum-1:
        ap=0
    else:
        ap=a+1
    if b==cnum-1:
        bp=0
    else:
        bp=b+1

    num+=grid[am][b]
    num+=grid[am][bp]
    num+=grid[a][bp]
    num+=grid[ap][bp]
    num+=grid[ap][b]
    num+=grid[ap][bm]
    num+=grid[a][bm]
    num+=grid[am][bm]
    return num,[[am,b],[am,bp],[a,bp],[ap,bp],[ap,b],[ap,bm],[a,bm],[am,bm]]

count=0
exit=False
display.fill(gray)
while not exit:
    for event in py.event.get():
        if event.type==py.QUIT:
            exit=True

    newcgrid=[]
    for i in cgrid:
        a,b=i[0],i[1]
        cn1,cn2=cneighb(a,b)
        if grid[a][b]==1:
            if cn1<2 or cn1>3:
                newgrid[a][b]=0
                newcgrid+=cn2
        else:
            if cn1==3:
                newgrid[a][b]=1
                newcgrid+=cn2
    grid=ujson.loads(ujson.dumps(newgrid))
    for i in cgrid:
        a,b=i[0],i[1]
        if grid[a][b]==0:
            if orgrid[a][b]!=0:
                py.draw.rect(display,gray,(b*sqsize,a*sqsize,sqsize,sqsize))
        elif orgrid[a][b]!=1:
            py.draw.rect(display,yellow,(b*sqsize,a*sqsize,sqsize,sqsize))
    cgrid=ujson.loads(ujson.dumps(newcgrid))
    orgrid=ujson.loads(ujson.dumps(grid))
   # clock.tick(1)
    py.display.update()
\$\endgroup\$
3
\$\begingroup\$

You will get better performance if you cache the cells that changed in the last generation and only check them and their neighbours in the next generation. This is less of a problem with small grids, but you have 1,200,000 cells. It's highly unlikely that even a significant fraction of those will change in a given generation.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.