10 KiB
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.ForEachCellso korrigieren, dass echte Zellen statt Kopien übergeben werden.Field.GetCellgegen negative Indizes undrow == Rowsbeziehungsweisecolumn == Columnsabsichern.- die Zahlenausgabe in
Field.Stringohne 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
LastDigitbeseitigen. - die beiden Slice-Iterationsfehler in
HiddenSinglekorrigieren: Kandidatenwerte statt Indizes auswerten. - in
Cell.RemoveNumberdie korrekte AktionActionRemoveNumberprotokollieren. - 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 ./...undgo 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.Propertiesbeim Erzeugen prüfen: positive Dimensionen, passende Blockaufteilung und exakt passende Zellmatrix.- Zahlenbereich und Position jeder Zelle prüfen; leere Zellen bleiben als
0repräsentiert. Part.IsSolvedfür Zeilen, Spalten und Blöcke implementieren.Field.IsValidimplementieren: keine Duplikate, nur erlaubte Werte und konsistente Dimensionen.Field.IsSolvedan 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;
StringNotesForNumberimplementieren 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. GetFieldso ändern, dass ein ungültiger Index einen Fehler liefert statt eines leeren, später abstürzenden Felds.- die fest kodierte Auswahl
GetField(2)aussudoku.Newentfernen. 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
Gamevalidieren.
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) booldurch eine aussagekräftige Schritt-API ersetzen, zum Beispiel mit den ZuständenProgress,Solved,Stuck,InvalidundFailed.- Konfiguration aus den ungenutzten
conf-Feldern ableiten oder diese entfernen. - Strategie-Reihenfolge, Wiederholungspunkt und
ApplyNext/ApplyAlleindeutig 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.Solvereichen.
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.
- Kandidaten erzeugen und pflegen (
Notes) LastDigitNakedSingleHiddenSingleNakedPairundNakedTripleHiddenPairundHiddenTripleLockedCandidateT1,LockedCandidateT2undLockedPair
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.
GetSolutionPathmit defensiven Kopien implementieren.- pro Schritt Strategie, betroffene Zellen, alter/neuer Wert, Begründung und optionale Markierungen speichern.
Markvollständig von außen lesbar und unabhängig von internenChange-Zeigern gestalten.- Undo/Redo auf Basis atomarer Schritte implementieren;
prevSolveStepentweder 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:
XWingXYWing,XYZWing,WXYZWingBasicTurbot2StringKiteundTurbotSkyscraperSimpleColoringT1EmptyRectangleUniqueRectangleT1,UniqueRectangleT4,UniqueRectangleT7XChain,XYChain,XChainLoop,XYChainLoopCRP, 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:
- Test-Helfer und Feldzugriffs-Tests erstellen.
ForEachCell,GetCellundField.Stringkorrigieren.- Change-Aktionen sowie Nil- und Werteprüfung absichern.
LastDigitdeduplizieren und den bekannten Panic per Regressionstest beseitigen.HiddenSinglekorrigieren und vollständig testen.Part.IsSolved,Field.IsValidundField.IsSolvedimplementieren.- Puzzle-Bank-Parser atomar und indexsicher machen.
- Solver-Schrittergebnis und Konflikterkennung einführen.
- die vier Basisstrategien durch End-to-End-Rätseltests absichern.
- 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.