View on GitHub

GymInf - Programmierung I

Übungen 5

Tutoren

matthias.amberg@unibas.ch

Foren-Austausch

Wir können uns für die Übungen auch mittels des offziellen GymInf Moodle Forum austauschen.

Übungs-Hilfsdateien

Bitte verwenden Sie die Vorlagen im Zipfile zu den Übungen

Musterlösungen

Musterlösungen finde sie wie gewohnt auf der Moodle Seite des Kurses.

Allgemeine Hinweise

Übung 1 - Game Of Life

Das Spiel des Lebens (Game of Life) geht auf den Mathematiker John Conway zurück und funktioniert nach folgenden Prinzipien: http://www.math.com/students/wonders/life/life.html

Die Grundeinheit sind Zellen, die in einer Matrix angeordnet sind. Jede Zelle kann lebendig oder tot sein. Jede Zelle hat acht Nachbarn, wobei Randzellen die Zellen des gegenüberliegenden Randes als Nachbarn haben. Der Zustand der Zellen (lebendig oder tot) ändert sich von Generation zu Generation. Die aktuelle Zellpopulation beeinflusst die darauffolgende Generation nach folgenden Regeln:

  1. Eine tote Zelle mit genau drei lebenden Nachbarn erwacht zum Leben (birth).
  2. Eine lebende Zelle mit zwei oder drei lebenden Nachbarn bleibt am Leben (survival).
  3. Alle anderen lebenden Zellen sterben (overcrowding or loneliness).

Sie finden im Verzeichnis src/main/java/ die Klasse GameOfLife, welche als Feld eine Zellenpopulation als eine size × size Matrix vom Typ boolean speichert. Jedes Element hat entweder den Wert false (tote Zelle, ‘.’) oder true (lebende Zelle, ‘@’). Speichern Sie auch die Grösse size als Feld der Klasse.

Konstruktoren

Implementieren Sie den Konstruktor, welcher ein boolean Array mit einem gegebenen Muster (repräsentiert als zweidimensionales boolean Array) entgegennimmt und die ent- sprechenden Felder setzt. Danach implementieren Sie die statischen Methoden createBlock, createBlinker und createGlider, welche ein neues Game of Life mit folgenden Mustern initialisiert:

Block

....
.@@.
.@@.
....

Blinker

.....
..@..
..@..
..@..
.....

Glider

......
.@.@..
..@@..
..@...
......
......

Implementieren Sie ausserdem eine statische Methode createRandom, welche ein Objekt der Klasse GameOfLife für eine angegebene Feldgrösse erstellt. Der Wert jeder Zelle soll dabei zufällig gesetzt werden. Dabei wird jede Zelle mit der angegebenen Wahrscheinlichkeit als “lebend” initialisiert. Verwenden Sie dazu die Klasse java.util.Random.

Evolution

Implementieren Sie die Methode isActive, die den Wert aus dem Feld abfragt, eine Methode getNumberOfActiveNeighbors, welche die lebenden Nachbarn zählt und eine Methode update, welche das Update ausführt. Dabei soll der Zustand aller Zellen zur “gleichen” Zeit ausgeführt werden. Verwenden Sie dazu eine Kopie der Zellpopulation. Beachten Sie ferner, dass der Zugriff auf eine Zelle jeweils auf der gegenüberliegenden Seite geschieht wenn auf die Nachbarn von Zellen am Rand zugegriffen wird.

Ausgabe

Schreiben Sie nun noch die Methode public String toString(), welche die Population in einem String darstellt. Um Zeilenumbrüche in einem String darzustellen, können Sie die Zeichenfolge “\n” verwenden. Jede Zelle soll dabei durch ein . oder ein @ dargestellt werden.

Testprogramm

Implementieren Sie die Methoden im Testprogramm GameOfLifeCommandLine, welches die Evolutionsschritte vom GameOfLife berechnet und das Ergebnis jeweils auf der Konsole ausgibt.

Übung 2 - Game of Life - AWT

:warning: Falls Sie die vorige Aufgabe nicht lösen konnten, können Sie Klasse MockGameOfLife nutzen, die Sie im Verzeichis src/main/java/ finden.

Sie finden im Verzeichnis src/main/java/ die Java-Klasse GOLWindow zur Visualisierung des Game Of Life. Implementieren Sie die fehlenden Methoden in dieser Klasse, gemäss den angegebenen Spezifikationen in den Kommentaren.

Experimentieren Sie mit verschiedenen Konfigurationen. Für die Konfiguration Blinker (und das MockGameOfLife) sollte ihre Ausgabe im ersten Schritt etwa so wie das folgende Bild aussehen:

Blinker

Wenn Sie grosse, zufällige Welten simulieren, sieht die Ausgabe etwa wie in diesem Bild aus:

Random Game Of Life

Übung 3 - Game of Life - AWT mit Double Buffering

Wenn Sie die vorige Übung gelöst haben, ist ihnen vielleicht aufgefallen, dass bei grossen Welten die Darstellung ins Stocken gerät. Abhilfe schafft hier das Double buffering. Double buffering ist eine Strategie, bei welcher nicht direkt auf den Screen gezeichnet wird, sondern erst ein Bild gezeichnet wird, welches dann in der Paint Methode jeweils direkt dargestellt wird. Die Klasse JFrame (respektive deren Superklasse Component) stellt dafür bereits die Methode createImage zur Verfügung, welches ein Offscreen Image erstellt, in welches gezeichnet werden kann.

Schreiben Sie ihr Programm nun so um, dass es double buffering benutzt. Dazu kopieren Sie ihre Lösungen zur vorigen Aufgabe erst in die Klasse GOLWindowDoubleBuffering und passen diese dann entsprechend an. Erstellen Sie dazu ein Feld offscreenImage sowie ein Feld offscreenGraphics. Das Feld offscreenGraphics ist vom Datentyp java.awt.Graphics. Beim ersten Aufruf der Paint-Methode soll nun mittels createImage das offscreenImage gesetzt werden und mit dem Befehl offscreenImage.getGraphics() das Feld offscreenGraphics. Wenn diese Felder gesetzt sind, zeichnen Sie nun in dieses Bild und nutzen dann die Methode drawImage, um das offscreen gerenderte Bild darzustellen (Achtung: stellen Sie sicher, dass Sie das richtige Graphics-Objekt nutzen. )

:warning: Sie dürfen bei dieser Teilaufgabe auch im Internet recherchieren, um Codebeispiele zu finden.