# Hauptteil

Dieses Wikibook beschäftigt sich mit der softwaretechnischen Implementation von Conways Spiel des Lebens (englisch: "Game of Life") mit der Hilfe von strukturierten Java-Programmen. Zur Modellierung des räumlich diskreten dynamischen Systems wird ein zweidimensionaler zellulärer Automat implementiert.

## Algorithmus für das Spiel des Lebens

In der angewandten Mathematik ist das Spiel des Lebens ein dynamisches System, das eine selbstorganisierte Entwicklung durchläuft. Hierbei entstehen aus einer gegebenen Anfangssituation aufgrund einer wohldefinierten Interaktion einzelner Systemelemente einfache und komplexe geometrische Strukturen. Jede üblicherweise quadratische Zelle auf dem Spielfeld kann entweder das Leben (englisch: "life") oder den Tod (englisch: "dead") repräsentieren, und das gesamte Spielfeld entwickelt sich Schritt für Schritt iterativ weiter. Für jede Zelle auf dem Spielfeld gilt, dass sie im nächsten Schritt nur und genau dann lebendig bleibt oder wird, wenn sie entweder genau zwei oder drei lebendige Zellen in den acht direkt benachbarten Zellen hat.
Das Spielfeld kann am Rand begrenzt sein, oder sich an der jeweils gegenüberliegenden Seite des Spielfelds fortsetzen, was auch als torodiale Struktur bezeichnet wird.
Bei der schrittweisen Entwicklung können statische, mit einer bestimmten Anzahl von Mustern oszillierende oder sich über das Spielfeld bewegende Strukturen entstehen. Es ist möglich, dass auf dem gesamten Spielfeld zu einem bestimmten Zeitpunkt sich keine Zellen mehr über das Spielfeld bewegen, keine Strukturen mehr oszillieren oder sogar alle Zellen statisch sind.
Der Algorithmus für das Spiel aus dem Jahr 1970 geht auf den britischen Mathematiker John Horton Conway (1937 bis 2020) zurück.
→ Siehe auch deutschsprachiger Wikipedia-Artikel Game of Life.
→ Siehe auch englischsprachiger Wikipedia-Artikel Game of Life.
* Beispiele für die Entwicklung von Strukturen im Spiel des Lebens perrow=3 widths=128 heights=128
* Die statische Figur "Honey farm" ("Honigfarm") aus vier statischen Figuren "bee hive" ("Bienenkorb") mit insgesamt 13 mal 13 Zellen.
* Die oszillierende Figur "Clover" in Form eines Kleeblatts mit 15 mal 15 aktiven Zellen aus drei sich wiederholenden Mustern.
* Die von links oben nach rechts unten gleitende Figur "Glider" mit 3 mal 3 aktiven Zellen

## Programmbestandteile

Das hier vorgestellte Java-Programm implementiert ein rechteckiges Spielfeld mit wählbarer Breite und Höhe. Hierzu werden für die Modellierung, die graphische Anzeige und die Initialisierung eines Spielfelds die drei Java-Klassen GameOfLifeModel, GameOfLifeFrame und GameOfLife verwendet, die im Folgenden beschrieben werden.

### GameOfLifeModel

Die Java-Klasse GameOfLifeModel dient der Implementierung eines Modells für die Umsetzung des Spiels des Lebens in einer rechteckigen Fläche.
Die Spielfläche in einem rechteckigen Spielfeld aus $x$ mal $y$ Zellen kann aus zwei verschiedenen Elementen zusammengesetzt werden:
* Tote Zelle (GameOfLifeModel.DEAD)
* Lebende Zelle (GameOfLifeModel.LIFE)
Die entsprechenden öffentlichen Konstanten für diese Aufzählung sind in der Java-Klasse "GameOfLifeModel" definiert. Ferner gibt es die beiden Konstanten ALWAYS_DEAD und TORODIAL, mit denen das Verhalten der Zellen an den Rändern des Spielfelds gesteuert werden kann:
Das Modell verwendet zwei zweidimensionalen Datenfelder (Arrays), um aus einem bestehenden Spielfeld, das in der Instanzvariablen GameOfLifeModel.currentBoard gespeichert ist, das nächstes Spielfeld zu berechnen, das in der Instanzvariable GameOfLifeModel.nextBoard zwischengespeichert wird. Jede Zelle des Spielfelds enthält einen booleschen Wert (Datentyps "boolean"), in dem die beiden oben genannten Werte gespeichert werden können. Mit dem Konstruktor GameOfLifeModel (int x, int y, boolean borderMode) der Klasse werden die Breite x und die Höhe h des rechteckigen Spielfelds sowie das Verhalten bordermode an den Spielfeldrändern festgelegt, und die beiden zweidimensionalen Datenfelder GameOfLifeModel.currentBoard und GameOfLifeModel.nextBoard werden erzeugt:
Für das hier implementierte Modell gelten die oben angegebenen Regeln. Eine Iteration wird mit dem Aufruf der Methode computeNextBoard durchgeführt:
Hierbei wird mit der Methode long countLifeNeighbours (int x, int y) für jede Zelle (x, y) des Spielfelds untersucht, wie viele der benachbarten acht Zellen lebendig sind.
Mit dem folgenden Java-Programm mit der Java-Klasse GameOfLifeModel können Modelle des Spiels des Lebens erzeugt und verwaltet werden:
→ Java-Programm "GameOfLifeModel"

### GameOfLifeFrame

Die Java-Klasse GameOfLifeFrame realisiert als Erweiterung der Java-Standardklasse javax.swing.JFrame (Basisklasse ist java.awt.Component, und der Name des Software-Pakets "awt" steht für "advanced windows toolkit", was ungefähr als "fortgeschrittener Fenster-Werkzeugsatz" übersetzt werden kann) eine iterativ aktualisierte graphische Ausgabe von Inhalten der Klasse GameOfLifeModel:
* java.awt.Component
** java.awt.Container
*** java.awt.Window
**** java.awt.Frame
***** javax.swing.JFrame
****** GameOfLifeFrame
Für die graphische Ausgabe einer Instanz model der Klasse GameOfLifeModel werden Instanzen der Java-Klassen java.awt.image.BufferedImage und java.awt.image.WritableRaster verwendet. Eine Instanz der Klasse GameOfLifeFrame wird mit der überschriebenen parameterlosen Java-Standardmethode init initialisiert und mit der überschriebenen, öffentlichen und typengebundenen Java-Standardmethode paint ausgegeben. Die Methode paint benötigt dafür als Parameter eine Instanz der Java-Klasse java.awt.Graphics.
Zur Synchronisation der graphischen Ausgabe wird eine Instanz der Java-Standardklasse java.awt.event.ActionListener implementiert. Hierbei handelt es sich um ein Java-Interface, das Ereignisse der Klasse java.awt.event.ActionEvent empfängt: Ereignisse zur aktualisierten graphischen Ausgabe werden mit Hilfe einer Instanz der Java-Klasse javax.swing.Timer ausgelöst. Dieser Zeitgeber wird durch den Aufruf seines Konstruktors javax.swing.Timer (50, this) mit einem Verzögerungsparameter (hier 50 Millisekunden) als ActionListener erstellt, und die Instanz der Klasse javax.swing.JFrame wird von diesem Zeitgeber durch den Aufruf seiner Methode addActionListener automatisch intern registriert. Der Verzögerungsparameter wird verwendet, um die Verzögerung jeder Iteration in Millisekunden festlegen zu können.
Der Konstruktor GameOfLifeFrame (int x, int y, boolean mode, long count, boolean saveBoard) zur Initialisierung der graphischen Ausgabe des Spiels ist folgendermaßen gestaltet, um ein Spielfeld (englisch: "board") mit der Breite x und der Höhe y für count Iterationen zu erzeugen:
Die Simulation wird mit dem Aufruf der Methode init gestartet. Bevor innerhalb der Methode init die graphische Ausgabe mit dem Aufruf der Methode paint zum ersten Mal erfolgt, wird der bereits registrierte javax.swing.Timer durch den Aufruf seiner Methode start gestartet:
Sobald der Zeitgeber mit der gebundenen Methode start aus der Klasse javax.swing.Timer im Konstruktor der Klasse GameOfLifeFrame gestartet wurde, wartet dieser jeweils, bevor ein Ereignis der Klasse java.awt.event.ActionEvent an den registrierten java.awt.event.ActionListener auslöst werden kann.
Wenn das Ereignis ausgelöst wurde, wird die Methode actionPerformed (java.awt.event.ActionEvent event) des Objekts mit einem Parameter event der Klasse java.awt.event.ActionEvent aufgerufen, die schließlich wiederum die Java-Standardmethode java.awt.Component.repaint aufruft, die intern dann wiederum die Standard-Methode paint aufruft. Am Ende des Spiels wird der Zeitgeber timer durch den Aufruf der gebundenen Methode timer.stop aus der Klasse javax.swing.Timer angehalten.
Die aus der Basisklasse java.awt.event.ActionListener überschriebene Standardmethode actionPerformed (java.awt.event.ActionEvent event) für die synchronisierte Aktualisierung einer Instanz der Klasse GameOfLifeFrame sieht folgendermaßen aus:
Mit dem Aufruf der Methode java.awt.Toolkit.getDefaultToolkit.sync am Ende der Standardmethode paint (java.awt.Graphics graphics) zur graphischen Darstellung der Instanz graphics wird sichergestellt, dass die graphische Anzeige vollständig aktualisiert ist, bevor durch den Zeitgeber ein neues Ereignis (java.awt.event.ActionEvent) ausgelöst wird:
Mit dem folgenden Java-Programm mit der Java-Klasse GameOfLifeFrame kann die Bildschirmanzeige des Spiels des Lebens realisiert werden:
→ Java-Programm "GameOfLifeFrame"

### Aufruf des Programms

Mit dem Aufruf der folgenden öffentlichen Hauptmethode main (java.lang.String arguments) kann werden 1000 Schritte für ein Spielfeld mit 800 Feldern in der Breite und 600 Feldern in der Höhe berechnet und graphisch dargestellt. Der Aufruf des Konstruktors GameOfLifeFrame (int x, int y, EEEEEEEEEE long count, boolean borderMode) erzeugt eine entsprechende Instanz frame der Klasse GameOfLifeFrame, wobei dieser automatisch den Konstruktor GameOfLifeModel (int x, int y, boolean borderMode) der Java-Klasse GameOfLifeModel aufruft und somit eine Instanz model dieser Klasse erzeugt. Mit dem Unterprogramm init (GameOfLifeModel model) kann die Instanz model von GameOfLifeModel initialisiert werden.
Mit den beiden gebundenen Methoden int getWidth und int getHeight können die Abmessungen des Spielfelds abgerufen werden. Von der Methode boolean model.getCellState (x, y) wird der Zustand der Zelle an der Stelle (x, y) zurückgegeben, und mit dem Aufruf der Methode model.setCellState (int x, int y, boolean status) wird der gewünschte boolesche Zustand status der Zelle an der Stelle (x, y) des Spielfelds gesetzt. Die beiden gültigen Zustände sind in den Konstanten DEAD und LIFE der Klasse GameOfLifeModel definiert.
Durch die Methode double nextProbability wirde eine pseudozufällige Gleitkommazahl zwischen Null und Eins zurückgegeben, mit der bei Bedarf gesteuert werden kann, welche Zellen des Spiels zu Beginn als lebendig gesetzt werden.
In dem Java-Programm mit der Java-Klasse PseudoRandom sind die Unterprogramme (Methoden) enthalten, mit denen in der Klasse GameOfLife die entsprechenden Pseudozufallszahlen erzeugt werden:
→ Siehe → Java-Programm "PseudoRandom"

## Nachwort

Die hier angegebenen strukturierten Programmbeispiele können ohne große Umstände in jede andere strukturierte Programmiersprache übertragen werden. Durch die Modifikation und Ergänzung der angegebenen Algorithmen können beliebig anders gestaltete Anfangssituationen gestaltet werden.
Es wäre erfreulich, wenn dieses Wikibook zu einem besseren und tieferen Verständnis der strukturierten Programmierung und als Einstieg in die Technik der Programmierung von Iterationen mit zellulären Automaten beitragen kann.

## Siehe auch

* Strukturierte Programmierung
* Rekursive Labyrinthe
* Das Apfelmännchen

## Zusammenfassung des Projekts

„Game of Life“ ist nach Einschätzung seiner Autoren zu 100 % fertig
* Zielgruppe: Informatiker, Mathematiker
* Lernziele: Iteration eines zweidimensionalen zellulären Automaten mit einem Java-Programm.
* Buchpatenschaft/Ansprechperson: Benutzer:Bautsch
* Sind Co-Autoren gegenwärtig erwünscht? Ja, sehr gerne. Korrekturen von offensichtlichen Fehlern direkt im Text; Inhaltliches bitte per Diskussion.
* Richtlinien für Co-Autoren: Wikimedia-like.