AutoFeedback API

Result c65ba3d8-7bc6-4fe1-b436-48b98989c23c

{
  "llm" : {
    "feedback" : "# Exercise: parking\n\n### Correctness\n- `GroupCard`: Für mehr als 20 Personen ist laut Aufgabe „nicht erlaubt“ – deine Implementation berechnet dafür aber weiterhin Kosten (weil `persons >= 11` auch für 21, 30, … gilt).\n- `GroupCard`: Für 11–20 Personen gilt 2.00 CHF pro Stunde; bei dir trifft diese Stufe bereits für `persons >= 11` zu, aber ohne die obere Grenze 20 zu berücksichtigen (dadurch ist auch der „nicht erlaubt“-Fall nicht umgesetzt).\n\n### Suggestion\n- Überlege dir, wie du im Konstruktor oder in `cost()` prüfen kannst, ob `persons > 20` ist, und wie du in so einem Fall reagieren willst (z.B. Ausnahme werfen), damit „nicht erlaubt“ wirklich durchgesetzt wird.\n- Formuliere die Tariflogik so, dass die Bereiche explizit sind (z.B. „bis 5“, „6–10“, „11–20“) und du damit automatisch auch erkennst, wann ein Wert außerhalb aller erlaubten Bereiche liegt.\n\n### Code Style\n- In `FlatRateCard` speicherst du `totalTime` und erhöhst es in `park()`, aber `cost()` ignoriert es komplett. Das ist verwirrend; entweder Zeit gar nicht speichern oder klar begründen, warum du sie trotzdem hältst.\n- In `GroupCard` ist `HOURLY_RATE` definiert, aber wird nie verwendet.\n- `persons` in `GroupCard` ist package-private (`int persons;`); mach es konsistent zu den anderen Feldern (typischerweise `private final`), damit die Klasse sauber gekapselt ist.\n\n\n# Exercise: labyrinth\n\n### Correctness\n- `TryStraightFirst` erfüllt die Aufgabenbeschreibung nicht: Du prüfst nicht explizit „links oder rechts“ (in dieser Reihenfolge/als Alternativen), sondern drehst zuerst nach rechts und nutzt `pathAhead()`; zudem fehlt der Fall „wenn weder vorne noch links noch rechts geht: rechtsum kehrt“ als klarer vierter Fall (bei dir wird zwar manchmal um 180° gedreht, aber nicht als „alles probiert, dann umkehren“ implementiert).\n- In `TryStraightFirst` wird nach einem erfolglosen Rechtsversuch die Figur am Ende nicht wieder in die Ausgangsrichtung zurückgedreht, bevor du „links probierst“ (du drehst `turnLeft(); turnLeft();` und startest damit effektiv in einer anderen Orientierung als zu Beginn des Schleifendurchlaufs).\n- `BacktrackingAlgorithm` kann den Zustand der Figur verändern, ohne anschließend konsistent wieder in den Ausgangszustand (Position *und* Richtung) zurückzukehren: Du drehst in jeder Iteration am Ende `turnLeft()`, und beim Backtracking drehst du zwar zurück, aber du stellst die ursprüngliche Blickrichtung nach dem rekursiven Versuch nicht wieder her. Das kann dazu führen, dass dein „4 Richtungen testen“-Loop nicht tatsächlich die vier gewünschten Richtungen testet.\n- `BacktrackingAlgorithm`: Dein „probeweiser Schritt“ zur Ermittlung des Offsets ist problematisch, weil er schon Teil der Navigation ist (inkl. Animation/Listener-Events) und du dabei kurzzeitig die Position änderst. Wenn dabei etwas schiefgeht (z.B. unerwartete Situation), kann das die Logik aus dem Tritt bringen. Außerdem ist das für Backtracking nicht gefordert und macht das Verhalten schwerer nachvollziehbar.\n- `BacktrackingAlgorithm`: `visited` speichert nur `row,col`. In einem Labyrinth kann es relevant sein, ob du dieselbe Zelle aus einer anderen Richtung betrittst (dein Algorithmus arbeitet richtungsabhängig durch Drehen). Durch das reine Positions-Visited kannst du Wege ausschließen, die mit anderer Orientierung noch sinnvoll wären.\n\n### Suggestion\n- Für `TryStraightFirst`: Formuliere den Schleifendurchlauf wirklich als 4 klar getrennte Fälle: (1) vorne, sonst (2) links, sonst (3) rechts, sonst (4) umkehren. Überlege dir dabei eine Strategie, wie du nach jedem „Test-Drehen“ die Orientierung wieder so setzt, dass der nächste Test wirklich relativ zur ursprünglichen Richtung ist.\n- Für `TryStraightFirst`: Nutze die vorgesehenen Abfragen `pathToTheLeft()` und `pathToTheRight()` direkt, dann musst du nicht über „drehen und pathAhead“ indirekt arbeiten und verlierst weniger leicht die Orientierung.\n- Für `BacktrackingAlgorithm`: Achte darauf, dass ein „Richtung testen“-Durchlauf am Ende wieder mit derselben Orientierung endet, mit der er begonnen hat (oder dass du sehr bewusst trackst, in welcher Richtung du gerade bist). Ein einfacher Check ist: Starte einen Loop, drehe/geh/tracke – und stelle sicher, dass du am Ende des Loop-Body wieder im Ausgangsdir bist, bevor die nächste Iteration startet.\n- Für `BacktrackingAlgorithm`: Überlege, ob du `visited` um die Richtung erweitern willst (z.B. als Tripel aus row/col/dir oder als Kante „von Zelle A nach Zelle B“). Das verhindert, dass du wegen einer früheren Sackgassen-Erfahrung eine Position komplett sperrst, obwohl ein anderer Eintrittswinkel noch eine neue Option eröffnet.\n- Für `BacktrackingAlgorithm`: Du brauchst die Offset-Ermittlung gar nicht, wenn du beim Backtracking einfach symmetrisch „hin und zurück“ arbeitest. Fokus auf: Entscheidung treffen → Schritt machen → rekursiv → wenn nicht erfolgreich: exakt inverse Bewegungsfolge, inkl. Blickrichtung.\n\n### Code Style\n- In `BacktrackingAlgorithm` ist `dirOffsets` als Feld mit `java.util.Map`/`java.util.HashMap` vollqualifiziert, während du oben schon `Set`/`HashSet` importierst. Einheitlich entweder imports verwenden oder vollqualifizieren.\n- `dirOffsets` wird als `Map<Integer, int[]>` benutzt; `int[]` ist hier wenig selbsterklärend. Ein kleiner eigener Typ/Record oder zumindest klare Benennung/Kommentar, was `[0]` und `[1]` bedeutet, würde die Lesbarkeit stark erhöhen.\n- Du hast viele Klassen (Figure, Labyrinth, GameOver, …) unverändert mitkopiert. Wenn nur deine eigenen Algorithmen bewertet werden sollen, ist das unnötig und macht den Diff schwer lesbar.\n\n\n# Exercise: swissmap\n\n### Correctness\n- In `SwissMapApp` ist die `main`-Methode als `void main()` deklariert; so wird sie normalerweise nicht als Programmeinstieg erkannt (üblich ist eine `public static ... main(String[] args)`-Signatur).\n- Du verwendest `gui.addComponents(cities)` / `gui.addComponents(mountains)` / `gui.addComponents(lakes)`; falls die verwendete `Gui`-Bibliothek diese Methode nicht anbietet (oder nur `addComponent(...)` erwartet), kompiliert das nicht bzw. die Objekte werden nicht registriert.\n- In `ModeButton.draw(...)` steht der Text `\"Sattelite View\"` (Schreibweise), aber fachlich wichtiger: Es ist nicht erkennbar, dass der Button im Hover-Zustand visuell reagiert bzw. eine Hover-Info anzeigt, obwohl er `Hoverable` implementiert (Aufgabe verlangt, dass er als Knopf angezeigt wird und Hoverable implementiert; typischerweise gehört dazu auch eine sichtbare Reaktion).\n\n### Suggestion\n- Prüfe die erwartete `main`-Signatur im Umfeld (wie wurden die anderen Aufgaben gestartet?) und passe sie so an, dass die JVM/IDE den Einstiegspunkt sicher findet.\n- Schau im API/IntelliSense der `Gui` nach, ob es wirklich `addComponents(...)` gibt; wenn nicht, registriere die Elemente über eine Schleife einzeln mit der Methode, die garantiert vorhanden ist.\n- Nutze den Hover-Zustand beim `ModeButton` ähnlich wie bei deinen `City/Lake/Mountain`: Merke dir `hovered` und ändere in `draw(...)` z. B. Farbe/Rahmen/Text, damit `Hoverable` tatsächlich einen Effekt hat.\n\n### Code Style\n- Verwende konsistente Bezeichner: `SwissMap Karte` ist gemischt deutsch/englisch und beginnt groß wie ein Typ; üblicher ist ein klein geschriebener Variablenname (z. B. `map`/`swissMap`) für bessere Lesbarkeit.\n- In `ModeButton` sind `onMouseEnter()` und `onMouseExit()` leer; wenn du `Hoverable` implementierst, ist es sauberer, entweder den Hover-Zustand wirklich zu verwenden oder (falls erlaubt) das Interface nicht zu implementieren.\n- Du nutzt mehrfach vollqualifizierte Klassennamen wie `new ch.trick17.gui.component.Rectangle(...)`; importiere `Rectangle` einmal, dann wird der Code deutlich lesbarer.\n\n\n# Exercise: visualizer\n\n### Correctness\n- In `VisualizerApp` ist die `main`-Methode nicht als Java-Entry-Point deklariert (sie ist weder `public static void main(String[] args)` noch wird sie sonst irgendwo aufgerufen); so startet das Programm typischerweise nicht wie gefordert.\n- Beim Prozessor-Datensatz soll die logarithmische y-Achse vom Visualizer umgesetzt werden; in deinem Ansatz loggst du stattdessen schon in `Processor.y()`. Das entspricht nicht der Aufgabenbeschreibung („Visualizer: logarithmische y‑Achse verwenden“) und verändert zudem, was in Min/Max und Hover als „Wert“ gilt.\n- Die Prozessor-Detailbeschreibung soll die „effektive Rechengeschwindigkeit“ (clock rate * cores) thematisieren; in deiner `description()` zeigst du zwar clock rate und cores separat, aber nicht den geforderten kombinierten Wert.\n\n### Suggestion\n- Schau dir die Methodensignatur an, die Java als Startpunkt erwartet, und passe `VisualizerApp` so an, dass die Applikation wirklich über die `main`-Methode gestartet werden kann.\n- Lass `Processor.y()` eher den *nicht-logarithmierten* Wert für die effektive Geschwindigkeit liefern und überlege dann, an welcher Stelle im `Visualizer` die Skalierung (logarithmisch) stattfinden müsste, damit weiterhin „echte“ Werte in DataPoints stecken, aber die Darstellung trotzdem log-skaliert ist.\n- Ergänze im Hover-Text der Prozessoren eine Zeile, die den kombinierten Speed-Wert (aus den vorhandenen Feldern berechnet) ausgibt, damit die Anforderung „effektive Rechengeschwindigkeit“ auch in der Detailansicht sichtbar ist.\n\n### Code Style\n- In `Visualizer` sind `DUMMY_DOUBLE` und `DUMMY_STRING` jetzt unbenutzt; wenn du sie nicht mehr brauchst, entfernen, damit keine „Altlasten“ stehen bleiben.\n- In `Processor.description()` verwendest du einmal `String.format(Locale.US, ...)` und sonst nicht; entscheide dich konsistent für/gegen eine Locale (oder kommentiere kurz, warum nur dort).\n",
    "status" : "SUCCESS"
  }
}