Conway’s Life

“When I see a new mathematical book for a general audience, I turn to the index, I look for a certain name in the back, and if I see this name, it shines out at me somehow. And it says, page 157, pages 293–298, or whatever. So I eagerly turn to those pages, hoping to see some mention of my discoveries. I only ever see the Game of Life. I am not ashamed of it; it was a good game. It said things that needed to be said. But I’ve discovered so many more things, and that was, from a certain point of view, rather trite—to me anyway. It is a bit upsetting to be known for this thing that I consider in a way rather trivial.”

John Conway, American Mathematical Society Interview

I wrote a quick and dirty implementation of Conway’s Life that runs on Drawbot that I needed to write for an illustration in HTSM. It’s largely based on a unique implementation style that I haven’t seen before by Robert Andrew Martin. FYI I failed at getting numpy running on Drawbot so it’s a bit kludgy and not nearly as elegant as the original implementation. Enjoy! —JM



size('A5Landscape')

# number of iterations to run the simulation
cycles = 100
# dimension of the rectangles that get drawn
dim = 32
# margin dimensions (not centered but good enough)
margin = 15
# whether to draw grid or not
drawgridp = True

rows, cols = (int((width()-2*margin)/dim), int((height()-2*margin)/dim))
 
universe = [[0 for i in range(cols)] for j in range(rows)] 
new_universe = [[0 for i in range(cols)] for j in range(rows)] 

beacon = [[0, 0, 0, 0, 0, 0],
          [0, 1, 1, 0, 0, 0],
          [0, 1, 1, 0, 0, 0],
          [0, 0, 0, 1, 1, 0],
          [0, 0, 0, 1, 1, 0],
          [0, 0, 0, 0, 0, 0]]

glider = [[0, 0, 0, 0, 0, 0],
          [0, 0, 1, 0, 0, 0],
          [0, 0, 0, 1, 0, 0],
          [0, 1, 1, 1, 0, 0],
          [0, 0, 0, 0, 0, 0],
          [0, 0, 0, 0, 0, 0]]

def copysrcdest(src,dest, xoff = 0, yoff = 0):
    for a in range(len(src)):
        for b in range(len(src[0])):
            dest[a+xoff][b+yoff] = src[a][b]

def within_bounds(x,y,maxx,maxy):
    if x < 0 or y < 0:
        return False
    if x >= maxx or y >= maxy:
        return False
    return True


def randomize_universe(u, amount):
    for a in range(len(u)):
        for b in range(len(u[0])):
            if random()< amount:
                u[a][b] = 1

def count_neighbors(u,x,y):
    xlen = len(u)
    ylen = len(u[0])
    x0 = x-1
    y0 = y-1
    x1 = x+1
    y1 = y+1
    cnt = 0
    # proceed clockwise from upper left (x0,y0)
    if within_bounds(x0,y0, xlen,ylen): 
        cnt += u[x0][y0]
    if within_bounds(x,y0, xlen,ylen): 
        cnt += u[x][y0]
    if within_bounds(x1,y0, xlen,ylen): 
        cnt += u[x1][y0]

    if within_bounds(x1,y, xlen,ylen): 
        cnt += u[x1][y]

    if within_bounds(x1,y1, xlen,ylen): 
        cnt += u[x1][y1]
    if within_bounds(x,y1, xlen,ylen): 
        cnt += u[x][y1]
    if within_bounds(x0,y1, xlen,ylen): 
        cnt += u[x0][y1]

    if within_bounds(x0,y, xlen,ylen): 
        cnt += u[x0][y]

    return cnt

randomize_universe(new_universe,.5)
copysrcdest(glider,new_universe)

for cycle in range(cycles):
    
    text("%04d"%cycle,(2,2))
    translate(margin,margin)
    frameDuration(1/20)
    copysrcdest(new_universe,universe)
    for x in range(len(universe)):
        for y in range(len(universe[0])):
            if universe[x][y]>0:
                rect(x*dim+1,y*dim+1,dim-2,dim-2)
            num_neighbors = count_neighbors(universe,x,y)
            if universe[x][y] and not 2 <= num_neighbors <= 3:
                new_universe[x][y] = 0
            elif num_neighbors == 3:
                new_universe[x][y] = 1 

    if drawgridp:
        stroke(0)
        for x in range(len(universe)+1):
            line((x*dim,0),(x*dim,dim*len(universe[0])))
        for y in range(len(universe[0])+1):
            line((0,y*dim),(dim*len(universe),y*dim))

    if cycle != cycles-1:
        newPage(width(),height())
    

saveImage("conwaylife.gif")

As a small courtesy the a few PDF links will be sent to you soon after you sign up! —@johnmaeda

Leave a Reply