“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")
Sign up for the Resilience Tech Briefing with no more than 2022 characters, zero images, and all in plain-text.
As a small courtesy the a few PDF links will be sent to you soon after you sign up! —@johnmaeda