Skip to content

Instantly share code, notes, and snippets.

@nst
Last active January 5, 2019 00:28
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nst/f7482d7b2b847911c9a89f347f093521 to your computer and use it in GitHub Desktop.
Save nst/f7482d7b2b847911c9a89f347f093521 to your computer and use it in GitHub Desktop.
Game of Life Visualization, now using PyCairo and ImageIO
#!/usr/bin/env python
# description: Game of Life Visualization
# author: Nicolas Seriot
# idea: https://twitter.com/JacobJoaquin/status/923681854254825473
# typical output: http://seriot.ch/visualization/gol.gif
# typical output: http://seriot.ch/visualization/gol2.gif
import cairo
import random
import imageio
import numpy
import math
from PIL import Image
NB_STEPS = 16
GRID_SIZE = 16
CELL_SIZE = 64
DENSITY = 0.3
def as_numpy_array(surface):
w = surface.get_width()
h = surface.get_height()
data = surface.get_data()
a = numpy.ndarray(shape=(h,w), dtype=numpy.uint32, buffer=data)
i = Image.frombytes("RGBA", (w,h), a, "raw", "BGRA", 0, 1)
return numpy.asarray(i)
def add_image(writer, surface):
a = as_numpy_array(surface)
writer.append_data(a)
def create_grid(N=24):
return [[0]*N for i in xrange(N)]
def fill_grid_randomly(g, density=0.5):
for x,y in [(x,y) for y in range(len(g)) for x in range(len(g[y]))]:
g[y][x] = 1 if random.uniform(0.0, 1.0) < density else 0
return g
def nb_neighbnours(grid, x, y):
size = len(grid)
W = (size + x-1) % size
E = (size + x+1) % size
N = (size + y-1) % size
S = (size + y+1) % size
return sum([grid[N][W], grid[N][x], grid[N][E],
grid[y][W], grid[y][E],
grid[S][W], grid[S][x], grid[S][E]])
def next(g):
new_grid = create_grid(N=len(g))
for x,y in [(x,y) for y in range(len(g)) for x in range(len(g[y]))]:
n = nb_neighbnours(g, x, y)
if (g[y][x] == 0 and n == 3) or (g[y][x] == 1 and n in [2,3]):
new_grid[y][x] = 1
return new_grid
def draw_grid(c, g, i):
for x,y in [(x,y) for y in range(len(g)) for x in range(len(g[y])) if g[y][x] == 1]:
center_x = CELL_SIZE + CELL_SIZE*x + CELL_SIZE / 2.0
center_y = CELL_SIZE + CELL_SIZE*y + CELL_SIZE / 2.0
c.arc(center_x, center_y, 2*i, 0, 2*math.pi)
c.stroke()
def main():
g = create_grid(N=GRID_SIZE)
fill_grid_randomly(g, density=DENSITY)
w = len(g)*CELL_SIZE + 2*CELL_SIZE
h = len(g)*CELL_SIZE + 2*CELL_SIZE
surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, w, h)
c = cairo.Context(surface)
c.set_source_rgb(1,1,1)
c.paint()
gif_writer = imageio.get_writer("gol.gif", mode='I', duration=0.5)
c.set_source_rgb(0,0,0)
c.set_line_width(2)
for num_gen in range(NB_STEPS):
draw_grid(c, g, num_gen)
add_image(gif_writer, surface)
g = next(g)
if __name__ == "__main__":
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment