Dies ist eine alte Version des Dokuments!
Das Programm besteht aus zwei Dateien 1. die Klassendatei GameOfLife.py 2. die Ausführungsdatei
In der ersten sind das Game of life und seine Regeln implementiert und die zweite greift darauf zu und erstellt eine Animation, mit der man interagieren kann.
inhalt der GoL
Die Animationsdatei:
import GameOfLife as gol import numpy as np from matplotlib import pyplot as plt from matplotlib import animation # in dieser Datei, wird die Animation der 'Game of Life' - Schritte ausgeführt # die vorletzte Zeile mit Funcanimation bildet das Grundgeruest, der Rest des Codes ist groesstenteils Vorbereitung # und die Funktionen zum Interagieren # unterschiedliche colourmaps (weil ein buntes Leben, lebenswerter ist) # diese werden zufaellig aufgerufen colormaps = ['Accent', 'Accent_r', 'Blues', 'Blues_r', 'BrBG', 'BrBG_r', 'BuGn', 'BuGn_r', 'BuPu', 'BuPu_r', 'CMRmap', 'CMRmap_r', 'Dark2', 'Dark2_r', 'GnBu', 'GnBu_r', 'Greens', 'Greens_r', 'Greys', 'Greys_r', 'OrRd', 'OrRd_r', 'Oranges', 'Oranges_r', 'PRGn', 'PRGn_r', 'Paired', 'Paired_r', 'Pastel1', 'Pastel1_r', 'Pastel2', 'Pastel2_r', 'PiYG', 'PiYG_r', 'PuBu', 'PuBuGn', 'PuBuGn_r', 'PuBu_r', 'PuOr', 'PuOr_r', 'PuRd', 'PuRd_r', 'Purples', 'Purples_r', 'RdBu', 'RdBu_r', 'RdGy', 'RdGy_r', 'RdPu', 'RdPu_r', 'RdYlBu', 'RdYlBu_r', 'RdYlGn', 'RdYlGn_r', 'Reds', 'Reds_r', 'Set1', 'Set1_r', 'Set2', 'Set2_r', 'Set3', 'Set3_r', 'Spectral', 'Spectral_r', 'Wistia', 'Wistia_r', 'YlGn', 'YlGnBu', 'YlGnBu_r', 'YlGn_r', 'YlOrBr', 'YlOrBr_r', 'YlOrRd', 'YlOrRd_r', 'afmhot', 'afmhot_r', 'autumn', 'autumn_r', 'binary', 'binary_r', 'bone', 'bone_r', 'brg', 'brg_r', 'bwr', 'bwr_r', 'cividis', 'cividis_r', 'cool', 'cool_r', 'coolwarm', 'coolwarm_r', 'copper', 'copper_r', 'cubehelix', 'cubehelix_r', 'flag', 'flag_r', 'gist_earth', 'gist_earth_r', 'gist_gray', 'gist_gray_r', 'gist_heat', 'gist_heat_r', 'gist_ncar', 'gist_ncar_r', 'gist_rainbow', 'gist_rainbow_r', 'gist_stern', 'gist_stern_r', 'gist_yarg', 'gist_yarg_r', 'gnuplot', 'gnuplot2', 'gnuplot2_r', 'gnuplot_r', 'gray', 'gray_r', 'hot', 'hot_r', 'hsv', 'hsv_r', 'inferno', 'inferno_r', 'jet', 'jet_r', 'magma', 'magma_r', 'nipy_spectral', 'nipy_spectral_r', 'ocean', 'ocean_r', 'pink', 'pink_r', 'plasma', 'plasma_r', 'prism', 'prism_r', 'rainbow', 'rainbow_r', 'seismic', 'seismic_r', 'spring', 'spring_r', 'summer', 'summer_r', 'tab10', 'tab10_r', 'tab20', 'tab20_r', 'tab20b', 'tab20b_r', 'tab20c', 'tab20c_r', 'terrain', 'terrain_r', 'twilight', 'twilight_r', 'twilight_shifted', 'twilight_shifted_r', 'viridis', 'viridis_r', 'winter', 'winter_r'] def animate(e): ''' die Funktion, die von Funcanimation ausgefuehrt wird wie gol.Schritt funktioniert ist in der Klassendatei beschrieben ''' gol.Schritt() draw(gol.zustand) return im, gol.Initialisiere() fig = plt.figure() def draw(zustand): ''' lebende Zellen aendern ihre Farbe, je laenger sie leben ''' global cmap #enthaelt Werte ueber die 'Lebensdauer' einer Zelle cmap = cmap * zustand + zustand im.set_array(np.ones(cmap.shape) - np.power(0.5, cmap)) fig.canvas.draw() zustand_neu = None anim_running = True drawing = False #die vier folgenden Funktionen sind zum Interagieren mit dem Geschehen def onPress(event): ''' zum Pausieren mit der Leertaste ''' global anim_running if event.key==' ': if anim_running: anim.event_source.stop() anim_running = False else: anim.event_source.start() anim_running = True def onClick(event): ''' mit dem Cursor kann man den Wert einer Zelle per Klick aendern von lebend zu tot, sowie andersherum ''' global cmap, zustand_neu, drawing if event.button == 1 and event.xdata != None and event.ydata != None: drawing = True anim.event_source.stop() zustand_neu = np.copy(gol.zustand) pos_x = int(np.round(event.xdata)) pos_y = int(np.round(event.ydata)) zustand_neu[pos_y, pos_x] = 1 - gol.zustand[pos_y, pos_x] cmap = np.zeros(zustand_neu.shape) draw(zustand_neu) def onMove(event): ''' mit dem Cursor kann man den Wert mehrerer Zellen per Klick aendern, indem man die Maustaste gedrueckt haelt die Animation wird hierfuer pausiert''' global zustand_neu, cmap if event.button == 1 and drawing and event.xdata != None and event.ydata != None: pos_x = int(np.round(event.xdata)) pos_y = int(np.round(event.ydata)) zustand_neu[pos_y, pos_x] = 1 - gol.zustand[pos_y, pos_x] cmap = np.zeros(zustand_neu.shape) draw(zustand_neu) def onClickEnd(event): ''' beim loslassen der Maustaste werden die geänderten Werte an die Animation gegeben und diese wird fortgesetzt ''' global zustand_neu, cmap, drawing if event.button == 1 and drawing: gol.zustand = zustand_neu cmap = np.zeros(zustand_neu.shape) draw(zustand_neu) drawing = False if anim_running: anim.event_source.start() plt.axis('off') #so wird bei jedem ausfuehren eine zufaellige colormap gewaehlt um ein angenehmeres, vielseitiges Langzeiterlebnis zu kreieren im = plt.imshow(gol.zustand, animated=True, cmap=plt.get_cmap(colormaps[int(np.random.random()*len(colormaps))])) cmap = np.zeros(gol.zustand.shape) draw(gol.zustand) #Verbinden, der interaktionsevents mit dem figure, in dem die animation laeuft fig.canvas.mpl_connect('key_press_event', onPress) fig.canvas.mpl_connect('button_press_event', onClick) fig.canvas.mpl_connect('button_release_event', onClickEnd) fig.canvas.mpl_connect('motion_notify_event', onMove) #die tatsaechliche Ausfuehrung: anim = animation.FuncAnimation(fig, animate, interval=200) plt.show()