# Entwicklungsfahrplan Dieser Fahrplan führt das Projekt vom aktuellen Prototyp zu einem verlässlichen, erklärbaren Sudoku-Löser. Die Reihenfolge ist absichtlich abhängigkeitsorientiert: Neue Strategien bauen erst dann auf dem Solver auf, wenn Feldmodell, Änderungen und Fortschrittserkennung korrekt und getestet sind. ## Zielbild Das erste stabile Release soll: - klassische 9x9-Sudokus sicher einlesen und validieren, - jeden Lösungsschritt deterministisch und nachvollziehbar protokollieren, - einfache und mittlere Rätsel mit menschlichen Strategien lösen, - bei Stillstand einen klaren Status statt eines Panic oder Endloslaufs liefern, - über eine kleine CLI mit Datei, Standard-Eingabe oder direkter Rätselzeichenfolge nutzbar sein und - durch Unit-, Integrations- und Regressionstests abgesichert sein. Backtracking, DLX und sehr fortgeschrittene menschliche Strategien folgen auf dieses Kern-Release. ## Phase 0 – Lauffähige und getestete Basis (P0) Zuerst wird der bestehende Zustand stabilisiert. In dieser Phase werden keine neuen Lösungsstrategien ergänzt. - Test-Helfer für kleine Felder und 9x9-Rätsel anlegen. - Regressionstests für die aktuell bekannten Abstürze und Logikfehler schreiben. - `Field.ForEachCell` so korrigieren, dass echte Zellen statt Kopien übergeben werden. - `Field.GetCell` gegen negative Indizes und `row == Rows` beziehungsweise `column == Columns` absichern. - die Zahlenausgabe in `Field.String` ohne fehlerhafte int-zu-string-Konvertierung implementieren. - doppelte oder widersprüchliche Änderungen aus überlappenden Zeilen, Spalten und Blöcken verhindern; damit auch den Nil-Panic in `LastDigit` beseitigen. - die beiden Slice-Iterationsfehler in `HiddenSingle` korrigieren: Kandidatenwerte statt Indizes auswerten. - in `Cell.RemoveNumber` die korrekte Aktion `ActionRemoveNumber` protokollieren. - Nil-Eingaben bei Feld, Zelle, Position und Änderung kontrolliert als Fehler behandeln. - Solver-Fortschritt so erkennen, dass ein Schritt weder fälschlich Stillstand meldet noch endlos wiederholt wird. Abgeschlossen, wenn: - `go test ./...` und `go vet ./...` erfolgreich sind, - `go run .` das ausgewählte Beispiel ohne Panic beendet und - die bekannten Fehler jeweils einen Regressionstest besitzen. ## Phase 1 – Verlässliches Feldmodell (P0) - `field.Properties` beim Erzeugen prüfen: positive Dimensionen, passende Blockaufteilung und exakt passende Zellmatrix. - Zahlenbereich und Position jeder Zelle prüfen; leere Zellen bleiben als `0` repräsentiert. - `Part.IsSolved` für Zeilen, Spalten und Blöcke implementieren. - `Field.IsValid` implementieren: keine Duplikate, nur erlaubte Werte und konsistente Dimensionen. - `Field.IsSolved` an Vollständigkeit **und** Validität koppeln. - Kandidaten-Invarianten festlegen: sortiert, eindeutig, im gültigen Bereich und niemals an bereits belegten Zellen. - Änderungen atomar anwenden und validieren. Ungültige Änderungen sollen einen Fehler zurückgeben und das Feld unverändert lassen. - lesenden Zugriff auf Eigenschaften und Änderungshistorie anbieten, ohne interne Slices veränderbar nach außen zu geben. - allgemeine und 9x9-spezifische Darstellung trennen; `StringNotesForNumber` implementieren oder bis zu einem echten Bedarf aus der API entfernen. Abgeschlossen, wenn gültige, ungültige, unvollständige und gelöste Felder in Tabellentests eindeutig unterschieden werden und keine Mutation die Feld-Invarianten umgehen kann. ## Phase 2 – Robuste Parser- und Game-API (P0) - Parserfehler vereinheitlichen und mit Zeilennummer sowie fehlerhaftem Feld anreichern. - Puzzle-Bank-Datensätze strikt prüfen: Hash, 81 Ziffern, Rating, Whitespace, LF/CRLF und leere Zeilen. - bei einem Parse-Fehler keine teilweise eingelesene Ergebnisliste übernehmen; wiederholte `Parse`-Aufrufe dürfen alte Ergebnisse nicht ungewollt anhängen. - `GetField` so ändern, dass ein ungültiger Index einen Fehler liefert statt eines leeren, später abstürzenden Felds. - die fest kodierte Auswahl `GetField(2)` aus `sudoku.New` entfernen. Das ausgewählte Feld soll explizit übergeben oder vom Aufrufer gewählt werden. - zusätzlich einen einfachen Parser für eine 81-stellige Rätselzeichenfolge bereitstellen; er eignet sich für CLI, Tests und externe Nutzung. - die Ausgangsbelegung bereits beim Erzeugen eines `Game` validieren. Abgeschlossen, wenn fehlerhafte Eingaben ohne Panic verständliche Fehler liefern und Parser sowie `Game` keine implizite Rätselauswahl mehr enthalten. ## Phase 3 – Klare Solver-Architektur (P0/P1) - ein Solver-Interface definieren, das später menschlichen Solver, Backtracking und DLX austauschbar macht. - `Run(int) bool` durch eine aussagekräftige Schritt-API ersetzen, zum Beispiel mit den Zuständen `Progress`, `Solved`, `Stuck`, `Invalid` und `Failed`. - Konfiguration aus den ungenutzten `conf`-Feldern ableiten oder diese entfernen. - Strategie-Reihenfolge, Wiederholungspunkt und `ApplyNext`/`ApplyAll` eindeutig definieren. - gefundene Änderungen vor dem Anwenden deduplizieren und auf Konflikte prüfen. - Kandidaten nach jedem Zahlenschritt korrekt und deterministisch aktualisieren. - Tippfehler in öffentlichen Namen (`InitStragies`, `TriggerdBy`) kontrolliert migrieren und alle Aufrufer anpassen. - Abbruch bei Stillstand, ungültigem Zustand und internem Fehler sauber durch `sudoku.Game.Solve` reichen. Abgeschlossen, wenn derselbe Input stets dieselben Schritte erzeugt und jeder Solverlauf genau einen überprüfbaren Endzustand besitzt. ## Phase 4 – Menschlicher Basis-Solver (P1) Die Strategien werden in aufsteigender Komplexität implementiert. Jede Strategie benötigt positive, negative und Konflikt-/Überlappungstests sowie mindestens ein komplettes Beispielrätsel. 1. Kandidaten erzeugen und pflegen (`Notes`) 2. `LastDigit` 3. `NakedSingle` 4. `HiddenSingle` 5. `NakedPair` und `NakedTriple` 6. `HiddenPair` und `HiddenTriple` 7. `LockedCandidateT1`, `LockedCandidateT2` und `LockedPair` Abgeschlossen, wenn die mitgelieferten einfachen und mittleren Beispieldaten ohne Raten lösbar sind und jeder Schritt seine auslösende Strategie nennt. ## Phase 5 – Erklärbarer Lösungsweg und Undo (P1) - Änderungen zu fachlichen Schritten gruppieren: eine Schlussfolgerung kann aus einer gesetzten Zahl und mehreren entfernten Kandidaten bestehen. - `GetSolutionPath` mit defensiven Kopien implementieren. - pro Schritt Strategie, betroffene Zellen, alter/neuer Wert, Begründung und optionale Markierungen speichern. - `Mark` vollständig von außen lesbar und unabhängig von internen `Change`-Zeigern gestalten. - Undo/Redo auf Basis atomarer Schritte implementieren; `prevSolveStep` entweder fertigstellen oder bis dahin entfernen. - menschenlesbare Textausgabe und ein stabiles JSON-Format für Lösungswege ergänzen. Abgeschlossen, wenn ein gelöstes Feld vollständig zum Ausgangszustand zurückgesetzt und durch Wiederanwenden desselben Pfads identisch rekonstruiert werden kann. ## Phase 6 – Fortgeschrittene Strategien (P2) Erst nach stabiler Schritt- und Markierungslogik ergänzen: 1. `XWing` 2. `XYWing`, `XYZWing`, `WXYZWingBasic` 3. `Turbot2StringKite` und `TurbotSkyscraper` 4. `SimpleColoringT1` 5. `EmptyRectangle` 6. `UniqueRectangleT1`, `UniqueRectangleT4`, `UniqueRectangleT7` 7. `XChain`, `XYChain`, `XChainLoop`, `XYChainLoop` 8. `CRP`, nachdem die genaue fachliche Bedeutung und Akzeptanzkriterien dokumentiert wurden Für jede Technik wird zuerst ein isoliertes Testmuster festgelegt. Ein leerer Typ ohne Verhalten gilt nicht als implementierte Strategie. ## Phase 7 – Vollständige algorithmische Solver (P2) - Backtracking-Solver mit Minimum-Remaining-Values-Heuristik implementieren. - optional einen DLX-/Algorithm-X-Solver ergänzen. - Eindeutigkeit einer Lösung prüfen und die Fälle keine, genau eine oder mehrere Lösungen unterscheiden. - algorithmische Solver als Referenz in Tests verwenden, um Ergebnisse des menschlichen Solvers zu validieren. - explizit konfigurieren, ob ein algorithmischer Solver nur prüft, als Fallback dient oder direkt löst. Abgeschlossen, wenn alle gültigen klassischen 9x9-Rätsel entweder gelöst oder eindeutig als unlösbar/mehrdeutig klassifiziert werden. ## Phase 8 – Kommandozeile und Bedienbarkeit (P2) - Flags für Datei, Puzzle-Index, direkte Zeichenfolge und Standard-Eingabe hinzufügen. - Solverart und zugelassene Strategien auswählbar machen. - Ausgabeoptionen für Ausgangsfeld, Endfeld, Einzelschritte und JSON anbieten. - konsistente Exit-Codes für Eingabefehler, ungültige Rätsel, Stillstand und erfolgreiche Lösung definieren. - Bibliothekspakete frei von direkter Konsolenausgabe halten; strukturiertes, optionales Logging nur an den Anwendungsgrenzen einführen. - große Puzzle-Bank-Dateien streamen, wenn nur ein Datensatz benötigt wird. Abgeschlossen, wenn das Programm ohne Quellcodeänderung mit eigenen Rätseln verwendet werden kann. ## Phase 9 – Qualität, Performance und Release (P2/P3) - Fuzz-Tests für Parser, Koordinatenzugriffe und Änderungsanwendung ergänzen. - Integrationssuite über repräsentative einfache, mittlere, schwere, ungültige und mehrdeutige Rätsel aufbauen. - `go test -race ./...` in den Standardprüfungen aufnehmen. - Benchmarks für Kandidatenberechnung, Strategie-Suche und vollständige Solver hinzufügen; erst danach gezielt optimieren. - CI für Formatierung, Tests, Vet und Race Detector einrichten. - öffentliche APIs mit GoDoc dokumentieren und Beispiele ergänzen. - README nach Stabilisierung von den Warnungen befreien, Versionsschema und Changelog festlegen und ein erstes Release markieren. ## Empfohlene nächste Arbeitspakete Diese Tickets bilden die kürzeste Route zu einem stabilen Zwischenstand: 1. Test-Helfer und Feldzugriffs-Tests erstellen. 2. `ForEachCell`, `GetCell` und `Field.String` korrigieren. 3. Change-Aktionen sowie Nil- und Werteprüfung absichern. 4. `LastDigit` deduplizieren und den bekannten Panic per Regressionstest beseitigen. 5. `HiddenSingle` korrigieren und vollständig testen. 6. `Part.IsSolved`, `Field.IsValid` und `Field.IsSolved` implementieren. 7. Puzzle-Bank-Parser atomar und indexsicher machen. 8. Solver-Schrittergebnis und Konflikterkennung einführen. 9. die vier Basisstrategien durch End-to-End-Rätseltests absichern. 10. erst danach Paar-/Tripel-Strategien oder neue Bedienfunktionen beginnen. Nach jedem Arbeitspaket müssen `gofmt`, `go test ./...` und `go vet ./...` erfolgreich sein. Neue bekannte Baseline-Fehler sollen nicht angesammelt werden.