Skip to content

Latest commit

 

History

History
209 lines (155 loc) · 8.05 KB

File metadata and controls

209 lines (155 loc) · 8.05 KB

Blatt 03: Methodenrefs, Lambdas, Observer

Zusammenfassung

Auf diesem Blatt üben Sie den Einsatz von Lambda-Ausdrücken und Methodenreferenzen. Sie modellieren das Observer-Pattern in einem kleinen Spiel.

Aufgaben

Aufgabe 1: Calculator: Anonyme Klassen und Lambda-Ausdrücke

Klonen/forken Sie die Vorgaben "Calculator" und laden Sie das Projekt in Ihre IDE. Konfigurieren Sie Gradle für dieses Projekt.

Im Package calculator finden Sie einige Interfaces und Klassen, mit denen man einen einfachen Taschenrechner modellieren kann: Dieser kann einfache mathematische Operationen auf zwei Integern ausführen.

In der Klasse calculator.Calculator finden Sie vier mit TODO markierte Stellen in der Methode setupOperationSelector:

  1. Erstellen Sie eine neue Java-Klasse Sub, die das Interface Operation implementiert und eine Subtraktion bereitstellt. Erweitern Sie den Calculator und binden Sie eine Instanz dieser Klasse ein. Nutzen Sie hier keine anonymen Klassen oder Lambda-Ausdrücke.
  2. Erstellen Sie eine weitere Operation "Mul" (Multiplikation von zwei Integern). Nutzen Sie dazu eine passende anonyme Klasse.
  3. Erstellen Sie eine weitere Operation "Div" (Integerdivision). Erstellen Sie einen passenden Lambda-Ausdruck.
  4. Für die JComboBox operationSelector wird ein ActionListener mit Hilfe einer anonymen Klasse definiert. Konvertieren Sie dies in einen entsprechenden Lambda-Ausdruck.

LockSnake: Lambda-Ausdrücke, Methodenreferenzen und Observer-Pattern

Klonen/forken Sie die Vorgaben "LockSnake" und laden Sie das Projekt in Ihre IDE. Konfigurieren Sie Gradle für dieses Projekt.

Ziel des Projekts ist es, ein kleines Swing-basiertes Spiel nach dem Vorbild von "Mouse: P.I. For Hire Lockpicking Gameplay" (16 s) zu implementieren.

Sie finden im Projekt ein lauffähiges Projektgerüst mit:

  • einem lauffähigen Swing-Fenster (Main, GamePanel) inkl. Timer-Loop,
  • einem fertigen Renderer (Java2DRenderer) sowie fertiger Level-Logik (Level, LevelLoader, Beispiellevel src/main/resources/levels/level1.txt),
  • den Datentypen CellType, Position, Direction, Pin und Snake,
  • einer leeren Modellierung für den Spielzustand GameState sowie einem leeren Spielmodell GameEngine.

Das fertige Spiel mit dem Beispiellevel könnte wie im folgenden Screenshot gezeigt aussehen:

(hier noch ein Link zu einem kurzen Video [YT]/[HSBI]).

Aufgabe 2.1: Code-Analyse

Analysieren Sie die Vorgaben und erstellen Sie ein UML-Klassendiagramm, welches die Beziehungen zwischen den Klassen zeigt.

Aufgabe 2.2: Spielmodell GameEngine und Spielzustand GameState

Ergänzen Sie das Spielmodell GameEngine und die Modellierung des Spielzustands GameState so, dass das Spiel spielbar ist und die Pin-Mechanik korrekt funktioniert. (Die mit TODO markierten Stellen sind ein guter Ausgangspunkt ...)

Aufgabe 2.3: Observer-Pattern

  1. Nutzen Sie das Observer-Pattern, so dass die GUI GamePanel automatisch aktualisiert wird, wenn sich der Spielzustand ändert.
  2. Nutzen Sie das Observer-Pattern, so dass die GameEngine automatisch benachrichtigt wird und den Spielzustand aktualisieren kann, wenn eine konfigurierte Taste gedrückt wird.

Aufgabe 2.4: JUnit

Schreiben Sie Unit-Tests mit JUnit 6 für Ihre Implementierung der Klasse GameState, um die Spielzustands-Logik zuverlässig zu validieren. Decken Sie dabei mindestens diese Kernfälle ab: Bewegungen, Pin-Interaktionen, Kollisionen/Blockaden, Gewinn-/Verlustzustände, Initialzustand.

Checkliste:

  • Mindestens 10 gut dokumentierte Tests für GameState, wie oben beschrieben.
  • Tests decken alle genannten Kernfälle ab (Wand, Pin blockiert, Pin aktivierbar, Selbstkollision, Gewinnbedingung, etc.).
  • Tests verwenden klare Assertions, keine Off-by-One-Fehler, eindeutige Erwartungshaltung, sprechende Testnamen, "given-when-then"-Mantra.
  • Tests bauen auf Level/Pin-Setup auf, sodass sie reproduzierbar sind (Test-Fixtures).

Checkliste Abgabe

  • Korrekte Behandlung von Wand / Pin blockiert / Pin aktivierbar
  • Korrekte Behandlung von Selbstkollision
  • Gewinnbedingung "alle Pins gesetzt"
  • Mind. 10 JUnit-Tests für GameState
  • Observer-Pattern sichtbar im Code:
    • UI (GamePanel) ist Observer für GameState in der GameEngine
    • GameEngine ist Observer für Direction (Tastatur-Events) im GamePanel
  • Lösung enthält mindestens 3 Lambda-Ausdrücke
  • Lösung enthält mindestens 2 Methodenreferenzen

Bonus

Sie finden in den Vorgaben Skizzen für TextureRenderer und MusicPlayer. Implementieren Sie davon ausgehend einen Renderer, der mit Texturen arbeitet. Lassen Sie im Hintergrund passend zum Spielzustand Soundeffekte abspielen (weiterer Observer in GameEngine). Erstellen Sie weitere Levels und ermöglichen Sie eine Level-Auswahl oder ein Fortschreiten der Level, sobald die User das aktuelle Level gelöst haben.

Details

Spielregeln

Spielfeld/Level

Das Spielfeld besteht aus Zellen (Grid). Es gibt:

  • Wände # (blockieren Bewegung),
  • leere Felder .,
  • Pin-Slots (im Level durch Pfeile markiert, z.B. ^ v < >),
  • eine Startposition S für die Snake.

(Symbole wie in der Level-Datei verwendet)

Bewegung
  • Die Spielschlange ("Snake") bewegt sich automatisch in Ticks.
  • Pro Tick gilt: Es wird höchstens ein Schritt in Blickrichtung ausgeführt.
  • Die Schlange erhält eine "Blickrichtung", wenn eine der Tasten "W A S D" oder "H J K L" oder die Pfeiltasten gedrückt werden.
  • Die Blickrichtung wird als kleine rote "Nase" angezeigt.
  • Die Blickrichtung bleibt erhalten, bis eine Tasteneingabe eine neue Blickrichtung setzt oder die Blickrichtung durch eine Blockade aufgelöst wird.
  • Ohne gesetzte Blickrichtung passiert nichts.
  • Die Schlange wächst bei jedem erfolgreich ausgeführten Schritt (der alte Kopf wird Teil des Körpers).
Wände
  • Eine Bewegung in eine Wand wird verworfen (Schlange bleibt stehen).
Pins

Jeder Pin hat:

  • eine Position,
  • einen Zustand LOW (nicht gesetzt) oder HIGH (gesetzt/aktiviert),
  • eine Aktivierungsrichtung (z.B. Pin < kann nur von links angestoßen werden).

Regeln:

  • Wenn die Schlange von der richtigen Richtung an einen LOW-Pin "anstößt", wird der Pin auf HIGH gesetzt.
  • In diesem Fall wird das Feld nicht betreten (Schlange bleibt auf der alten Position stehen).
  • Ist der Pin bereits HIGH oder die Richtung falsch, blockiert er wie eine Wand.
Selbstkollision und Ende
  • Wenn die Schlange in ihren eigenen Körper laufen würde: Game Over.
  • Wenn alle Pins HIGH sind: Gewonnen (oder nächstes Level).

Bearbeitung und Abgabe

  • Bearbeitung: Einzelbearbeitung
  • Abgabe Post Mortem im ILIAS: bis 18. Mai, 08:00 Uhr
  • Vorstellung im Praktikum: 18./20. Mai

Unless otherwise noted, this work is licensed under CC BY-SA 4.0.

Last modified: 9f2cf5c 2026-05-14 b03: add a checklist for the junit task