|
# coding: utf-8 |
|
|
|
"""Juego de la vida de Conway. |
|
|
|
Author: Chema Cortés <[email protected]> |
|
|
|
""" |
|
|
|
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() |
Yups! Corregido. Aunque la cuenta de twitter que pones en Pybonacci pone Muñoz.