📚 The CoCalc Library - books, templates and other resources
License: OTHER
""" Code example from Complexity and Computation, a book about1exploring complexity science with Python. Available free from23http://greenteapress.com/complexity45Copyright 2016 Allen Downey6MIT License: http://opensource.org/licenses/MIT7"""8from __future__ import print_function, division910import sys1112import numpy as np13import matplotlib.pyplot as plt1415from matplotlib.patches import RegularPolygon1617from Cell2D import Cell2DViewer1819"""20For animation to work, you might have to install21ffmpeg. On Ubuntu and Linux Mint, the following should work.2223sudo add-apt-repository ppa:mc3man/trusty-media24sudo apt-get update25sudo apt-get install ffmpeg26"""2728class Turmite:29"""Implements Langton's Ant"""3031# map from orientation to (di, dj)32move = {0: (-1, 0), # north331: (0, 1), # east342: (1, 0), # south353: (0, -1)} # west3637def __init__(self, n, m=None):38"""Initializes the attributes.3940n: number of rows41m: number of columns42"""43m = n if m is None else m44self.n = n45self.m = m46self.array = np.zeros((n, m), np.uint8)47self.loc = (n//2, m//2)48self.state = 04950def step(self):51"""Executes one time step."""52try:53cell = self.array[self.loc]54except IndexError:55sys.exit()5657# toggle the current cell58self.array[self.loc] ^= 15960if cell:61# turn left62self.state = (self.state + 3) % 463else:64# turn right65self.state = (self.state + 1) % 46667move = self.move[self.state]68self.loc = self.loc[0] + move[0], self.loc[1] + move[1]697071class TurmiteViewer(Cell2DViewer):72"""Generates an animated view of the grid."""7374cmap = plt.get_cmap('Oranges')7576def __init__(self, viewee):77Cell2DViewer.__init__(self, viewee)78self.viewee = viewee79self.arrow = None8081def draw(self, grid=False):82"""Updates the display with the state of the grid."""83self.draw_array(self.viewee.array)84self.draw_arrow()85if grid:86self.draw_grid()8788def draw_arrow(self):89"""Draws the arrow."""90center, angle = self.arrow_specs()91self.arrow = RegularPolygon(center, 3, color='orange',92radius=0.4, orientation=angle)93ax = plt.gca()94ax.add_patch(self.arrow)9596def arrow_specs(self):97"""Computes the center and orientation of the arrow."""98a = self.viewee.array99n, m = a.shape100i, j = self.viewee.loc101center = j+0.5, n-i-0.5102angle = -np.pi / 2 * self.viewee.state103return center, angle104105def animate_func(self, i):106"""Draws one frame of the animation."""107self.step()108109# update the array110a = self.viewee.array111self.im.set_array(a)112113# update the arrow114center, angle = self.arrow_specs()115self.arrow.xy = center116self.arrow.orientation = angle117118return (self.im, self.arrow)119120121def main(script, *args):122"""Runs Langton's Ant."""123n, m = 70, 80124turmite = Turmite(n, m)125viewer = TurmiteViewer(turmite)126127# run a few steps and draw the end condition128#for i in range(5):129# turmite.step()130#viewer.draw(grid=True)131132# run a short animation133#anim = viewer.animate(frames=5, interval=1000, grid=True)134135anim = viewer.animate(frames=10700, interval=0)136plt.subplots_adjust(left=0.01, right=0.99, bottom=0.01, top=0.99)137plt.show()138139140if __name__ == '__main__':141main(*sys.argv)142143144145146