Juego de la vida de Conway realizado en numpy y animado con matplotlib. Basado en el artículo de Juan Luis Cano (@Juanlu001) en http://pybonacci.wordpress.com/2012/11/30/juego-de-la-vida-de-conway-con-python-usando-numpy/
# coding: utf-8 | |
"""Juego de la vida de Conway. | |
Author: Chema Cortés <ch3m4@ch3m4.org> | |
""" | |
import numpy as np | |
import matplotlib.pyplot as plt | |
import matplotlib.cm as cm | |
from matplotlib import animation | |
class Board(object): | |
def __init__(self, n, m): | |
self.T = np.zeros((n,m), dtype=int) | |
# Matrices generadoras | |
self.A = np.roll(np.identity(n),1,0) + np.roll(np.identity(n),-1,0) | |
self.B = np.roll(np.identity(m),1,1) + np.roll(np.identity(m),-1,1) | |
self.C = np.identity(m) + self.B | |
def clear(self): | |
self.T = np.zeros(self.T.shape, dtype=int) | |
def fill_random(self): | |
self.T = np.random.randint(2,size=self.T.shape) | |
def pos_pattern(self, patstr, x, y, rot=0, flip=False): | |
pat = np.array([[1 if c=='x' else 0 for c in l] for l in patstr.split()]) | |
if flip: pat = np.fliplr(pat) | |
pat = np.rot90(pat, rot) | |
h,v = pat.shape | |
self.T[x:x+h,y:y+v] = pat | |
def step(self): | |
# Células vivas en el vecindario. | |
# A·T + T·B + A·T·B == (A·T)·(1+B) + T·B == A·T·C + T·B | |
V = np.dot(np.dot(self.A,self.T),self.C) + np.dot(self.T,self.B) | |
# Sobrevive si hay dos vecinos. Se genera una nueva si hay tres. | |
self.T = np.select([V==3,V+self.T==3],[1,1],0) | |
class Anim(animation.TimedAnimation): | |
def __init__(self, board, generations=200, interval=10): | |
fig = plt.figure(figsize=(8, 8)) | |
ax = fig.add_subplot(111) | |
ax.axis('off') | |
self.board = board | |
self.generations = generations | |
self.img = ax.imshow(board.T, interpolation="none", cmap=cm.gray_r) | |
animation.TimedAnimation.__init__(self, fig, interval=interval, blit=True) | |
def _init_draw(self): | |
self.img.set_data(np.zeros(self.board.T.shape)) | |
def _draw_frame(self, framedata): | |
self.board.step() | |
self.img.set_data(self.board.T) | |
def new_frame_seq(self): | |
return iter(xrange(self.generations)) | |
# Some patterns | |
glider=""" | |
-x- | |
--x | |
xxx | |
""" | |
ship=""" | |
x--x- | |
----x | |
x---x | |
-xxxx | |
""" | |
r_pentomino=""" | |
----- | |
--xx- | |
-xx-- | |
--x-- | |
----- | |
""" | |
#Gosper glider gun | |
gun=""" | |
-------------------------------------- | |
-------------------------x------------ | |
-----------------------x-x------------ | |
-------------xx------xx------------xx- | |
------------x---x----xx------------xx- | |
-xx--------x-----x---xx--------------- | |
-xx--------x---x-xx----x-x------------ | |
-----------x-----x-------x------------ | |
------------x---x--------------------- | |
-------------xx----------------------- | |
-------------------------------------- | |
""" | |
pat_minimal=""" | |
---------- | |
-------x-- | |
-----x-xx- | |
-----x-x-- | |
-----x---- | |
---x------ | |
-x-x------ | |
""" | |
one_line=""" | |
----------------------------------------- | |
-xxxxxxxx-xxxxx---xxx------xxxxxxx-xxxxx- | |
----------------------------------------- | |
""" | |
if __name__ == "__main__": | |
tablero = Board(100,100) | |
# tablero.fill_random() | |
tablero.pos_pattern(gun,30,11, 1) | |
tablero.pos_pattern(gun,40,50, 2) | |
anim = Anim(tablero) | |
# anim.save("juego_vida.avi", fps=10) | |
plt.show() |
This comment has been minimized.
This comment has been minimized.
Yups! Corregido. Aunque la cuenta de twitter que pones en Pybonacci pone Muñoz. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This comment has been minimized.
Me ha hecho gracia lo de Muñoz pero soy Juan Luis Cano jeje :P