Files

10 KiB
Raw Permalink Blame History

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.