{ "cells": [ { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "# Conway's life and games\n", "\n", "![](data:image/jpeg;base64,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)" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "## Conway's Life" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "Some of his achievements:\n", " \n", "* Game of Life\n", "* Surreal numbers\n", "* Free Will Theorem" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "## Game of Life\n", "\n", "\n", "" ] }, { "cell_type": "code", "execution_count": 8, "metadata": { "slideshow": { "slide_type": "skip" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Populating the interactive namespace from numpy and matplotlib\n" ] } ], "source": [ "%pylab inline\n", "from pylab import rc\n", "\n", "import numpy as np\n", "import scipy\n", "from IPython.display import HTML\n", "from matplotlib import animation\n", "\n", "rc('animation', html='html5')" ] }, { "cell_type": "code", "execution_count": 17, "metadata": { "slideshow": { "slide_type": "slide" } }, "outputs": [], "source": [ "def life_step(X):\n", " \"\"\"Game of life step using scipy tools\"\"\"\n", " from scipy.signal import convolve2d\n", " nbrs_count = convolve2d(X, np.ones((3, 3)), mode='same', boundary='wrap') - X\n", " return (nbrs_count == 3) | (X & (nbrs_count == 2))" ] }, { "cell_type": "code", "execution_count": 175, "metadata": { "scrolled": false, "slideshow": { "slide_type": "skip" } }, "outputs": [], "source": [ "def life_animation(X, dpi=120, fps=30, frames=10, interval=300, mode='loop', save=None):\n", " \"\"\"Produce a Game of Life Animation\n", " \n", " Parameters\n", " ----------\n", " X : array_like\n", " a two-dimensional numpy array showing the game board\n", " dpi : integer\n", " the number of dots per inch in the resulting animation.\n", " This controls the size of the game board on the screen\n", " frames : integer\n", " The number of frames to compute for the animation\n", " interval : float\n", " The time interval (in milliseconds) between frames\n", " mode : string\n", " The default mode of the animation. Options are ['loop'|'once'|'reflect']\n", " \"\"\"\n", " X = np.asarray(X)\n", " assert X.ndim == 2\n", " X = X.astype(bool)\n", " \n", " X_blank = np.zeros_like(X)\n", "# figsize = (X.shape[1] * 1. / dpi, X.shape[0] * 1. / dpi)\n", "# print(figsize, dpi)\n", "\n", " fig = plt.figure(dpi=dpi);\n", " plt.close()\n", " ax = fig.add_axes([0, 0, 1, 1], xticks=[], yticks=[], frameon=False)\n", " im = ax.imshow(X, cmap=plt.cm.binary, interpolation='nearest')\n", " im.set_clim(-0.05, 1) # Make background gray\n", " orig = X.copy()\n", " # initialization function: plot the background of each frame\n", " def init():\n", " im.set_data(orig)\n", " animate.X = orig\n", " return (im,)\n", "\n", " # animation function. This is called sequentially\n", " def animate(i):\n", " im.set_data(animate.X)\n", " animate.X = life_step(animate.X)\n", " return (im,)\n", "\n", " anim = animation.FuncAnimation(fig, animate, init_func=init,\n", " frames=frames, interval=interval,\n", " blit=True)\n", " \n", " #print anim_to_html(anim)\n", " htmlcode = anim.to_jshtml(default_mode=mode)\n", " if save:\n", " anim.save(save+'.gif', writer='imagemagick', fps=fps)\n", " return HTML(htmlcode)\n", "\n", "\n", "def pattern(*figs, height=50, width=70):\n", " '''Concatenate different patterns into a single board'''\n", " X = np.zeros((height, width)) \n", " for patt, x0, y0 in figs:\n", " X[y0:y0+len(patt), x0:x0+len(patt[0])] = patt\n", " return X" ] }, { "cell_type": "code", "execution_count": 110, "metadata": { "scrolled": false, "slideshow": { "slide_type": "slide" } }, "outputs": [ { "data": { "text/html": [ "\n", "\n", "\n", "\n", "\n", "\n", "