Files
Jander_Semester2/Semesterprojekt/docs/data-structures.md
Jean-Luc Makiola 83643a192f semesterprojekt: implement full text adventure (phases 1-7)
Walking skeleton through Swing GUI: YAML-driven world (4 rooms,
4 items, 1 NPC), HashMap command dispatch with parser, three-tier
item hierarchy (readable / switchable / plain), and end-to-end
NPC give/receive flow. 67 tests green.
2026-05-25 21:37:59 +02:00

3.1 KiB

Datenstrukturen

Bewusste Wahl jeder Collection — der Dozent bewertet das laut Aufgabenstellung explizit.

Übersicht

Verwendung Struktur Komplexität Lookup
Ausgänge eines Raums EnumMap<Direction, Room> O(1)
Alle Räume der Welt HashMap<String, Room> O(1)
Item-Registry (global) HashMap<String, Item> O(1)
NPC-Registry (global) HashMap<String, Npc> O(1)
Items in einem Raum LinkedHashMap<String, Item> O(1)
NPCs in einem Raum LinkedHashMap<String, Npc> O(1)
Spieler-Inventar LinkedHashMap<String, Item> O(1)
Befehlsregistry HashMap<String, Command> O(1)
NPC-Reaktionen HashMap<String, NpcReaction> O(1)
Eingabehistorie (optional) ArrayDeque<String> O(1) Front/Back

Begründungen im Detail

EnumMap<Direction, Room> für Raum-Ausgänge

  • Direction ist Enum (NORTH, SOUTH, EAST, WEST, evtl. UP, DOWN)
  • EnumMap ist array-backed, kein Hashing nötig → schneller und kompakter als HashMap
  • Iteration in Enum-Deklarationsreihenfolge (stabil)

HashMap<String, Room> für die Welt

  • Lookup über id beim Auflösen von Exits
  • Reihenfolge irrelevant (keine Anzeige der gesamten Welt)
  • Standardwahl wenn nur Lookup gebraucht wird

LinkedHashMap<String, Item> für Inventar & Raum-Items

Zwei Anforderungen gleichzeitig:

  1. O(1) Lookup beim take letter / read letter
  2. Stabile Anzeigereihenfolge beim inventory

Eine plain HashMap würde Punkt 2 verletzen (Items springen scheinbar zufällig zwischen Ausgaben). Eine ArrayList<Item> würde Punkt 1 auf O(n) drücken und Duplikat-Prüfung verlangen.

Entscheidung "keine Stapel" (1 Item pro id) macht das Map-basierte Modell sauber.

HashMap<String, Command> für Befehle

  • O(1)-Dispatch
  • Aliase durch Mehrfach-Registrierung (put("go", goCmd); put("move", goCmd);)
  • Entspricht dem expliziten Tipp aus der Aufgabenstellung
  • Vermeidet wachsendes switch-Statement

ArrayDeque<String> für Historie (optional)

  • Falls Up-Arrow in der GUI gewünscht oder Befehlsverlauf
  • ArrayDeque ist LinkedList praktisch immer überlegen (bessere Cache-Lokalität, weniger Overhead)
  • Beidseitige O(1)-Operationen

Bewusst NICHT gewählt

Struktur Warum nicht
ArrayList<Item> für Inventar O(n)-Lookup, Duplikat-Handling nötig
HashMap<String, Item> für Inventar Anzeige-Reihenfolge instabil
TreeMap irgendwo Keine sortierte Iteration nötig, O(log n) ohne Nutzen
LinkedList ArrayDeque ist fast immer besser
Vector / Hashtable Legacy, synchronisiert (nicht gebraucht), langsamer
Map<String, String> für Exits in Domain Direction sollte Enum sein, nicht String

Threading

Single-threaded: Game-Loop liest, dispatcht, schreibt — keine parallelen Mutationen.

Ausnahme: Bei Swing-GUI läuft Input über den Event-Dispatch-Thread, der Game-Loop in einem Worker-Thread. Hier kommt BlockingQueue<String> (ArrayBlockingQueue reicht) als Brücke ins Spiel — siehe architecture.md.