{
"llm" : {
"feedback" : "# Exercise: parking\n\n### Correctness\n- In `FlatRateCard` erfüllst du die Anforderung „fixe Monatskosten von 150 CHF“ grundsätzlich, aber deine Klasse sammelt trotzdem Parkzeit (`totalTime`) und lässt `park(...)` diese verändern; das widerspricht dem Konzept einer Flatrate (Parkzeit sollte für die Kosten keine Rolle spielen).\n- Die Ausgabe soll laut Aufgabenstellung beim Ausführen einen **Gesamtumsatz von 156.75 CHF** anzeigen; mit deinem aktuellen Beispielablauf und deinen Tarifen ergibt sich ein anderer Wert (u.a. weil die `FlatRateCard` immer 150 CHF beiträgt).\n\n### Suggestion\n- Überlege dir bei der `FlatRateCard`, welche Methoden wirklich einen Einfluss haben müssen: Wenn die Kosten immer fix sind, was sollte dann `park(...)` überhaupt tun und was bedeutet `reset()` in diesem Kontext?\n- Rechne den erwarteten Gesamtumsatz aus den im Example gefahrenen Minuten und den Tarifen deiner Karten nach und vergleiche ihn mit den geforderten 156.75 CHF. Prüfe dann, welche Annahme im Modell (Tarif/Zeiteinfluss/Beispielszenario) angepasst werden muss, damit genau dieser Wert herauskommt.\n\n### Code Style\n- `FlatRateCard` hat mit `totalTime` einen Zustand, der für die Kosten nicht verwendet wird; das macht die Klasse unnötig komplex und verwirrend.\n- `HOURLY_RATE` in `GroupCard` ist als `final` okay, aber die Konstante wird nicht wie eine Konstante benannt/konzipiert (sie hängt vom Konstruktorparameter ab). Ein neutralerer Name (z.B. „rate“) wäre verständlicher.\n\n\n# Exercise: labyrinth\n\n### Correctness\n- `TryStraightFirst` erfüllt die Aufgabenbeschreibung nicht: Du brichst die Schleife ab, sobald `pathAhead()` false ist (`while (... && figure.pathAhead())`), obwohl der Algorithmus dann erst links/rechts/kehrt machen soll, um weiterzusuchen.\n- `TryStraightFirst` macht keinen „rechtsum kehrt“, wenn vorne/links/rechts alles blockiert ist (gefordert: umdrehen).\n- `TryStraightFirst` versucht links und rechts nicht in der geforderten Priorität „geradeaus, sonst links oder rechts“: deine Bedingungen erlauben z.B. nur rechts, wenn **nicht** links möglich ist, statt „sonst links, sonst rechts (oder umgekehrt), sonst umdrehen“.\n- `TryStraightFirst` bewegt sich in manchen Fällen nicht weiter, obwohl eine Seitwärtsoption existiert: Du drehst zwar ggf., aber machst danach im selben Schleifendurchlauf keinen `moveForward()`, und wegen deiner `while`-Bedingung kann es dann sogar direkt stoppen.\n- `BacktrackingAlgorithm`: Dein Backtracking kann in Zyklen/Endlosschleifen geraten, weil du keine „besuchten“ Zustände/Entscheidungen speicherst. In Labyrinthen mit Schleifen kann reine Rekursion ohne Markierung immer wieder dieselben Wege ausprobieren.\n- `BacktrackingAlgorithm`: Beim Rückgängigmachen der Links-Verzweigung stellst du die Orientierung nicht sauber wieder her (du gehst zurück und machst dann nur ein `turnLeft()` statt die ursprüngliche Richtung wiederherzustellen). Dadurch ist der Zustand nach dem Fehlschlag nicht garantiert derselbe wie vor dem Abbiegen.\n- `BacktrackingAlgorithm`: Du prüfst und gehst „ahead“, dann „left“, dann „right“ unabhängig voneinander im selben Knoten. Nach einem erfolglosen „ahead“-Versuch hast du zwar versucht zurückzugehen, aber wegen möglicher Orientierungs-/Zustandsabweichungen können die folgenden Checks nicht mehr dem ursprünglichen Abzweigpunkt entsprechen.\n\n### Suggestion\n- Für `TryStraightFirst`: Lass die Schleife nur vom Ziel abhängen (oder zumindest nicht von `pathAhead()`), und entscheide innerhalb eines Durchlaufs per `if/else if/else` den nächsten Schritt (vorwärts vs. drehen/umdrehen).\n- Für `TryStraightFirst`: Implementiere explizit den Fall „nichts geht“ (ahead/left/right alle false) und überlege, welche minimale Drehsequenz dafür nötig ist.\n- Für `TryStraightFirst`: Wenn du dich drehst, überlege, ob du im gleichen Schleifendurchlauf auch wirklich einen Schritt machen willst (und dass die Schleifenbedingung dich nicht vorher rauswirft).\n- Für `BacktrackingAlgorithm`: Überlege dir eine Strategie, wie du bereits besuchte Positionen (evtl. inkl. Blickrichtung) markierst, damit du in Schleifen nicht ewig erneut explorierst.\n- Für `BacktrackingAlgorithm`: Achte darauf, dass du nach einem rekursiven Versuch den Zustand exakt wiederherstellst (Position **und** Richtung). Hilfreich ist, dir vor dem Abzweig die Richtung zu merken und nach dem Zurückgehen so lange zu drehen, bis sie wieder stimmt.\n- Für `BacktrackingAlgorithm`: Wenn du mehrere Optionen (ahead/left/right) ausprobieren willst, ist es oft einfacher, sie als „Kandidaten“ nacheinander zu testen, aber dabei sicherzustellen, dass jeder Test vom identischen Ausgangszustand startet.\n\n### Code Style\n- In `TryStraightFirst` sind die Bedingungen unnötig komplex und wiederholen `!figure.pathAhead()` mehrfach; eine klar strukturierte `if / else if / else`-Kette wäre deutlich lesbarer.\n- In `BacktrackingAlgorithm` sollten Hilfsmethoden wie `navigateRec` und `turnAround` tendenziell `private` sein, da sie nur intern verwendet werden.\n- Du hast sehr viel Template-Code (Figure/Labyrinth/LabyrinthGame/etc.) im Attempt mitkopiert; für die Abgabe sind meist nur die neu erstellten/angepassten Klassen relevant (je nach Vorgabe der Übung).\n\n\n# Exercise: swissmap\n\n### Correctness\n- `SwissMapApp` hat eine Methode `void main()` statt der geforderten Java-Entry-Point-Signatur `public static void main(String[] args)`; so wird das Programm je nach Umgebung nicht starten.\n- In `Mountain.draw(...)` verwendest du `gui.drawImage(...)` (oben links positioniert), während du bei `City`/`Lake` `drawImageCentered(...)` nutzt; dadurch liegt der Berg nicht am vorgesehenen Koordinatenpunkt (er ist um die Bildbreite/-höhe verschoben).\n- Die interaktiven Bereiche (`getInteractiveArea`) sind bei City/Lake/Mountain fix `20x20` Pixel und skalieren nicht mit, obwohl du beim Zeichnen teils unterschiedliche/skalierte Marker-Grössen verwendest (z.B. City 0.03/0.05, Lake/Mountain 0.3). Dadurch “trifft” Hover nicht zuverlässig die sichtbare Grafik.\n\n### Suggestion\n- Schau dir an, welche `main`-Signatur Java als Startpunkt wirklich erwartet, und passe die Methode in `SwissMapApp` entsprechend an.\n- Überlege bei `Mountain`, ob du – analog zu den anderen Klassen – ebenfalls zentriert zeichnen willst, oder ob du die Koordinaten so umrechnest, dass das Bild trotz “top-left drawing” am Markerzentrum liegt.\n- Leite die Breite/Höhe deines `Rectangle` in `getInteractiveArea(...)` aus der tatsächlich gezeichneten Darstellung ab (inkl. Skalierung und “hovered”-Variante), damit der Hover-Bereich zur sichtbaren Grösse passt.\n\n### Code Style\n- In `ModeButton` ist `name` eigentlich ein Label (Text) und nicht “Name” des Objekts; eine präzisere Bezeichnung würde das Lesen erleichtern.\n- `ModeButton` implementiert `Hoverable`, aber `onMouseEnter/Exit` sind leer; entweder Hover-Effekt implementieren oder das Interface weglassen, falls nicht gebraucht.\n- Das `enum Mode` steht als Top-Level-Typ in derselben Datei wie `ModeButton`; üblich ist entweder als `private enum` innerhalb der Klasse oder in eine eigene Datei auszulagern, damit die Datei-Struktur klar bleibt.\n\n\n# Exercise: visualizer\n\n### Correctness\n- In `VisualizerApp` ist die `main`-Methode nicht als Java-Programmeinstiegspunkt definiert (Signatur/`static` fehlt), dadurch startet das Programm so nicht wie erwartet.\n- Beim Prozessor-Datensatz soll die *effektive Rechengeschwindigkeit* zwar als `clockRate * cores` verwendet werden, aber die Aufgabe verlangt zusätzlich, dass dafür eine logarithmische **y-Achse im Visualizer** verwendet wird; bei dir steckt die Logarithmierung direkt in `Processor.y()`, womit du statt „logarithmischer Achse“ eigentlich „logarithmierte Daten“ lieferst.\n- `Processor.getTrueClockRate()` erfüllt die Einheit-Vorgabe nicht vollständig: kHz-Werte sollten als kHz angezeigt werden, MHz als ganze Zahl, GHz als Kommazahl; bei dir fehlen teils Einheiten/Formatierung (z. B. kHz-Fall ohne „kHz“, GHz ohne definierte Dezimaldarstellung).\n- `Movie.group()` ist konstant `\"Movie\"`, dadurch gibt es bei Filmen keine Gruppierung/Farbaufteilung wie in den Screenshots (dort sind Filme nach einem Merkmal in Gruppen eingefärbt, nicht alle gleich).\n\n### Suggestion\n- Schau dir die korrekte Java-`main`-Signatur an, die von der JVM automatisch gefunden wird, und passe deine Methode entsprechend an.\n- Überleg dir, was „logarithmische y-Achse“ bedeutet: Wo sollte die Transformation stattfinden – in den Datenpunkten oder in der Abbildung `guiY(...)`/Skalierung im Visualizer? Prüfe, wie sich das auf Min/Max und die Anzeige der Details auswirkt.\n- Implementiere die Taktfrequenz-Formatierung regelbasiert nach Größenordnung (kHz/MHz/GHz) und achte darauf, dass der String in allen Fällen die Einheit enthält und GHz nicht als lange Double-Kette ausgegeben wird.\n- Überleg dir für Filme ein Gruppierungsmerkmal, das mehrere Gruppen ergibt (wie in der Legende gezeigt), und gib dieses über `group()` zurück, statt einen konstanten Text zu verwenden.\n\n### Code Style\n- In `Visualizer` ist `import javax.xml.crypto.Data;` unbenutzt und sollte entfernt werden.\n- In `DataPoint` verwendest du Block-Kommentare `/* ... */` statt der geforderten Javadoc-Kommentare `/** ... */` (wichtig, damit es als API-Doku erkannt wird).\n- Methodenamen wie `x()`, `y()`, `name()` sind ok, aber achte bei Detail-Strings auf konsistente Formatierung (Zeilenumbrüche/Leerzeichen, keine doppelte Wiederholung wie `name()` + Title nochmal) und gut lesbare Zahlenformate.\n",
"status" : "SUCCESS"
}
}