Refactor Sudoku solver architecture
This commit is contained in:
@@ -1,3 +1,114 @@
|
||||
# Sudoku
|
||||
|
||||
Sudoku-Puzzle-Löser mit Lösungsweg
|
||||
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](#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:
|
||||
|
||||
```sh
|
||||
go run .
|
||||
```
|
||||
|
||||
Der Pfad und die Rätselauswahl sind momentan noch nicht über
|
||||
Kommandozeilenargumente konfigurierbar.
|
||||
|
||||
## Entwicklung
|
||||
|
||||
Alle Pakete bauen und testen:
|
||||
|
||||
```sh
|
||||
go test ./...
|
||||
```
|
||||
|
||||
Code formatieren und statisch prüfen:
|
||||
|
||||
```sh
|
||||
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:
|
||||
|
||||
```text
|
||||
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](data/sudoku-exchange-puzzle-bank/README.md): 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.IsValid` und die `IsSolved`-Prüfungen einzelner Bereiche sind
|
||||
noch nicht implementiert. Ein vollständig belegtes, aber ungültiges Feld kann
|
||||
daher als gelöst gelten.
|
||||
- `logic.Solver.GetSolutionPath` liefert noch keinen Lösungsweg.
|
||||
- Mehrere fortgeschrittene Strategien sind nur als leere Typen vorhanden.
|
||||
- `go test ./...` meldet aktuell in `field/field.go`, dass eine Ganzzahl direkt
|
||||
in einen String konvertiert wird.
|
||||
- Die Demo kann in `LastDigit.SearchProgressableCells` auf 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](LICENSE).
|
||||
Für die mitgelieferten Rätseldaten gelten die Hinweise im jeweiligen
|
||||
Unterverzeichnis.
|
||||
|
||||
Reference in New Issue
Block a user