Files

225 lines
10 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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) ✅
Abgeschlossen am 10. September 2026.
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) ✅
Abgeschlossen am 10. September 2026.
- `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.
- die fest codierte 9x9-Darstellung durch eine allgemeine Darstellung ersetzen
und `StringNotesForNumber` implementieren.
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) ✅
Abgeschlossen am 10. September 2026.
- 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, error)` durch eine aussagekräftige Schritt-API ersetzen, zum Beispiel
mit den Zuständen `Progress`, `Solved`, `Stuck`, `Invalid` und `Failed`.
- Strategie-Reihenfolge, Wiederholungspunkt und `ApplyNext`/`ApplyAll` eindeutig
definieren.
- Tippfehler in öffentlichen Namen (`InitStragies`, `TriggerdBy`) kontrolliert
migrieren und alle Aufrufer anpassen.
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. ein gemeinsames Solver-Interface und aussagekräftige Schrittzustände
entwerfen.
2. Strategie-Reihenfolge sowie `ApplyNext` und `ApplyAll` als öffentlichen
Vertrag festlegen und testen.
3. `InitStragies` und `TriggerdBy` kontrolliert auf korrekt geschriebene Namen
migrieren.
4. End-to-End-Tests für mehrere einfache und mittlere Puzzle-Bank-Rätsel
ergänzen.
5. anschließend `NakedPair`, `NakedTriple`, `HiddenPair` und `HiddenTriple`
implementieren.
Nach jedem Arbeitspaket müssen `gofmt`, `go test ./...` und `go vet ./...`
erfolgreich sein. Neue bekannte Baseline-Fehler sollen nicht angesammelt werden.