Document solver roadmap in README
This commit is contained in:
+224
@@ -0,0 +1,224 @@
|
||||
# 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.
|
||||
Reference in New Issue
Block a user