Update of exercises

master
Thomas Smits 2023-05-23 09:08:43 +02:00
parent d4c8c8df35
commit ea1ca587f6
74 changed files with 2238 additions and 0 deletions

View File

@ -0,0 +1,31 @@
# Einen generischen Typ schreiben
## Lernziel
Einen vorhandenen Typ so umgestalten, dass er als generischer Typ verwendet werden kann.
## Aufgabe
Gehen Sie in das Paket [pr2.generics.einfach](../sources/src/main/java/pr2/generics/einfach/).
Sie finden mit `Liste` eine sehr simple Implementierung einer einfach verketteten Liste vor. Zusätzlich gib es auch noch Tests, die die Liste testen.
Führen Sie die Tests aus und überzeugen Sie sich, dass die Liste korrekt funktioniert.
Schreiben Sie die Klasse `Liste` so um, dass sie zu einem generischen Typ wird. Dies bedeutet insbesondere, dass die Methoden `get` und `add` nicht mehr mit `Object` arbeiten, sondern typsicher werden. Sie dürfen in Ihrer Lösung __keine Casts__ verwenden, d.h. Sie müssen sich auch mit der Klasse `ListNode` beschäftigen und hier Änderungen vornehmen.
Führen Sie die Tests erneut aus, um sicherzugehen, dass Sie bei Ihren Änderungen nichts kaputt gemacht haben.
## Abgabe (optional)
__Sie müssen keine Lösung für diese Aufgabe einreichen.__
Sie können Ihre Lösung aber auf die Konformität mit den Programmierstandards testen. Hierzu gehen Sie wie folgt vor:
1. Öffnen Sie eine Kommandozeile (Terminal).
2. Gehen Sie in Ihr Working Directory.
3. Wechseln Sie mit `cd` in das Verzeichnis `sources`.
4. Bauen Sie das Projekt mit dem Kommando `mvn`.

View File

@ -0,0 +1,27 @@
# Generische Klasse Pair schreiben
## Lernziel
Von einem generischen Typ erben.
## Aufgabe
Gehen Sie in das Paket [pr2.generics.pair](../sources/src/main/java/pr2/generics/pair/).
Schreiben Sie eine generische Klasse `Pair`, die zwei Objekte unterschiedlichen Typs verwalten kann. Die Instanzen von `Pair` sollen unveränderlich (**immutable**) sein.
Testen Sie Ihre Implementierung mit der vorhandenen `Main`-Klasse.
## Abgabe (optional)
__Sie müssen keine Lösung für diese Aufgabe einreichen.__
Sie können Ihre Lösung aber auf die Konformität mit den Programmierstandards testen. Hierzu gehen Sie wie folgt vor:
1. Öffnen Sie eine Kommandozeile (Terminal).
2. Gehen Sie in Ihr Working Directory.
3. Wechseln Sie mit `cd` in das Verzeichnis `sources`.
4. Bauen Sie das Projekt mit dem Kommando `mvn`.

View File

@ -0,0 +1,27 @@
# Generische Klasse Pair erweitern: NumberPair
## Lernziel
Von einem generischen Typ erben.
## Aufgabe
Gehen Sie in das Paket [pr2.generics.number_pair](../sources/src/main/java/pr2/generics/number_pair/).
Schreiben Sie eine generische Klasse `NumberPair`, die von der Klasse `Pair` aus der vorhergehenden Aufgabe abgeleitet ist und erzwingt, dass beide verwaltete Objekte von `Number` oder einer Subklasse von `Number` (`Double`, `Integer`, `Long` etc.) sind.
Testen Sie Ihre Implementierung mit der vorhandenen `Main`-Klasse.
## Abgabe (optional)
__Sie müssen keine Lösung für diese Aufgabe einreichen.__
Sie können Ihre Lösung aber auf die Konformität mit den Programmierstandards testen. Hierzu gehen Sie wie folgt vor:
1. Öffnen Sie eine Kommandozeile (Terminal).
2. Gehen Sie in Ihr Working Directory.
3. Wechseln Sie mit `cd` in das Verzeichnis `sources`.
4. Bauen Sie das Projekt mit dem Kommando `mvn`.

View File

@ -0,0 +1,27 @@
# Generische Klasse Pair erweitern: SamePair
## Lernziel
Von einem generischen Typ erben.
## Aufgabe
Gehen Sie in das Paket [pr2.generics.same_pair](../sources/src/main/java/pr2/generics/same_pair/).
Schreiben Sie eine generische Klasse `SamePair`, die von der Klasse `Pair` aus der vorhergehenden Aufgabe abgeleitet ist und erzwingt, dass beide verwaltete Objekte vom selben Typ sind.
Testen Sie Ihre Implementierung mit der vorhandenen `Main`-Klasse.
## Abgabe (optional)
__Sie müssen keine Lösung für diese Aufgabe einreichen.__
Sie können Ihre Lösung aber auf die Konformität mit den Programmierstandards testen. Hierzu gehen Sie wie folgt vor:
1. Öffnen Sie eine Kommandozeile (Terminal).
2. Gehen Sie in Ihr Working Directory.
3. Wechseln Sie mit `cd` in das Verzeichnis `sources`.
4. Bauen Sie das Projekt mit dem Kommando `mvn`.

View File

@ -0,0 +1,27 @@
# PairList
## Lernziel
Sammlungen von Objekten eines generischen Typs erstellen.
## Aufgabe
Gehen Sie in das Paket [pr2.generics.pairlist](../sources/src/main/java/pr2/generics/pairlist/).
Schreiben Sie eine generische Klasse `PairList`, die eine beliebige Anzahl von `Pair`-Objekten verwalten kann. Die Anzahl der maximal gespeicherten Objekte wird beim Erzeugen mitgegeben. Die Klasse erlaubt das Hinzufügen (`add`) und das Auslesen von Objekten anhand des Indexes (`get`).
Testen Sie Ihre Implementierung mit der vorhandenen `Main`-Klasse.
## Abgabe (optional)
__Sie müssen keine Lösung für diese Aufgabe einreichen.__
Sie können Ihre Lösung aber auf die Konformität mit den Programmierstandards testen. Hierzu gehen Sie wie folgt vor:
1. Öffnen Sie eine Kommandozeile (Terminal).
2. Gehen Sie in Ihr Working Directory.
3. Wechseln Sie mit `cd` in das Verzeichnis `sources`.
4. Bauen Sie das Projekt mit dem Kommando `mvn`.

View File

@ -0,0 +1,25 @@
# Wildcard benutzen
## Lernziel
Wildcards einsetzen.
## Aufgabe
Gehen Sie in das Paket [pr2.generics.printer](../sources/src/main/java/pr2/generics/printer/).
Schreiben Sie eine Klasse `CollectionPrinter` mit einer statischen Methode `print`, der man eine beliebige (generische) Collection übergeben kann und die dann deren Inhalt ausdruckt. Eine _Collection_ ist eine Klasse, die beliebig viele Objekte verwalten kann und über die man mit der _for each_-Schleife iterieren kann.
## Abgabe (optional)
__Sie müssen keine Lösung für diese Aufgabe einreichen.__
Sie können Ihre Lösung aber auf die Konformität mit den Programmierstandards testen. Hierzu gehen Sie wie folgt vor:
1. Öffnen Sie eine Kommandozeile (Terminal).
2. Gehen Sie in Ihr Working Directory.
3. Wechseln Sie mit `cd` in das Verzeichnis `sources`.
4. Bauen Sie das Projekt mit dem Kommando `mvn`.

View File

@ -0,0 +1,29 @@
# Generische Queue
## Lernziel
Einen komplexeren generischen Typ entwickeln.
## Aufgabe
Gehen Sie in das Paket [pr2.generics.queue](../sources/src/main/java/pr2/generics/queue/).
Schreiben Sie eine generische Klasse `Queue`, die eine einfache Warteschlange (Queue) realisiert. Über die Methode `offer` können Objekte hinzugefügt werden, über `poll` wieder ausgelesen. Über Probleme des Over- und Underflows brauchen Sie sich hier keine Gedanken zu machen.
Erweitern Sie die Klasse `Queue` um eine Methode `addAll`, der man eine andere `Queue` übergibt und die dann alle Elemente der übergebenen Queue in die aktuelle übernimmt.
Erweitern Sie die Klasse `Queue` aus der vorhergehenden Aufgabe um eine Methode `copyInto`, der man eine andere `Queue` übergibt und die dann alle Elemente der aktuellen Queue in die übergebenen kopiert.
## Abgabe (optional)
__Sie müssen keine Lösung für diese Aufgabe einreichen.__
Sie können Ihre Lösung aber auf die Konformität mit den Programmierstandards testen. Hierzu gehen Sie wie folgt vor:
1. Öffnen Sie eine Kommandozeile (Terminal).
2. Gehen Sie in Ihr Working Directory.
3. Wechseln Sie mit `cd` in das Verzeichnis `sources`.
4. Bauen Sie das Projekt mit dem Kommando `mvn`.

View File

@ -0,0 +1,34 @@
# `super` und `extends` einsetzen
## Lernziel
Methoden unter Verwendung von `super` und `extends` gestalten, sodass sie flexibel auch mit Sub- bzw. Supertypen umgehen können.
## Aufgabe
Gehen Sie in das Paket [pr2.generics.super_extends](../sources/src/main/java/pr2/generics/super_extends/).
In dieser Aufgabe sollen Sie die Klasse `Liste` erweitern.
Fügen Sie `Liste` zwei Methoden hinzu:
* `fillFrom`: befüllt die Liste mit den Daten aus einer anderen (übergebene) Liste.
* `copyInto`: kopiert die Daten der Liste in eine andere (übergebene) Liste.
Verwenden Sie für Ihre Lösung `super` und `extends` zusammen mit Wildcards (`?`).
Kommentieren Sie die Testmethode in den vorhandenen Tests ein und führen Sie diese danach aus. Versichern Sie sich, dass Ihre Implementierung korrekt funktioniert, bevor Sie die Lösung abgeben.
## Abgabe (optional)
__Sie müssen keine Lösung für diese Aufgabe einreichen.__
Sie können Ihre Lösung aber auf die Konformität mit den Programmierstandards testen. Hierzu gehen Sie wie folgt vor:
1. Öffnen Sie eine Kommandozeile (Terminal).
2. Gehen Sie in Ihr Working Directory.
3. Wechseln Sie mit `cd` in das Verzeichnis `sources`.
4. Bauen Sie das Projekt mit dem Kommando `mvn`.

View File

@ -0,0 +1,31 @@
# Generischen Typ verwenden
## Lernziel
Einen vorgegebenen generischen Typ einsetzen, um typsicher eine Menge von Objekten zu verwalten.
## Aufgabe
Gehen Sie in das Paket [pr2.generics.verwenden](../sources/src/main/java/pr2/generics/verwenden/).
In dieser Aufgabe werden Sie ein einfaches Spiel implementieren, mit bei dem man einen Stapel Münzen möglichst schnell abräumen muss. Man nimmt eine Münze, indem man auf sie klickt. Jede Münze gibt dieselbe Anzahl von Punkten. Es geht also eher um das schnelle Klicken.
Die Münzen liegen als Stapel (_Stack_) vor, d.h. man kann immer nur die oberste Münze herunternehmen. Um dies in dem Spiel zu realisieren, sollen Sie den vorgefertigten, generischen Datentyp `Stack` verwenden, den Sie im Paket `java.util` finden.
Bei dieser Aufgabe sollen Sie _nicht_ die Klasse `GameBoard` generisch machen, sondern innerhalb der Klasse den `Stack` als generischen Typ verwenden.
Öffnen Sie die Klasse `GameBoard` und orientieren Sie sich bei Ihren Änderungen an den `TODO`-Kommentaren.
## Abgabe (optional)
__Sie müssen keine Lösung für diese Aufgabe einreichen.__
Sie können Ihre Lösung aber auf die Konformität mit den Programmierstandards testen. Hierzu gehen Sie wie folgt vor:
1. Öffnen Sie eine Kommandozeile (Terminal).
2. Gehen Sie in Ihr Working Directory.
3. Wechseln Sie mit `cd` in das Verzeichnis `sources`.
4. Bauen Sie das Projekt mit dem Kommando `mvn`.

View File

@ -0,0 +1,48 @@
# Generische Typen zusammen mit Wildcards einsetzen
## Lernziel
Gebundene und ungebundene Wildcards einsetzen.
## Aufgabe
Gehen Sie in das Paket [pr2.generics.wildcards](../sources/src/main/java/pr2/generics/wildcards/).
In dieser Aufgabe finden Sie bereits eine Implementierung einer generischen, auf Arrays basierenden Liste namens `SimpleList` vor. An dieser müssen Sie nichts verändern, sondern verwenden die Klasse wie sie ist.
Schreiben Sie nun eine _nicht generische_ Klasse `ListHelper`, die zwei statische Methoden enthält:
* `printList`: Diese Methode bekommt eine beliebige `SimpleList` übergeben und druckt deren Inhalt einfach auf der Konsole aus. Deswegen hat die Methode auch den Rückgabetyp `void`.
* `sumList`: Diese Methode nimmt als Parameter `SimpleList`-Objekte, die irgendeine Form von Zahlen enthalten (`Number` oder Subklassen davon) und berechnet deren Summe. Das Ergebnis wird als `double`-Wert zurückgegeben.
Verwenden Sie für die Methoden gebundene bzw. ungebundene Wildcards.
Kommentieren Sie die entsprechenden Zeilen in der Klasse `Main` aus und sehen überprüfen Sie, ob Ihre Implementierungen auch wie gewünscht funktionieren. Die Ausgabe sollte sein:
```console
Dies
ist
ein
Test
.
1
2
3
4
5
15.0
```
## Abgabe (optional)
__Sie müssen keine Lösung für diese Aufgabe einreichen.__
Sie können Ihre Lösung aber auf die Konformität mit den Programmierstandards testen. Hierzu gehen Sie wie folgt vor:
1. Öffnen Sie eine Kommandozeile (Terminal).
2. Gehen Sie in Ihr Working Directory.
3. Wechseln Sie mit `cd` in das Verzeichnis `sources`.
4. Bauen Sie das Projekt mit dem Kommando `mvn`.

View File

@ -0,0 +1,33 @@
# Anonyme Klasse schreiben
## Lernziel
Eine anonyme Klasse verwenden, um einen Event-Handler zu implementieren. Den Zugriff der anonymen Klasse auf Attribute der umgebenden Klasse und finale Parameter der Methode nutzen.
## Aufgabe
In dieser Aufgabe sollen Sie den Event-Handler für das Zerstören des Aliens als anonyme Klasse im Konstruktor von `GameBoard` realisieren. D.h. nicht mehr das Alien selbst reagiert auf das Klicken, sondern das `GameBoard` bekommt alle Klicks und überprüft, ob sich die Maus über dem Alien befindet.
Fügen Sie dem Konstruktor von `GameBoard` eine anonyme Klasse hinzu, die von `MouseAdapter` erbt. Überschreiben Sie in dieser Klasse die Methode `mousePressed` aus `MouseAdapter`.
In der `mousePressed`-Methode holen Sie die X- und Y-Koordinate aus dem `MouseEvent` und überprüfen Sie mit der Methode `intersects` von `Alien`, ob sich die Maus auch wirklich über dem Alien befindet. Wenn ja, rufen Sie die `explode`-Methode des Aliens auf.
Wenn sich der Mauszeiger nicht innerhalb des Aliens befindet, verschieben Sie das Alien (mit der Methode `setPosition`) an die Position des Mauszeigers.
Übergeben Sie die Instanz der anonymen Klasse der `addMouseListener`-Methode von `GameBoard`.
Lassen Sie das Programm laufen und überprüfen Sie, ob es das erwartete Verhalten zeigt.
## Abgabe (optional)
__Sie müssen keine Lösung für diese Aufgabe einreichen.__
Sie können Ihre Lösung aber auf die Konformität mit den Programmierstandards testen. Hierzu gehen Sie wie folgt vor:
1. Öffnen Sie eine Kommandozeile (Terminal).
2. Gehen Sie in Ihr Working Directory.
3. Wechseln Sie mit `cd` in das Verzeichnis `sources`.
4. Bauen Sie das Projekt mit dem Kommando `mvn`.

View File

@ -0,0 +1,25 @@
# Eigene compare-Methode schreiben
## Lernziel
Objekte vergleichen.
## Aufgabe
Gehen Sie in das Paket [pr2.lambda.array_sorter](../sources/src/main/java/pr2/lambda/array_sorter/).
Schreiben Sie ein Java-Programm `ReverseSort`, das ein Array mit `Date`-Objekten erzeugt und dieses dann mithilfe der `Arrays.sort`-Methode in umgekehrter Reihenfolge sortiert. Um die umgekehrte Sortierung zu erhalten, erzeugen Sie bitte direkt im Aufruf der `sort`-Methode einen entsprechenden `Comparator` als anonyme innere Klasse.
## Abgabe (optional)
__Sie müssen keine Lösung für diese Aufgabe einreichen.__
Sie können Ihre Lösung aber auf die Konformität mit den Programmierstandards testen. Hierzu gehen Sie wie folgt vor:
1. Öffnen Sie eine Kommandozeile (Terminal).
2. Gehen Sie in Ihr Working Directory.
3. Wechseln Sie mit `cd` in das Verzeichnis `sources`.
4. Bauen Sie das Projekt mit dem Kommando `mvn`.

View File

@ -0,0 +1,29 @@
# Innere Klasse Beobachter
## Lernziel
Zugriff von inneren Klassen auf die umgebende Klasse.
## Aufgabe
Gehen Sie in das Paket: [pr2.lambda.observer](../sources/src/main/java/pr2/lambda/observer/).
Dort finden Sie das Interface `Beobachter`.
Schreiben Sie eine Klasse `Datenhalter`, die eine einziges, privates Attribut vom Typ `int` enthält. Setzen Sie das Attribut im Konstruktor, erzeugen Sie aber keinen Getter.
Implementieren Sie das Interface `Beobachter` als nicht-statische, private innere Klasse in `Datenhalter` und erlauben Sie über den Beobachter Zugriff auf das Attribut, indem Sie ein entsprechendes Objekt vom Typ `Beobachter` zurückgeben. Testen Sie Ihre Implementierung mit einem JUnit-Test.
## Abgabe (optional)
__Sie müssen keine Lösung für diese Aufgabe einreichen.__
Sie können Ihre Lösung aber auf die Konformität mit den Programmierstandards testen. Hierzu gehen Sie wie folgt vor:
1. Öffnen Sie eine Kommandozeile (Terminal).
2. Gehen Sie in Ihr Working Directory.
3. Wechseln Sie mit `cd` in das Verzeichnis `sources`.
4. Bauen Sie das Projekt mit dem Kommando `mvn`.

View File

@ -0,0 +1,29 @@
# Callback mit anonymer Klasse realisieren
## Lernziel
Eine gegebene Funktion durch einen Callback parametrieren. Der Callback wird als anonyme innere Klasse realisiert.
## Aufgabe
Gehen Sie in das Paket [pr2.lambda.callback](../sources/src/main/java/pr2/lambda/callback/).
In dieser Aufgabe wird ein sehr gängiges Muster benutzt, dass auch bei großen Suchmaschinen zum Einsatz kommt. Über eine Filter-Funktion werden aus einer Menge von Daten diejenigen ausgewählt, die gewünscht sind. Die Auswahlfunktion wird von außen vorgegeben, sodass beliebige Filteroperationen möglich sind, auch solche, die beim Schreiben des Rahmenwerkes noch nicht bekannt waren.
Sehen Sie sich das Interface `Prediacte` und die Klasse `NumberSelector` an und versuchen Sie die Funktionsweise der beiden zu verstehen. Betrachten Sie nun die Klasse `Main`, die versucht zuerst die geraden und dann die ungeraden Zahlen auszuwählen und auszugeben. Der hierfür nötige Code ist zwar schon weitgehend vorhanden, aber in der `main`-Methode müssen Sie noch zwei passende Filterfunktionen als **anonyme innere Klassen** realisieren.
Nachdem Sie die beiden Filter geschrieben haben, lassen Sie das Programm laufen und überprüfen Sie, ob wirklich die richtigen Zahlen ausgewählt werden.
## Abgabe (optional)
__Sie müssen keine Lösung für diese Aufgabe einreichen.__
Sie können Ihre Lösung aber auf die Konformität mit den Programmierstandards testen. Hierzu gehen Sie wie folgt vor:
1. Öffnen Sie eine Kommandozeile (Terminal).
2. Gehen Sie in Ihr Working Directory.
3. Wechseln Sie mit `cd` in das Verzeichnis `sources`.
4. Bauen Sie das Projekt mit dem Kommando `mvn`.

View File

@ -0,0 +1,28 @@
# Comparator als Lambda
## Lernziel
Lambdas verwenden.
## Aufgabe
Gehen Sie in das Paket
[pr2.lambda.comparator](../sources/src/main/java/pr2/lambda/comparator/).
Als Teil der Java-Klassenbibliothek findet sich das Interface `Comparator`, mit dem beim Sortieren eine Sortierreihenfolge vorgeben werden kann. Da es sich um ein funktionales Interface handelt, kann man es auch mit einem Lambda-Ausdruck implementieren. Schauen Sie sich den Aufbau des Interfaces in der JavaDoc an.
Sortieren Sie ein Array von Zahlen (repräsentiert als `Integer`, nicht als `int`) in _absteigender_ Reihenfolge mithilfe der Methode `sort` der Klasse `Arrays` und geben Sie ihr einen entsprechenden `Comparator` als Lambda-Ausdruck mit.
## Abgabe (optional)
__Sie müssen keine Lösung für diese Aufgabe einreichen.__
Sie können Ihre Lösung aber auf die Konformität mit den Programmierstandards testen. Hierzu gehen Sie wie folgt vor:
1. Öffnen Sie eine Kommandozeile (Terminal).
2. Gehen Sie in Ihr Working Directory.
3. Wechseln Sie mit `cd` in das Verzeichnis `sources`.
4. Bauen Sie das Projekt mit dem Kommando `mvn`.

View File

@ -0,0 +1,31 @@
# Callback mit Lambda realisieren
## Lernziel
Eine gegebene Funktion durch einen Callback parametrieren. Der Callback wird als Lambda realisiert.
## Aufgabe
Gehen Sie in das Paket [pr2.lambda.lambdas](../sources/src/main/java/pr2/lambda/lambdas/).
In dieser Aufgabe wird ein sehr gängiges Muster benutzt, dass auch bei großen Suchmaschinen zum Einsatz kommt. Über eine Filter-Funktion werden aus einer Menge von Daten diejenigen ausgewählt, die gewünscht sind. Die Auswahlfunktion wird von außen vorgegeben, sodass beliebige Filteroperationen möglich sind, auch solche, die beim Schreiben des Rahmenwerkes noch nicht bekannt waren.
Sehen Sie sich das Interface `Predicate` und die Klasse `NumberSelector` an und versuchen Sie die Funktionsweise der beiden zu verstehen. Betrachten Sie nun die Klasse `Main`, die versucht zuerst die geraden und dann die ungeraden Zahlen auszuwählen und auszugeben. Der hierfür nötige Code ist zwar schon weitgehend vorhanden, aber in der `main`-Methode müssen Sie noch zwei passende Filterfunktionen als **Lambda** realisieren.
Nachdem Sie die beiden Filter geschrieben haben, lassen Sie das Programm laufen und überprüfen Sie, ob wirklich die richtigen Zahlen ausgewählt werden.
Vergleichen Sie die Lösung mit Lambdas mit der aus der vorhergehenden Aufgabe, die auf anonymen inneren Klassen basiert hat.
## Abgabe (optional)
__Sie müssen keine Lösung für diese Aufgabe einreichen.__
Sie können Ihre Lösung aber auf die Konformität mit den Programmierstandards testen. Hierzu gehen Sie wie folgt vor:
1. Öffnen Sie eine Kommandozeile (Terminal).
2. Gehen Sie in Ihr Working Directory.
3. Wechseln Sie mit `cd` in das Verzeichnis `sources`.
4. Bauen Sie das Projekt mit dem Kommando `mvn`.

View File

@ -0,0 +1,33 @@
# Lokale Klasse schreiben
## Lernziel
Eine lokale Klasse verwenden, um einen Event-Handler zu implementieren. Den Zugriff der lokalen Klasse auf Attribute der umgebenden Klasse und finale Parameter der Methode nutzen.
## Aufgabe
Gehen Sie in das Paket [pr2.lambda.local](../sources/src/main/java/pr2/lambda/local/).
In dieser Aufgabe sollen Sie den Event-Handler für das Zerstören des Aliens als lokale Klasse im Konstruktor von `GameBoard` realisieren. D.h. nicht mehr das Alien selbst reagiert auf das Klicken, sondern das `GameBoard` bekommt alle Klicks und überprüft, ob sich die Maus über dem Alien befindet.
Fügen Sie dem Konstruktor von `GameBoard` eine lokale Klasse `AlienExploder` hinzu, die von `MouseAdapter` erbt. Überschreiben Sie in dieser Klasse die Methode `mousePressed` aus `MouseAdapter`.
In der `mousePressed`-Methode holen Sie die X- und Y-Koordinate aus dem `MouseEvent` und überprüfen Sie mit der Methode `intersects` von `Alien`, ob sich die Maus auch wirklich über dem Alien befindet. Wenn ja, rufen Sie die `explode`-Methode des Aliens auf.
Erzeugen Sie nach der Deklaration der Klasse `AlienExploder` eine Instanz von dieser und übergeben Sie das Objekt der `addMouseListener`-Methode von `GameBoard`.
Lassen Sie das Programm laufen und überprüfen Sie, ob es das erwartete Verhalten zeigt.
## Abgabe (optional)
__Sie müssen keine Lösung für diese Aufgabe einreichen.__
Sie können Ihre Lösung aber auf die Konformität mit den Programmierstandards testen. Hierzu gehen Sie wie folgt vor:
1. Öffnen Sie eine Kommandozeile (Terminal).
2. Gehen Sie in Ihr Working Directory.
3. Wechseln Sie mit `cd` in das Verzeichnis `sources`.
4. Bauen Sie das Projekt mit dem Kommando `mvn`.

View File

@ -0,0 +1,27 @@
# MatrixSuche
## Lernziel
Statische innere Klassen einsetzen.
## Aufgabe
Gehen Sie in das Paket [pr2.lambda.matrixsuche](../sources/src/main/java/pr2/lambda/matrixsuche/).
Schreiben Sie eine Klasse `MatrixSuche`, die eine statische Methode `findEntry` anbietet. Die Methode soll in einem zweidimensionalen `int`-Array nach einem gegebenen Eintrag suchen und die Position des gefundenen Eintrags in der Matrix zurückgeben. Um die Position zurückzugeben, verwenden Sie bitte eine statische innere Klasse namens `Position`, die die x- und y-Postion enthält.
Überschreiben Sie die `toString`-Methode in `Position` und testen Sie, ob Ihre Implementierung richtig funktioniert.
## Abgabe (optional)
__Sie müssen keine Lösung für diese Aufgabe einreichen.__
Sie können Ihre Lösung aber auf die Konformität mit den Programmierstandards testen. Hierzu gehen Sie wie folgt vor:
1. Öffnen Sie eine Kommandozeile (Terminal).
2. Gehen Sie in Ihr Working Directory.
3. Wechseln Sie mit `cd` in das Verzeichnis `sources`.
4. Bauen Sie das Projekt mit dem Kommando `mvn`.

View File

@ -0,0 +1,33 @@
# StringTransmogrifier
## Lernziel
Funktionale Interfaces entwerfen und verwenden.
## Aufgabe
Gehen Sie in das Paket [pr2.lambda.mogrifier_1](../sources/src/main/java/pr2/lambda/mogrifier_1/).
Schreiben Sie ein funktionales Interface namens `StringFunction`. Die Methode des Interfaces nimmt eine String und gibt einen String zurück.
Schreiben Sie eine Klasse `StringTransmogrifier`, die eine statische Methode `transmogrify` hat, der man ein String-Array und eine `StringFunction` übergibt. Die Methode wendet die Funktion auf jedes Element des Arrays an und gibt ein neues Array mit dem Ergebnis zurück.
Schreiben Sie eine Klasse `StringTransmogrifierTest`, die ein String-Array erzeugt und dann mithilfe der Klasse `StringTransmogrifier` die Elemente verändert. Nehmen Sie folgende Änderungen am Array vor, indem Sie entsprechende Lambda-Ausdrücke oder Methodenreferenzen übergeben:
* Umwandeln aller Buchstaben in Kleinbuchstaben.
* Umwandeln aller Buchstaben in Großbuchstaben.
* Ersetzen jedes Buchstaben durch den im Alphabet folgenden.
## Abgabe (optional)
__Sie müssen keine Lösung für diese Aufgabe einreichen.__
Sie können Ihre Lösung aber auf die Konformität mit den Programmierstandards testen. Hierzu gehen Sie wie folgt vor:
1. Öffnen Sie eine Kommandozeile (Terminal).
2. Gehen Sie in Ihr Working Directory.
3. Wechseln Sie mit `cd` in das Verzeichnis `sources`.
4. Bauen Sie das Projekt mit dem Kommando `mvn`.

View File

@ -0,0 +1,27 @@
# StringTransmogrifier erweitern
## Lernziel
Funktionale Interfaces entwerfen und verwenden.
## Aufgabe
Gehen Sie in das Paket [pr2.lambda.mogrifier_2](../sources/src/main/java/pr2/lambda/mogrifier_2/).
Ausgehend von der vorhergehenden Aufgabe, erweitern Sie das Interface `StringFunction` um eine _statische Methode_ namens `caesar`, mit der man sich eine `StringFunction` erzeugen lassen kann, die die Buchstaben des Strings um einen frei wählbaren Wert verschiebt.
Teste Sie Ihre Implementierung wieder mit `StringTransmogrifierTest`.
## Abgabe (optional)
__Sie müssen keine Lösung für diese Aufgabe einreichen.__
Sie können Ihre Lösung aber auf die Konformität mit den Programmierstandards testen. Hierzu gehen Sie wie folgt vor:
1. Öffnen Sie eine Kommandozeile (Terminal).
2. Gehen Sie in Ihr Working Directory.
3. Wechseln Sie mit `cd` in das Verzeichnis `sources`.
4. Bauen Sie das Projekt mit dem Kommando `mvn`.

View File

@ -0,0 +1,27 @@
# Nonstatic Member Class
## Lernziel
Eine nichtstatische Elementklasse verwenden.
## Aufgabe
Gehen Sie in das Paket [pr2.lambda.nonstatic](../sources/src/main/java/pr2/lambda/nonstatic/).
Wieder geht es um das einfache Spiel aus der ersten Aufgabe. Diesmal sollen Sie allerdings die Klasse `Alien` zu einer nichtstatischen Elementklasse von `GameBoard` machen. Achten Sie insbesondere darauf, dass sie nur noch die implizite Referenz `GameBoard.this` verwenden, um das Board innerhalb von `Alien` zu verwenden. Außerdem soll sich `Alien` im Konstruktor selbst als `MouseListener` registrieren, d.h. die entsprechende Zeile `addMouseListener(alien);` soll aus `GameBoard` verschwinden und in `Alien` verwendet werden.
Lassen Sie das Spiel wieder laufen und überprüfen Sie, ob es korrekt funktioniert.
## Abgabe (optional)
__Sie müssen keine Lösung für diese Aufgabe einreichen.__
Sie können Ihre Lösung aber auf die Konformität mit den Programmierstandards testen. Hierzu gehen Sie wie folgt vor:
1. Öffnen Sie eine Kommandozeile (Terminal).
2. Gehen Sie in Ihr Working Directory.
3. Wechseln Sie mit `cd` in das Verzeichnis `sources`.
4. Bauen Sie das Projekt mit dem Kommando `mvn`.

View File

@ -0,0 +1,29 @@
# Static Member Class
## Lernziel
Eine Klasse als statische Elementklasse realisieren.
## Aufgabe
Gehen Sie in das Paket [pr2.lambda.static_member](../sources/src/main/java/pr2/lambda/static_member/).
In dieser Aufgabe finden Sie bereits ein voll funktionsfähiges Beispiel vor. Lassen Sie es laufen und machen Sie sich mit der Funktionsweise vertraut. (Das Spiel kennen Sie bereits aus einer vorhergehenden Aufgabe, nur die Grafik ist etwas anders.)
Ihre Aufgabe besteht nun darin, die Klasse `Alien` zu einer statischen Elementklasse der Klasse `GameBoard` zu machen.
Lassen Sie das Programm nach der Änderung wieder laufen und schauen überprüfen Sie, dass es sich noch korrekt verhält.
## Abgabe (optional)
__Sie müssen keine Lösung für diese Aufgabe einreichen.__
Sie können Ihre Lösung aber auf die Konformität mit den Programmierstandards testen. Hierzu gehen Sie wie folgt vor:
1. Öffnen Sie eine Kommandozeile (Terminal).
2. Gehen Sie in Ihr Working Directory.
3. Wechseln Sie mit `cd` in das Verzeichnis `sources`.
4. Bauen Sie das Projekt mit dem Kommando `mvn`.

View File

@ -71,3 +71,25 @@ Hinweise zur nötigen Softwareausstattung finden Sie [hier](help/softwareausstat
| 61. | 04.05.2023 | [Rot13-Verschlüsselung](Assignment_061/readme.md) |
| 62. | 04.05.2023 | [Datei zerhacken](Assignment_062/readme.md) |
| 63. | 04.05.2023 | [Serialisierung](Assignment_063/readme.md) |
| 64. | 22.05.2023 | [Einen generischen Typ schreiben](Assignment_064/readme.md) |
| 65. | 22.05.2023 | [Generische Klasse Pair schreiben](Assignment_065/readme.md) |
| 66. | 22.05.2023 | [Generische Klasse Pair erweitern: NumberPair](Assignment_066/readme.md) |
| 67. | 22.05.2023 | [Generische Klasse Pair erweitern: SamePair](Assignment_067/readme.md) |
| 68. | 22.05.2023 | [PairList](Assignment_068/readme.md) |
| 69. | 22.05.2023 | [Wildcard benutzen](Assignment_069/readme.md) |
| 70. | 22.05.2023 | [Generische Queue](Assignment_070/readme.md) |
| 71. | 22.05.2023 | [`super` und `extends` einsetzen](Assignment_071/readme.md) |
| 72. | 22.05.2023 | [Generischen Typ verwenden](Assignment_072/readme.md) |
| 73. | 22.05.2023 | [Generische Typen zusammen mit Wildcards einsetzen](Assignment_073/readme.md) |
| 74. | 05.06.2023 | [Anonyme Klasse schreiben](Assignment_074/readme.md) |
| 75. | 05.06.2023 | [Eigene compare-Methode schreiben](Assignment_075/readme.md) |
| 76. | 05.06.2023 | [Innere Klasse Beobachter](Assignment_076/readme.md) |
| 77. | 05.06.2023 | [Callback mit anonymer Klasse realisieren](Assignment_077/readme.md) |
| 78. | 05.06.2023 | [Comparator als Lambda](Assignment_078/readme.md) |
| 79. | 05.06.2023 | [Callback mit Lambda realisieren](Assignment_079/readme.md) |
| 80. | 05.06.2023 | [Lokale Klasse schreiben](Assignment_080/readme.md) |
| 81. | 05.06.2023 | [MatrixSuche](Assignment_081/readme.md) |
| 82. | 05.06.2023 | [StringTransmogrifier](Assignment_082/readme.md) |
| 83. | 05.06.2023 | [StringTransmogrifier erweitern](Assignment_083/readme.md) |
| 84. | 05.06.2023 | [Nonstatic Member Class](Assignment_084/readme.md) |
| 85. | 05.06.2023 | [Static Member Class](Assignment_085/readme.md) |

View File

@ -0,0 +1,87 @@
package pr2.generics.einfach;
/**
* Eine einfache, verkettete Liste.
*
* @param <T> Typ der gespeicherten Objekte
*/
/**
* Eine einfache, verkettete Liste.
*/
public class Liste {
/** Referenz auf den ersten Knoten. */
private ListeNode first;
/** Referenz auf den aktuellen Knoten. */
private ListeNode current;
/**
* Fügt ein neues Element an das Ende der Liste an.
*
* @param data das Element
*/
public void add(Object data) {
ListeNode nextNode = new ListeNode(data);
if (current == null) {
// Liste komplett leer
first = nextNode;
current = nextNode;
}
else {
current.next = nextNode;
current = nextNode;
}
}
/**
* Liest das Element an der gegebenen Position.
*
* @param index Index, beginnend bei 0.
* @return Das Element oder {@code null}, wenn es nicht gefunden wurde.
*/
public Object get(int index) {
int count = 0;
ListeNode node = first;
while ((node != null) && (count < index)) {
node = node.next;
count++;
}
if ((count == index) && (node != null)) {
return node.data;
}
else {
// index does not exist
return null;
}
}
/**
* Löscht die Liste und entfernt alle Elemente.
*/
public void clear() {
first = null;
current = null;
}
/**
* Liefert die Anzahl der Elemente der Liste zurück.
*
* @return die Anzahl der Elemente.
*/
public int size() {
int count = 0;
ListeNode node = first;
while (node != null) {
node = node.next;
count++;
}
return count;
}
}

View File

@ -0,0 +1,22 @@
package pr2.generics.einfach;
/**
* Interne Repräsentation der Knoten in der Liste.
*/
class ListeNode {
/** Daten. */
Object data;
/** Referenz auf den nächsten Knoten. */
ListeNode next;
/**
* Legt einen neuen Knoten an.
*
* @param data daten, die gespeichert werden
*/
ListeNode(Object data) {
this.data = data;
}
}

View File

@ -0,0 +1,61 @@
package pr2.generics.einfach.test;
import org.junit.jupiter.api.Test;
import pr2.generics.einfach.Liste;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNull;
/**
* Test für die Liste.
*/
public class ListeTest {
/**
* Testet das Hinzufügen und Löschen der Liste.
*/
@Test
void testAddAndClear() {
Liste l = new Liste();
assertEquals(0, l.size());
l.add("Hallo");
assertEquals(1, l.size());
l.add("Hugo");
assertEquals(2, l.size());
l.add("Peter");
l.add("Alfons");
assertEquals(4, l.size());
l.clear();
assertEquals(0, l.size());
}
/**
* Testet das Lesen von Elementen.
*/
@Test
void testGet() {
Liste l = new Liste();
l.add("Hallo");
l.add("Hugo");
l.add("Peter");
l.add("Alfons");
assertNull(l.get(-1));
assertNull(l.get(4));
assertEquals("Hallo", l.get(0));
assertEquals("Hugo", l.get(1));
assertEquals("Peter", l.get(2));
assertEquals("Alfons", l.get(3));
assertEquals(4, l.size());
l.clear();
assertEquals(0, l.size());
assertNull(l.get(0));
assertNull(l.get(1));
assertNull(l.get(2));
assertNull(l.get(3));
}
}

View File

@ -0,0 +1,16 @@
package pr2.generics.number_pair;
public class Main {
public static void main(String[] args) {
// TODO: Einkommentieren
// var note = new Pair<String, Integer>("Peter", 1);
// var name = new Pair<String, String>("Peter", "Meier");
// var tel = new NumberPair<Integer>(621, 292122);
//
// System.out.printf("%s:%d\n", note.getFirst(), note.getSecond());
//
// System.out.printf("%s %s\n", name.getFirst(), name.getSecond());
//
// System.out.printf("%d %d\n", tel.getFirst(), tel.getSecond());
}
}

View File

@ -0,0 +1,5 @@
package pr2.generics.number_pair;
public class NumberPair {
}

View File

@ -0,0 +1,20 @@
package pr2.generics.number_pair;
public class Pair<T, V> {
private final T first;
private final V second;
public Pair(T first, V second) {
this.first = first;
this.second = second;
}
public T getFirst() {
return first;
}
public V getSecond() {
return second;
}
}

View File

@ -0,0 +1,18 @@
package pr2.generics.pair;
public class Main {
public static void main(String[] args) {
// TODO: Einkommentieren
// var note1 = new Pair<String, Integer>("Peter", 1);
// var note2 = new Pair<String, Integer>("Frank", 3);
// var note3 = new Pair<String, Integer>("Sabine", 1);
//
// var name = new Pair<String, String>("Peter", "Meier");
//
// System.out.printf("%s:%d\n", note1.getFirst(), note1.getSecond());
// System.out.printf("%s:%d\n", note2.getFirst(), note1.getSecond());
// System.out.printf("%s:%d\n", note3.getFirst(), note1.getSecond());
//
// System.out.printf("%s %s\n", name.getFirst(), name.getSecond());
}
}

View File

@ -0,0 +1,5 @@
package pr2.generics.pair;
public class Pair {
}

View File

@ -0,0 +1,20 @@
package pr2.generics.pairlist;
public class Main {
public static void main(String[] args) {
// TODO: Einkommentieren
// var note1 = new Pair<String, Integer>("Peter", 1);
// var note2 = new Pair<String, Integer>("Frank", 3);
// var note3 = new Pair<String, Integer>("Sabine", 1);
//
// var pl = new PairList<String, Integer>(3);
// pl.add(note1);
// pl.add(note2);
// pl.add(note3);
//
// for (int i = 0; i < 3; i++) {
// System.out.printf("%s:%d\n", pl.get(i).getFirst(),
// pl.get(i).getSecond());
// }
}
}

View File

@ -0,0 +1,20 @@
package pr2.generics.pairlist;
public class Pair<T, V> {
private final T first;
private final V second;
public Pair(T first, V second) {
this.first = first;
this.second = second;
}
public T getFirst() {
return first;
}
public V getSecond() {
return second;
}
}

View File

@ -0,0 +1,5 @@
package pr2.generics.pairlist;
public class PairList {
}

View File

@ -0,0 +1,6 @@
package pr2.generics.printer;
import java.util.Collection;
public class CollectionPrinter {
}

View File

@ -0,0 +1,24 @@
package pr2.generics.printer;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
public class Main {
public static void main(String[] args) {
// TODO: Einkommentieren
// List<String> ls = new ArrayList<>();
// List<Integer> li = new ArrayList<>();
// ls.add("PR2");
// ls.add("ist");
// ls.add("cool");
// Set<String> s = new HashSet<>(ls);
// li.add(23);
// li.add(42);
//
// CollectionPrinter.print(ls);
// CollectionPrinter.print(li);
// CollectionPrinter.print(s);
}
}

View File

@ -0,0 +1,6 @@
package pr2.generics.queue;
public class Queue {
// TODO: Klasse gemäß der Aufgabenstellung implementieren
}

View File

@ -0,0 +1,16 @@
package pr2.generics.same_pair;
public class Main {
public static void main(String[] args) {
// TODO: Einkommentieren
// var note = new Pair<String, Integer>("Peter", 1);
// var name = new SamePair<String>("Peter", "Meier");
// var tel = new SamePair<Integer>(621, 2009992);
//
// System.out.printf("%s:%d\n", note.getFirst(), note.getSecond());
//
// System.out.printf("%s %s\n", name.getFirst(), name.getSecond());
//
// System.out.printf("%d %d\n", tel.getFirst(), tel.getSecond());
}
}

View File

@ -0,0 +1,20 @@
package pr2.generics.same_pair;
public class Pair<T, V> {
private final T first;
private final V second;
public Pair(T first, V second) {
this.first = first;
this.second = second;
}
public T getFirst() {
return first;
}
public V getSecond() {
return second;
}
}

View File

@ -0,0 +1,5 @@
package pr2.generics.same_pair;
public class SamePair {
}

View File

@ -0,0 +1,102 @@
package pr2.generics.super_extends;
/**
* Eine einfache, verkettete Liste.
*
* @param <T> Typ der gespeicherten Objekte
*/
public class Liste<T> {
/**
* Referenz auf den ersten Knoten.
*/
private ListeNode<T> first;
/**
* Referenz auf den aktuellen Knoten.
*/
private ListeNode<T> current;
/**
* Fügt ein neues Element an das Ende der Liste an.
*
* @param data das Element
*/
public void add(T data) {
ListeNode<T> nextNode = new ListeNode<>(data);
if (current == null) {
// Liste komplett leer
first = nextNode;
current = nextNode;
}
else {
current.next = nextNode;
current = nextNode;
}
}
/**
* Liest das Element an der gegebenen Position.
*
* @param index Index, beginnend bei 0.
* @return Das Element oder {@code null}, wenn es nicht gefunden wurde.
*/
public T get(int index) {
int count = 0;
ListeNode<T> node = first;
while ((node != null) && (count < index)) {
node = node.next;
count++;
}
if ((count == index) && (node != null)) {
return node.data;
}
else {
// index does not exist
return null;
}
}
/**
* Löscht die Liste und entfernt alle Elemente.
*/
public void clear() {
first = null;
current = null;
}
/**
* Liefert die Anzahl der Elemente der Liste zurück.
*
* @return die Anzahl der Elemente.
*/
public int size() {
int count = 0;
ListeNode<T> node = first;
while (node != null) {
node = node.next;
count++;
}
return count;
}
/**
* Kopiert alle Elemente dieser Liste in die andere Liste.
*
* @param other die andere Liste.
*/
// TODO: copyInto implementieren
/**
* Füllt diese Liste mit dem Inhalt der übergebenen Liste.
*
* @param other die andere Liste.
*/
// TODO: fillFrom implementieren
}

View File

@ -0,0 +1,28 @@
package pr2.generics.super_extends;
/**
* Interne Repräsentation der Knoten in der Liste.
*
* @param <T> Typ der gespeicherten Daten.
*/
class ListeNode<T> {
/**
* Daten.
*/
T data;
/**
* Referenz auf den nächsten Knoten.
*/
ListeNode<T> next;
/**
* Legt einen neuen Knoten an.
*
* @param data daten, die gespeichert werden
*/
ListeNode(T data) {
this.data = data;
}
}

View File

@ -0,0 +1,43 @@
package pr2.generics.super_extends.test;
import org.junit.jupiter.api.Test;
import pr2.generics.super_extends.Liste;
import static org.junit.jupiter.api.Assertions.assertEquals;
/**
* Test für die Liste.
*/
public class ListeTest {
/**
* Testet das Umkopieren.
*/
@Test
void testAddAndClear() {
// TODO: Einkommentieren
// Liste<String> ls = new Liste<>();
// Liste<Object> lo = new Liste<>();
//
// ls.add("Hallo");
// ls.add("Hugo");
// ls.add("Peter");
// ls.add("Alfons");
//
// ls.copyInto(lo);
//
// assertEquals("Hallo", lo.get(0));
// assertEquals("Hugo", lo.get(1));
// assertEquals("Peter", lo.get(2));
// assertEquals("Alfons", lo.get(3));
//
// lo = new Liste<>();
// lo.fillFrom(ls);
//
// assertEquals("Hallo", lo.get(0));
// assertEquals("Hugo", lo.get(1));
// assertEquals("Peter", lo.get(2));
// assertEquals("Alfons", lo.get(3));
}
}

View File

@ -0,0 +1,166 @@
package pr2.generics.verwenden;
import de.smits_net.games.framework.board.Board;
import de.smits_net.games.framework.image.SimpleImage;
import de.smits_net.games.framework.sprite.Sprite;
import de.smits_net.games.framework.sprite.Sprite.BoundaryPolicy;
import de.smits_net.games.framework.sprite.Velocity;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.event.MouseEvent;
import java.util.Random;
import java.util.Stack;
/**
* Spielfeld.
*/
public class GameBoard extends Board {
/**
* Zufallszahlengenerator.
*/
private final Random rnd = new Random();
/**
* Münzstapel.
*/
// TODO: Münzen als Stack speichern
/**
* A moving coin.
*/
private Sprite moving;
/**
* Punkte.
*/
private int points = 0;
/**
* Zeitpunkt des ersten Klicks.
*/
private long startzeit;
/**
* Erzeugt ein neues Board.
*/
public GameBoard() {
// neues Spielfeld anlegen
super(10, new Dimension(400, 400), Color.BLACK);
// Münzen anlegen
for (int i = 0; i < 20; i++) {
// TODO: Neue Münzen auf den Stapel legen
}
}
/**
* Legt eine zufällige Münze an.
*
* @return die Münze als Sprite.
*/
private Sprite createCoin() {
final String prefix = "pr2/generics/verwendung";
String asset;
switch (rnd.nextInt(8)) {
case 0:
asset = prefix + "/1c.png";
break;
case 1:
asset = prefix + "/2c.png";
break;
case 3:
asset = prefix + "/5c.png";
break;
case 4:
asset = prefix + "/10c.png";
break;
case 5:
asset = prefix + "/20c.png";
break;
case 6:
asset = prefix + "/50c.png";
break;
case 7:
asset = prefix + "/1e.png";
break;
default:
asset = prefix + "/2e.png";
break;
}
int offset = rnd.nextInt(10);
return new Sprite(this, new Point(100 + offset, 100 + offset),
BoundaryPolicy.NONE, new SimpleImage(asset));
}
/**
* Spielfeld neu zeichnen. Wird vom Framework aufgerufen.
*/
@Override
public synchronized void drawGame(Graphics g) {
// TODO: Alle Münzen zeichnen
if (moving != null) {
moving.draw(g, this);
}
writeText(g, 0, 20, "Punkte: " + points);
}
/**
* Spielfeld zeichnen.
*
* @param g Grafik-Kontext.
*/
@Override
protected void drawGameOver(Graphics g) {
centerText(g, String.format("%d Punkte in %.2f Sekunden", points,
(System.currentTimeMillis() - startzeit) / 1000.0));
}
/**
* Mausklick abfangen.
*
* @param e Maus-Event.
*/
@Override
public synchronized void mouseClicked(MouseEvent e) {
if (startzeit == 0) {
startzeit = System.currentTimeMillis();
}
// TODO: Wenn Stapel leer ist, nichts tun
// Oberstes Sprite vom Stapel ansehen und s zuweisen
Sprite s = null;
if (s.intersects(new Point(e.getX(), e.getY()))) {
points++;
// TODO: Oberstes Sprite vom Stapel entfernen und s zuweisen
moving = s;
moving.setVelocity(new Velocity(0, 20));
}
}
/**
* Spielsituation updaten. Wird vom Framework aufgerufen.
*/
@Override
public boolean updateGame() {
if (moving != null) {
moving.move();
}
// TODO: Solange Stapel noch Elemente enthält, true zurückgeben.
return true;
}
}

View File

@ -0,0 +1,28 @@
package pr2.generics.verwenden;
import de.smits_net.games.framework.board.MainWindow;
import java.awt.EventQueue;
/**
* Hauptklasse des Spiels.
*/
public class GameMain extends MainWindow {
/**
* Neues Spiel anlegen.
*/
public GameMain() {
super("Click the coins as fast as you can", new GameBoard());
}
/**
* Startpunkt.
*
* @param args command line arguments.
*/
public static void main(String[] args) {
// Spiel starten
EventQueue.invokeLater(GameMain::new);
}
}

View File

@ -0,0 +1,23 @@
package pr2.generics.wildcards;
/**
* Klasse zum Ausdrucken von Listen.
*/
public class ListHelper {
/**
* Druckt alle Elemente der Liste auf der Konsole aus.
*
* @param liste Die zu druckende Liste.
*/
// TODO: Methode schreiben
/**
* Summiert die Elemente der Liste. Deswegen können nur Listen übergeben
* werden, deren Elemente mindestens vom Typ {@code Number} sind.
*
* @param liste Die Liste, deren Elemente summiert werden sollen.
* @return das Ergebnis
*/
// TODO: Methode schreiben
}

View File

@ -0,0 +1,39 @@
package pr2.generics.wildcards;
/**
* Ausgabe der Liste.
*/
public final class Main {
/**
* Constructor.
*/
private Main() {
// keine Instanzen
}
/**
* Haupt-Methode.
*
* @param args Kommandozeilenargumente.
*/
public static void main(String[] args) {
SimpleList<String> l1 = new SimpleList<>();
l1.add("Dies");
l1.add("ist");
l1.add("ein");
l1.add("Test");
l1.add(".");
SimpleList<Integer> l2 = new SimpleList<>();
l2.add(1);
l2.add(2);
l2.add(3);
l2.add(4);
l2.add(5);
// ListHelper.printList(l1);
// ListHelper.printList(l2);
// System.out.println(ListHelper.sumList(l2));
}
}

View File

@ -0,0 +1,12 @@
package pr2.generics.wildcards;
import java.util.ArrayList;
/**
* Listenklasse.
*
* @param <T> Typ, der in der Liste gespeichert wird.
*/
public class SimpleList<T> extends ArrayList<T> {
// nothing here
}

View File

@ -0,0 +1,22 @@
package pr2.lambda.array_sorter;
import java.util.Arrays;
import java.util.Comparator;
import java.util.Date;
public class ReverseSort {
public static void main(String[] args) {
Date[] dates = {
new Date(9200000000L),
new Date(9300000000L),
new Date(92100000000L),
new Date(9600000000L),
new Date(93300000000L)
};
// TODO: Daten umgekehrt sortieren
System.out.println(Arrays.asList(dates));
}
}

View File

@ -0,0 +1,36 @@
package pr2.lambda.callback;
import java.util.Arrays;
/**
* Hauptklasse.
*/
public class Main {
private static final int[] ZAHLEN =
{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
20};
/**
* Hauptmethode.
*
* @param args Kommandozeilenargumente.
*/
public static void main(String[] args) {
NumberSelector s = new NumberSelector();
int[] gerade = null;
// TODO: Gerade Zahlen filtern
System.out.println(Arrays.toString(gerade));
int[] ungerade = null;
// TODO: Ungerade Zahlen filtern
System.out.println(Arrays.toString(ungerade));
}
}

View File

@ -0,0 +1,30 @@
package pr2.lambda.callback;
/**
* Auswählen von Zahlen mithilfe eines Callbacks.
*/
public class NumberSelector {
/**
* Filtert die übergebenen Zahlen anhand des Prädikates.
*
* @param predicate Prädikat.
* @param numbers die zu filternden Zahlen.
* @return Das Ergebnis
*/
public int[] filter(Predicate<Integer> predicate, int[] numbers) {
int[] temp = new int[numbers.length];
int count = 0;
for (int i : numbers) {
if (predicate.accept(i)) {
temp[count++] = i;
}
}
int[] result = new int[count];
System.arraycopy(temp, 0, result, 0, count);
return result;
}
}

View File

@ -0,0 +1,20 @@
package pr2.lambda.callback;
/**
* Interface, um Entscheidung über ein Objekt zu
* treffen.
*
* @param <T> Typ des Objekts
*/
@FunctionalInterface
public interface Predicate<T> {
/**
* Entscheidet, ob ein Objekt akzeptiert wird oder nicht.
*
* @param object das zu untersuchende Objekt
* @return {@code true} wenn das Objekt akzeptiert wird,
* andernfalls {@code false}.
*/
boolean accept(T object);
}

View File

@ -0,0 +1,12 @@
package pr2.lambda.comparator;
import java.util.Arrays;
public class SortLambda {
public static void main(String[] args) {
Integer[] zahlen = {23, 42, 17, 9, 1, 5, 7, 88, 35};
// TODO: Zahlen mit einem Lambda sortieren
System.out.println(Arrays.toString(zahlen));
}
}

View File

@ -0,0 +1,33 @@
package pr2.lambda.lambdas;
import java.util.Arrays;
/**
* Hauptklasse.
*/
public class Main {
private static final int[] ZAHLEN =
{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
20};
/**
* Hauptmethode.
*
* @param args Kommandozeileargumente.
*/
public static void main(String[] args) {
NumberSelector s = new NumberSelector();
// TODO: Daten filtern
int[] gerade = null;
System.out.println(Arrays.toString(gerade));
// TODO: Daten filtern
int[] ungerade = null;
System.out.println(Arrays.toString(ungerade));
}
}

View File

@ -0,0 +1,30 @@
package pr2.lambda.lambdas;
/**
* Auswählen von Zahlen mithilfe eines Callbacks.
*/
public class NumberSelector {
/**
* Filtert die übergebenen Zahlen anhand des Prädikates.
*
* @param predicate Prädikat.
* @param numbers die zu filternden Zahlen.
* @return Das Ergebnis
*/
public int[] filter(Predicate<Integer> predicate, int[] numbers) {
int[] temp = new int[numbers.length];
int count = 0;
for (int i : numbers) {
if (predicate.accept(i)) {
temp[count++] = i;
}
}
int[] result = new int[count];
System.arraycopy(temp, 0, result, 0, count);
return result;
}
}

View File

@ -0,0 +1,20 @@
package pr2.lambda.lambdas;
/**
* Interface, um Entscheidung über ein Objekt zu
* treffen.
*
* @param <T> Typ des Objekts
*/
@FunctionalInterface
public interface Predicate<T> {
/**
* Entscheidet, ob ein Objekt akzeptiert wird oder nicht.
*
* @param object das zu untersuchende Objekt
* @return {@code true} wenn das Objekt akzeptiert wird,
* andernfalls {@code false}.
*/
boolean accept(T object);
}

View File

@ -0,0 +1,46 @@
package pr2.lambda.local;
import de.smits_net.games.framework.board.Board;
import de.smits_net.games.framework.image.AnimatedImage;
import de.smits_net.games.framework.image.ImagePack;
import de.smits_net.games.framework.image.StripedImage;
import de.smits_net.games.framework.sprite.AnimatedSprite;
import de.smits_net.games.framework.sprite.Direction;
import java.awt.Point;
/**
* Ein Alien.
*/
public class Alien extends AnimatedSprite {
/**
* Geschwindigkeit des Aliens X-Richtung.
*/
private static final int ALIEN_SPEED = 2;
/**
* Neues Alien anlegen.
*
* @param board das Spielfeld
* @param startPoint Start-Position
*/
public Alien(Board board, Point startPoint) {
super(board, startPoint, BoundaryPolicy.JUMP_BACK,
new AnimatedImage(50,
new ImagePack("pr2/lambda/local/",
"ship01", "ship02", "ship03")));
velocity.setVelocity(Direction.WEST, ALIEN_SPEED);
}
/**
* Alien explodieren lassen.
*/
public void explode() {
setActive(false);
setImages(new AnimatedImage(20,
new StripedImage("pr2/lambda/local/explosion_1" + ".png",
43)));
setInvisibleAfterFrames(70);
}
}

View File

@ -0,0 +1,62 @@
package pr2.lambda.local;
import de.smits_net.games.framework.board.Board;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.Random;
/**
* Spielfeld.
*/
public class GameBoard extends Board {
/**
* Alien, das durch das Bild läuft.
*/
Alien alien; // nicht private wegen Zugriff aus innerer Klasse
/**
* Erzeugt ein neues Board.
*/
public GameBoard() {
// neues Spielfeld anlegen
super(10, new Dimension(800, 300), Color.BLACK);
// Alien initialisieren
alien = new Alien(this,
new Point(800, 50 + new Random().nextInt(100)));
// TODO: AlienExploder hier einfügen
}
/**
* Spielfeld neu zeichnen. Wird vom Framework aufgerufen.
*/
@Override
public void drawGame(Graphics g) {
// Alien zeichnen
alien.draw(g, this);
}
/**
* Game-Over-Text anzeigen. Wird vom Framework aufgerufen.
*/
@Override
public void drawGameOver(Graphics g) {
centerText(g, "Das Spiel ist aus!");
}
/**
* Spielsituation updaten. Wird vom Framework aufgerufen.
*/
@Override
public boolean updateGame() {
alien.move();
return alien.isVisible();
}
}

View File

@ -0,0 +1,28 @@
package pr2.lambda.local;
import de.smits_net.games.framework.board.MainWindow;
import java.awt.EventQueue;
/**
* Hauptklasse des Spiels.
*/
public class GameMain extends MainWindow {
/**
* Neues Spiel anlegen.
*/
public GameMain() {
super("Click Alien - (03) Local Class", new GameBoard());
}
/**
* Startpunkt.
*
* @param args command line arguments.
*/
public static void main(String[] args) {
EventQueue.invokeLater(GameMain::new);
}
}

View File

@ -0,0 +1,5 @@
package pr2.lambda.matrixsuche;
public class MatrixSuche {
}

View File

@ -0,0 +1,33 @@
package pr2.lambda.matrixsuche.test;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import pr2.lambda.matrixsuche.MatrixSuche;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNull;
public class MatrixSucheTest {
@Test
void testSuche() {
// TODO: Einkommentieren
// int[][] matrix = {
// {3, 5, 6, 7, 8},
// {10, 12, 14, 16, 18},
// {23, 25, 26, 27, 28}
// };
//
// Assertions.assertEquals("(0, 1)",
// MatrixSuche.findEntry(matrix, 5).toString());
// assertEquals("(2, 0)",
// MatrixSuche.findEntry(matrix, 23).toString());
// assertEquals("(1, 2)",
// MatrixSuche.findEntry(matrix, 14).toString());
// assertEquals("(0, 4)",
// MatrixSuche.findEntry(matrix, 8).toString());
// assertNull(
// MatrixSuche.findEntry(matrix, 99));
}
}

View File

@ -0,0 +1,4 @@
package pr2.lambda.mogrifier_1;
public interface StringFunction {
}

View File

@ -0,0 +1,6 @@
package pr2.lambda.mogrifier_1;
public class StringTransmogrifier {
// TODO: Statische Methode transmogrify schreiben
}

View File

@ -0,0 +1,15 @@
package pr2.lambda.mogrifier_1.test;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import pr2.lambda.mogrifier_1.StringTransmogrifier;
import static org.junit.jupiter.api.Assertions.assertArrayEquals;
public class StringTransmogrifierTest {
@Test
void testMogrification() {
// TODO: Tests durchführen
}
}

View File

@ -0,0 +1,6 @@
package pr2.lambda.mogrifier_2;
public interface StringFunction {
String apply(String s);
}

View File

@ -0,0 +1,14 @@
package pr2.lambda.mogrifier_2;
public class StringTransmogrifier {
public static String[] transmogrify(String[] elements, StringFunction t) {
String[] result = new String[elements.length];
for (int i = 0; i < elements.length; i++) {
result[i] = t.apply(elements[i]);
}
return result;
}
}

View File

@ -0,0 +1,38 @@
package pr2.lambda.mogrifier_2.test;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import pr2.lambda.mogrifier_2.StringFunction;
import pr2.lambda.mogrifier_2.StringTransmogrifier;
import static org.junit.jupiter.api.Assertions.assertArrayEquals;
public class StringTransmogrifierTest {
static final String[] ELEMENTS = {"Hello", "World"};
@Test
void testMogrification() {
Assertions.assertArrayEquals(new String[] {"hello", "world"},
StringTransmogrifier.transmogrify(ELEMENTS,
String::toLowerCase));
assertArrayEquals(new String[] {"HELLO", "WORLD"},
StringTransmogrifier.transmogrify(ELEMENTS,
String::toUpperCase));
assertArrayEquals(new String[] {"Ifmmp", "Xpsme"},
StringTransmogrifier.transmogrify(ELEMENTS,
s -> {
char[] c = s.toCharArray();
for (int i = 0; i < c.length; i++) {
c[i] = (char) (c[i] + 1);
}
return new String(c);
}));
}
// TODO: Tests für caesar durchführen
}

View File

@ -0,0 +1,54 @@
package pr2.lambda.nonstatic;
import de.smits_net.games.framework.board.Board;
import de.smits_net.games.framework.image.AnimatedImage;
import de.smits_net.games.framework.image.ImagePack;
import de.smits_net.games.framework.image.StripedImage;
import de.smits_net.games.framework.sprite.AnimatedSprite;
import de.smits_net.games.framework.sprite.Direction;
import java.awt.Point;
/**
* Ein Alien.
*/
public class Alien extends AnimatedSprite {
/**
* Geschwindigkeit des Aliens X-Richtung.
*/
private static final int ALIEN_SPEED = 2;
/**
* Neues Alien anlegen.
*
* @param board das Spielfeld
* @param startPoint Start-Position
*/
public Alien(Board board, Point startPoint) {
super(board, startPoint, BoundaryPolicy.JUMP_BACK,
new AnimatedImage(50,
new ImagePack("pr2/lambda/static_member",
"ship01", "ship02", "ship03")));
velocity.setVelocity(Direction.WEST, ALIEN_SPEED);
}
/**
* Alien explodieren lassen.
*/
public void explode() {
setActive(false);
setImages(new AnimatedImage(20,
new StripedImage("pr2/lambda/static_member/explosion_1.png",
43)));
setInvisibleAfterFrames(70);
}
/**
* Klick auf das Alien lässt es explodieren.
*/
@Override
public void mousePressed() {
explode();
}
}

View File

@ -0,0 +1,67 @@
package pr2.lambda.nonstatic;
import de.smits_net.games.framework.board.Board;
import de.smits_net.games.framework.image.AnimatedImage;
import de.smits_net.games.framework.image.ImagePack;
import de.smits_net.games.framework.image.StripedImage;
import de.smits_net.games.framework.sprite.AnimatedSprite;
import de.smits_net.games.framework.sprite.Direction;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Point;
import java.util.Random;
/**
* Spielfeld.
*/
public class GameBoard extends Board {
/**
* Alien, das durch das Bild läuft.
*/
private final Alien alien;
/**
* Erzeugt ein neues Board.
*/
public GameBoard() {
// neues Spielfeld anlegen
super(10, new Dimension(800, 300), Color.BLACK);
// Alien initialisieren
alien = new Alien(this, new Point(800, 50 + new Random().nextInt(100)));
// Alien soll auf Maus-Klicks reagieren
addMouseListener(alien);
}
/**
* Spielfeld neu zeichnen. Wird vom Framework aufgerufen.
*/
@Override
public void drawGame(Graphics g) {
// Alien zeichnen
alien.draw(g, this);
}
/**
* Game-Over-Text anzeigen. Wird vom Framework aufgerufen.
*/
@Override
public void drawGameOver(Graphics g) {
centerText(g, "Das Spiel ist aus!");
}
/**
* Spielsituation updaten. Wird vom Framework aufgerufen.
*/
@Override
public boolean updateGame() {
alien.move();
return alien.isVisible();
}
// TODO: Alien zu einer non-static class machen
}

View File

@ -0,0 +1,27 @@
package pr2.lambda.nonstatic;
import de.smits_net.games.framework.board.MainWindow;
import java.awt.EventQueue;
/**
* Hauptklasse des Spiels.
*/
public class GameMain extends MainWindow {
/**
* Neues Spiel anlegen.
*/
public GameMain() {
super("Click Alien - (02) Nonstatic Member", new GameBoard());
}
/**
* Startpunkt.
*
* @param args command line arguments.
*/
public static void main(String[] args) {
EventQueue.invokeLater(GameMain::new);
}
}

View File

@ -0,0 +1,5 @@
package pr2.lambda.observer;
public interface Beobachter {
int getValue();
}

View File

@ -0,0 +1,54 @@
package pr2.lambda.static_member;
import de.smits_net.games.framework.board.Board;
import de.smits_net.games.framework.image.AnimatedImage;
import de.smits_net.games.framework.image.ImagePack;
import de.smits_net.games.framework.image.StripedImage;
import de.smits_net.games.framework.sprite.AnimatedSprite;
import de.smits_net.games.framework.sprite.Direction;
import java.awt.Point;
/**
* Ein Alien.
*/
public class Alien extends AnimatedSprite {
/**
* Geschwindigkeit des Aliens X-Richtung.
*/
private static final int ALIEN_SPEED = 2;
/**
* Neues Alien anlegen.
*
* @param board das Spielfeld
* @param startPoint Start-Position
*/
public Alien(Board board, Point startPoint) {
super(board, startPoint, BoundaryPolicy.JUMP_BACK,
new AnimatedImage(50,
new ImagePack("pr2/lambda/static_member",
"ship01", "ship02", "ship03")));
velocity.setVelocity(Direction.WEST, ALIEN_SPEED);
}
/**
* Alien explodieren lassen.
*/
public void explode() {
setActive(false);
setImages(new AnimatedImage(20,
new StripedImage("pr2/lambda/static_member/explosion_1.png",
43)));
setInvisibleAfterFrames(70);
}
/**
* Klick auf das Alien lässt es explodieren.
*/
@Override
public void mousePressed() {
explode();
}
}

View File

@ -0,0 +1,68 @@
package pr2.lambda.static_member;
import de.smits_net.games.framework.board.Board;
import de.smits_net.games.framework.image.AnimatedImage;
import de.smits_net.games.framework.image.ImagePack;
import de.smits_net.games.framework.image.StripedImage;
import de.smits_net.games.framework.sprite.AnimatedSprite;
import de.smits_net.games.framework.sprite.Direction;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Point;
import java.util.Random;
/**
* Spielfeld.
*/
public class GameBoard extends Board {
/**
* Alien, das durch das Bild läuft.
*/
private final Alien alien;
/**
* Erzeugt ein neues Board.
*/
public GameBoard() {
// neues Spielfeld anlegen
super(10, new Dimension(800, 300), Color.BLACK);
// Alien initialisieren
alien = new Alien(this,
new Point(800, 50 + new Random().nextInt(100)));
// Alien soll auf Maus-Klicks reagieren
addMouseListener(alien);
}
/**
* Spielfeld neu zeichnen. Wird vom Framework aufgerufen.
*/
@Override
public void drawGame(Graphics g) {
// Alien zeichnen
alien.draw(g, this);
}
/**
* Game-Over-Text anzeigen. Wird vom Framework aufgerufen.
*/
@Override
public void drawGameOver(Graphics g) {
centerText(g, "Das Spiel ist aus!");
}
/**
* Spielsituation updaten. Wird vom Framework aufgerufen.
*/
@Override
public boolean updateGame() {
alien.move();
return alien.isVisible();
}
// TODO: Alien zu einer statischen Klasse machen
}

View File

@ -0,0 +1,27 @@
package pr2.lambda.static_member;
import de.smits_net.games.framework.board.MainWindow;
import java.awt.EventQueue;
/**
* Hauptklasse des Spiels.
*/
public class GameMain extends MainWindow {
/**
* Neues Spiel anlegen.
*/
public GameMain() {
super("Click Alien - (01) Static Member", new GameBoard());
}
/**
* Startpunkt.
*
* @param args command line arguments.
*/
public static void main(String[] args) {
EventQueue.invokeLater(GameMain::new);
}
}