Raspberry Pi – Game of Life
In meinem letzten Artikel habe ich das Unicorn Hat Erweiterungsboard für den Raspberry Pi vorgestellt. Damit ist es möglich eine 8×8 Pixelmatrix bestehend aus RGB LEDs anzusprechen. Um zu demonstrieren wie einfach die Arbeit mit den LEDs ist habe ich ein eigenes kleines Beispielskript in Python geschrieben, welches Conway’s Game of Life auf diesem Board darstellt und berechnet.
Game of Life
Der Algorithmus zu Conway’s Game of Life ist recht einfach und besteht nur aus einigen Regeln. Er wird auf eine 2-dimensionales Array aus binären Werten angewendet, welches Zellen simuliert die entweder den Status „lebend“ oder „tot“ haben. In vielen Programmierkursen wird dieser Algorithmus gerne als Beispiel gezeigt oder als Hausaufgabe aufgegeben. Die meisten Programmierer sind deshalb mit den Regeln bestens vertraut.
Source Code
Das Skript beginnt mit den Imports. Wir benötigen neben der Unicorn Hat Bibliothek noch die time und random um den Zufallszahlengenerator zu initialisieren und Zufallszahlen zu erzeugen und die numpy Bibliothek, welche ein Objekt zu effizienten Verwaltung und Bearbeitung eines 2-dimensionalen Arrays beinhaltet.
#!/usr/bin/env python import unicornhat as unicorn import time import random import numpy
Im nächsten Schritt setze ich die Helligkeit der LEDs global auf 20%. Das ist mehr als ausreichend, viel höhere Werte schmerzen die Augen. Danach lege ich ein 8 mal 8 großes Array an, welches mit Nullen initialisiert wird. Zuletzt lege ich noch eine Farbe fest in der dann alle LEDs leuchten sollen. In diesem Fall gelb.
unicorn.brightness(0.2) board = numpy.zeros((8,8), dtype=numpy.byte) color = [255, 255, 0]
Die ganze Berechnung des Skripts wird in 3 Funktionen stattfinden. Die erste Funktion ist initialize(). Diese Funktion bekommt als Parameter das 2-dimensionale Array und befüllt dieses mit zufälligen Werten (0 oder 1). Ganz zu beginn der Funktion wird der Zufallszahlengenerator mit dem aktuellen Timestamp initialisiert, damit auch garantiert bei jedem Skriptaufruf ein anderes Muster erzeugt wird.
def initialize(board): #initialize random number generator random.seed(time.time()) #loop board for y in range(8): for x in range(8): #set element randomized rand = random.randint(0,1) board[x][y] = rand
In der Funktion draw() wird der aktuelle Zustand des 2-dimensionalen Array ausgegeben. Dafür liefert die Unicorn Hat Bibliothek eine Funktion set_pixel, in der neben der x- und y-Koordinate der LED auch die 3 RGB Farbwerte (0-255) angegeben werden. In einer if Abfrage wird geprüft ob das Array an dieser Koordinate eine 1 enthält. Falls ja wird das Pixel mit der Farbe gesetzt, andernfalls mit 0, 0, 0 auf schwarz gesetzt. Schwarz heißt in dem Fall auch nicht leuchtend. Nachdem alle Pixel gesetzt wurden wird die komplette LED Matrix mit der Funktion show() angezeigt.
def draw(board): for y in range(8): for x in range(8): #set pixel with color or unset it if board[x][y] == 1: unicorn.set_pixel(x,y,color[0],color[1],color[2]) else: unicorn.set_pixel(x,y,0,0,0) #draw whole unicorn led matrix unicorn.show()
In der dritten und letzten Funktion compute() wird der Game of Life Algorithmus auf das 2-dimensionale Array angewendet und als Rückgabewert das veränderte Array zurückgegeben.
def compute(board): #game of life logic xmax, ymax = board.shape b = board.copy() for x in range(xmax): for y in range(ymax): n = numpy.sum(board[max(x - 1, 0):min(x + 2, xmax), max(y - 1, 0):min(y + 2, ymax)]) - board[x, y] if board[x, y]: if n < 2 or n > 3: b[x, y] = 0 elif n == 3: b[x, y] = 1 return b
Zuletzt fehlt uns nur noch der Aufruf dieser Funktionen. Die Initialisierung wird nur einmal gemacht und ist der erste Schritt. Danach wird in einer Spielschleife reihum zuerst das 2-dimensionale Array auf dem Unicorn Hat Board ausgegeben, danach die neue Zustand des Array errechnet und 1,5 Sekunden lang gewartet. Danach wird das Array wieder ausgegeben usw…
initialize(board) while True: draw(board) board = compute(board) time.sleep(1.5)
Das fertige Skript könnt ihr hier downloaden.
Ausgeführt wird das Beispielskript wie folgt:
sudo python gameoflife.py
Lebendig oder Tot?
Die Berechnung des Game of Life Algorithmus passiert in diesem Fall auf einem lediglich 8×8 großem Array und wird mit einem zufälligen Zustand gestartet. Deshalb ist nicht abzusehen wie lange es eine Ausgabe geben wird. Es kann sein, dass nach wenigen Runden bereits alle Zellen gestorben sind und man nur noch ein leeres Board präsentiert bekommt. Genauso kann es aber auch sein, dass die Berechnung sehr lange funktioniert und möglicherweise sogar konstante Strukturen übrig bleiben die „ewig“ leben. Am besten selber ausprobieren und die Erfahrung machen.
Fazit
Es macht jedes mal wieder Spaß den Game of Life Algorithmus umzusetzen. Die Berechnung ist sehr dynamisch und man hat schnell eine schöne Ausgabe programmiert. Gerade für das Unicorn Hat Board ist der Algorithmus eine nette Sache, mal sehen ob mein Code eventuell mal den Beispielen hinzugefügt werden wird.
Habt ihr andere Ideen für Beispielskripte? Oder Verbesserungen für mein Game of Life Skript?
Eine richtig schöne Laufschrift, die man sich dank Python von einer Site runterziehen kann.
Bsp.: Jedes Mal wenn du eine Seite aufrufst, wird ein kurzer Satz dargestellt, aus einem Pool von Sätzen.
Python schnappt sich den Satz und zeigt diesen in Laufschrift in der Matrix an. Danach holt sich der Raspi wieder einen Satz. Wenn dieser anders ist als der vorherige, dann wird dieser auch ausgegeben..
Und so weiter und so weiter
hat jemand diese Textfunktion für das Unicorn Hat als Python Funktion programmiert ?
meinst du damit, dass man beliebigen Text über die Matrix anzeigen lassen kann?