4.1 KiB
Sudoku
Ein in Go geschriebener Sudoku-Löser, der Rätsel mit nachvollziehbaren, menschlichen Lösungsstrategien bearbeiten soll. Neben dem gelösten Feld soll langfristig auch der Lösungsweg mit Kandidaten, Änderungen und Markierungen verfügbar sein.
Warning
Das Projekt befindet sich in einer frühen Entwicklungsphase. Der aktuelle Prüflauf ist wegen eines Vet-Fehlers noch nicht grün und die Demo kann während des Lösens abstürzen. Siehe Bekannte Einschränkungen.
Voraussetzungen
- Go 1.25.10 oder neuer (siehe
go.mod) - keine externen Go-Abhängigkeiten
Ausführen
Die Demo in main.go liest derzeit fest das dritte Rätsel aus
data/sudoku-exchange-puzzle-bank/easy3.txt, zeigt das Ausgangsfeld an und
startet anschließend den Solver:
go run .
Der Pfad und die Rätselauswahl sind momentan noch nicht über Kommandozeilenargumente konfigurierbar.
Entwicklung
Alle Pakete bauen und testen:
go test ./...
Code formatieren und statisch prüfen:
gofmt -w main.go field/*.go parser/*.go logic/*.go logic/strategies/*.go sudoku/*.go
go vet ./...
Aktuell gibt es noch keine automatisierten Tests. Neue Funktionalität sollte
nach Möglichkeit mit paketnahen *_test.go-Tests ergänzt werden.
Architektur
| Pfad | Aufgabe |
|---|---|
main.go |
Kleine Demo und Zusammenbau von Parser, Solver und Strategien |
field/ |
Spielfeld, Zellen, Positionen, Zeilen, Spalten, Blöcke, Kandidaten und Änderungsprotokoll |
parser/ |
Parser-Schnittstelle und Import des Sudoku-Exchange-Puzzle-Bank-Formats |
logic/ |
Ablaufsteuerung des Solvers |
logic/strategies/ |
Lösungsstrategien und gemeinsame Strategie-Basis |
sudoku/ |
Fassade, die Parser, Feld und Solver zu einem Spiel verbindet |
data/ |
Mitgelieferte Beispielrätsel samt eigener Herkunfts- und Lizenzhinweise |
todo.md |
Offene technische Ideen und Aufgaben |
Der Datenfluss der Demo ist:
Puzzle-Bank-Datei -> parser.PuzzleBank -> field.Field
-> sudoku.Game -> logic.Solver
-> Strategien -> Änderungen am Feld
Eine Strategie implementiert strategies.Strategy. SearchProgressableCells
sammelt mögliche Änderungen, ApplyAll oder ApplyNext übernimmt sie in das
Feld. Wird eine Zahl gesetzt, entfernt der Solver den entsprechenden Kandidaten
aus der zugehörigen Zeile, Spalte und dem Block.
Derzeit in main.go aktiv:
- Kandidaten eintragen (
Notes) - letzte fehlende Zahl eines Bereichs (
LastDigit) - einzelner Kandidat einer Zelle (
NakedSingle) - nur einmal vorkommender Kandidat eines Bereichs (
HiddenSingle)
Weitere Strategietypen sind bereits als Gerüste angelegt, aber noch nicht implementiert.
Eingabedaten
parser.PuzzleBank erwartet das Format der
Sudoku Exchange Puzzle Bank: pro
Zeile einen 12-stelligen Hash, 81 Ziffern für das Rätsel und eine
Schwierigkeitsbewertung. 0 steht für ein leeres Feld. Leere Zeilen werden
übersprungen; alle eingelesenen Rätsel werden im Parser gespeichert.
Die Datensätze unter data/sudoku-exchange-puzzle-bank/ stehen unter der dort
beiliegenden separaten Lizenz.
Bekannte Einschränkungen
field.Field.IsValidund dieIsSolved-Prüfungen einzelner Bereiche sind noch nicht implementiert. Ein vollständig belegtes, aber ungültiges Feld kann daher als gelöst gelten.logic.Solver.GetSolutionPathliefert noch keinen Lösungsweg.- Mehrere fortgeschrittene Strategien sind nur als leere Typen vorhanden.
go test ./...meldet aktuell infield/field.go, dass eine Ganzzahl direkt in einen String konvertiert wird.- Die Demo kann in
LastDigit.SearchProgressableCellsauf eine leere Zelle zugreifen und dadurch abstürzen. - Fehlertexte und Bezeichner sind derzeit teilweise deutsch, teilweise englisch; einige öffentliche Namen enthalten noch Tippfehler.
Lizenz
Der Programmcode steht unter der GNU General Public License v3.0. Für die mitgelieferten Rätseldaten gelten die Hinweise im jeweiligen Unterverzeichnis.