3

I have an implemented Conway's Game of Life as:

def neighbors(point):
    x, y = point
    for i, j in itertools.product(range(-1, 2), repeat=2):
        if any((i, j)):
            yield (x + i, y + j)

def advance(board):
    newstate = set()
    recalc = board | set(itertools.chain(*map(neighbors, board)))

    for point in recalc:
        count = sum((neigh in board)
                for neigh in neighbors(point))
        if count == 3 or (count == 2 and point in board):
            newstate.add(point)

    return newstate

I want to visualize the result, so I tried to modify the given example from Matplotlib animation example:

glider = set([(0, 0), (1, 0), (2, 0), (0, 1), (1, 2)])

fig, ax = plt.subplots()

x, y = zip(*glider)
mat, = ax.plot(x, y, 'o')

def animate(i):
    glider = advance(glider)
    x, y = zip(*glider)
    mat.set_data(x, y)
    return mat,

ani = animation.FuncAnimation(fig, animate, interval=50)
plt.show()

but that just plots the initial points.

Yulian
  • 365
  • 4
  • 12
  • You might be interested in other matplotlib implementations of the game of life, like [this one](https://stackoverflow.com/questions/45653550/stopping-animation-conways-game-of-life) or [this one](https://stackoverflow.com/questions/46196346/why-does-my-game-of-life-simulation-slow-down-to-a-crawl-within-seconds-matplot). – ImportanceOfBeingErnest Oct 20 '17 at 13:35

1 Answers1

5

The code you have should actually produce an error. The problem is that you reference glider before you assign it.

Mind the local scope of variables in python functions. E.g. try

a = 0
def f():
    a = a + 1
f()

which will give you the same error.

In your code of Conway's Game of Life, you can circumvent this by making glider available to the global scope, global glider. Also make sure your axes limits allow for the animation to be seen.

Complete example:

import itertools
import matplotlib.pyplot as plt
import matplotlib.animation as animation

def neighbors(point):
    x, y = point
    for i, j in itertools.product(range(-1, 2), repeat=2):
        if any((i, j)):
            yield (x + i, y + j)

def advance(board):
    newstate = set()
    recalc = board | set(itertools.chain(*map(neighbors, board)))

    for point in recalc:
        count = sum((neigh in board)
                for neigh in neighbors(point))
        if count == 3 or (count == 2 and point in board):
            newstate.add(point)

    return newstate

glider = set([(0, 0), (1, 0), (2, 0), (0, 1), (1, 2)])

fig, ax = plt.subplots()

x, y = zip(*glider)
mat, = ax.plot(x, y, 'o')

def animate(i):
    global glider
    glider = advance(glider)
    x, y = zip(*glider)
    mat.set_data(x, y)
    return mat,

ax.axis([-15,5,-15,5])
ani = animation.FuncAnimation(fig, animate, interval=50)
plt.show()

enter image description here

ImportanceOfBeingErnest
  • 321,279
  • 53
  • 665
  • 712