Refactor Sudoku solver architecture
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
package strategies
|
||||
|
||||
import (
|
||||
"git.kleiax.de/homepage/board"
|
||||
"git.kleiax.de/homepage/field"
|
||||
)
|
||||
|
||||
// ────────────────────────────────────────────────────────────────────────────── //
|
||||
@@ -13,20 +13,20 @@ type LastDigit struct {
|
||||
}
|
||||
|
||||
func (ld *LastDigit) SearchProgressableCells() int {
|
||||
ld.field.ForEachPart(func(part board.Part) {
|
||||
ld.field.ForEachPart(func(part field.Part) {
|
||||
missingNumbers := part.GetMissingNumbers()
|
||||
if len(missingNumbers) == 1 {
|
||||
var emptyCell *board.Cell
|
||||
part.ForEachCell(func(cell *board.Cell) {
|
||||
var emptyCell *field.Cell
|
||||
part.ForEachCell(func(cell *field.Cell) {
|
||||
if cell.GetNumber() == 0 {
|
||||
emptyCell = cell
|
||||
}
|
||||
})
|
||||
// fmt.Println(part)
|
||||
// fmt.Printf("Gefundene Zelle: %d/%d - %d, missungNumber: %v, Typ: %T\n", emptyCell.Pos.GetRow(), emptyCell.Pos.GetColumn(), emptyCell.GetNumber(), missingNumbers, part)
|
||||
change := board.ExternalChange{
|
||||
change := field.ExternalChange{
|
||||
Cell: emptyCell,
|
||||
Action: board.ActionSetNumber,
|
||||
Action: field.ActionSetNumber,
|
||||
Value: missingNumbers[0],
|
||||
From: emptyCell.GetNumber(),
|
||||
TriggerdBy: ld.getName(),
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package strategies
|
||||
|
||||
import "git.kleiax.de/homepage/field"
|
||||
|
||||
// ────────────────────────────────────────────────────────────────────────────── //
|
||||
// HIDDEN_SINGLE STRUCTURE //
|
||||
// ────────────────────────────────────────────────────────────────────────────── //
|
||||
@@ -8,6 +10,46 @@ type HiddenSingle struct {
|
||||
Base
|
||||
}
|
||||
|
||||
func (hs *HiddenSingle) SearchProgressableCells() int {
|
||||
hs.field.ForEachPart(func(part field.Part) {
|
||||
m := make(map[int]int)
|
||||
|
||||
part.ForEachCell(func(cell *field.Cell) {
|
||||
notes := cell.Notes.Get()
|
||||
for note := range notes {
|
||||
m[note]++
|
||||
}
|
||||
})
|
||||
|
||||
var hiddenSingles []int
|
||||
for num, count := range m {
|
||||
if count == 1 {
|
||||
hiddenSingles = append(hiddenSingles, num)
|
||||
}
|
||||
}
|
||||
|
||||
for num := range hiddenSingles {
|
||||
part.ForEachCell(func(cell *field.Cell) {
|
||||
if cell.Notes.Has(num) {
|
||||
change := field.ExternalChange{
|
||||
Cell: cell,
|
||||
Action: field.ActionSetNumber,
|
||||
Value: num,
|
||||
From: cell.GetNumber(),
|
||||
TriggerdBy: hs.getName(),
|
||||
}
|
||||
hs.changes = append(hs.changes, change)
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
return len(hs.changes)
|
||||
}
|
||||
|
||||
func (hs *HiddenSingle) getName() string {
|
||||
return "Hidden Single"
|
||||
}
|
||||
|
||||
// ────────────────────────────────────────────────────────────────────────────── //
|
||||
// HIDDEN_PAIR STRUCTURE //
|
||||
// ────────────────────────────────────────────────────────────────────────────── //
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package strategies
|
||||
|
||||
import "git.kleiax.de/homepage/board"
|
||||
import "git.kleiax.de/homepage/field"
|
||||
|
||||
// ────────────────────────────────────────────────────────────────────────────── //
|
||||
// NAKED_SINGLE STRUCTURE //
|
||||
@@ -11,13 +11,13 @@ type NakedSingle struct {
|
||||
}
|
||||
|
||||
func (ns *NakedSingle) SearchProgressableCells() int {
|
||||
ns.field.ForEachPart(func(part board.Part) {
|
||||
part.ForEachCell(func(cell *board.Cell) {
|
||||
ns.field.ForEachPart(func(part field.Part) {
|
||||
part.ForEachCell(func(cell *field.Cell) {
|
||||
candidates := cell.Notes.Get()
|
||||
if len(candidates) == 1 && cell.GetNumber() == 0 {
|
||||
change := board.ExternalChange{
|
||||
change := field.ExternalChange{
|
||||
Cell: cell,
|
||||
Action: board.ActionSetNumber,
|
||||
Action: field.ActionSetNumber,
|
||||
Value: candidates[0],
|
||||
From: cell.GetNumber(),
|
||||
TriggerdBy: ns.getName(),
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package strategies
|
||||
|
||||
import (
|
||||
"git.kleiax.de/homepage/board"
|
||||
"git.kleiax.de/homepage/field"
|
||||
)
|
||||
|
||||
// ────────────────────────────────────────────────────────────────────────────── //
|
||||
@@ -13,8 +13,8 @@ type Notes struct {
|
||||
}
|
||||
|
||||
func (n *Notes) SearchProgressableCells() int {
|
||||
n.field.ForEachRow(func(row *board.Row) {
|
||||
row.ForEachCell(func(cell *board.Cell) {
|
||||
n.field.ForEachRow(func(row *field.Row) {
|
||||
row.ForEachCell(func(cell *field.Cell) {
|
||||
column, _ := n.field.GetColumn(cell.Pos.GetColumn())
|
||||
block, _ := n.field.GetBlock(cell.Pos.GetBlockRow(), cell.Pos.GetBlockColumn())
|
||||
candidates := intersection3(row.GetMissingNumbers(), column.GetMissingNumbers(), block.GetMissingNumbers())
|
||||
@@ -22,9 +22,9 @@ func (n *Notes) SearchProgressableCells() int {
|
||||
if cell.Notes.Has(note) || cell.GetNumber() != 0 {
|
||||
continue
|
||||
}
|
||||
ch := board.ExternalChange{
|
||||
ch := field.ExternalChange{
|
||||
Cell: cell,
|
||||
Action: board.ActionSetNote,
|
||||
Action: field.ActionSetNote,
|
||||
Value: note,
|
||||
TriggerdBy: n.getName(),
|
||||
Marks: nil,
|
||||
|
||||
@@ -3,7 +3,7 @@ package strategies
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"git.kleiax.de/homepage/board"
|
||||
"git.kleiax.de/homepage/field"
|
||||
)
|
||||
|
||||
// ────────────────────────────────────────────────────────────────────────────── //
|
||||
@@ -11,9 +11,9 @@ import (
|
||||
// ────────────────────────────────────────────────────────────────────────────── //
|
||||
|
||||
type Strategy interface {
|
||||
Init(f *board.Field)
|
||||
ApplyAll() []board.ExternalChange
|
||||
ApplyNext() board.ExternalChange
|
||||
Init(f *field.Field)
|
||||
ApplyAll() []field.ExternalChange
|
||||
ApplyNext() field.ExternalChange
|
||||
Name() string
|
||||
SearchProgressableCells() int
|
||||
}
|
||||
@@ -23,7 +23,7 @@ type Strategy interface {
|
||||
// ────────────────────────────────────────────────────────────────────────────── //
|
||||
|
||||
type StrategyVisualization interface {
|
||||
pointOut(f *board.Field) []board.Mark
|
||||
pointOut(f *field.Field) []field.Mark
|
||||
}
|
||||
|
||||
// ────────────────────────────────────────────────────────────────────────────── //
|
||||
@@ -32,16 +32,16 @@ type StrategyVisualization interface {
|
||||
|
||||
type Base struct {
|
||||
name string
|
||||
field *board.Field
|
||||
changes []board.ExternalChange
|
||||
field *field.Field
|
||||
changes []field.ExternalChange
|
||||
}
|
||||
|
||||
func (b *Base) Init(f *board.Field) {
|
||||
func (b *Base) Init(f *field.Field) {
|
||||
b.field = f
|
||||
}
|
||||
|
||||
func (b *Base) ApplyAll() []board.ExternalChange {
|
||||
changesCopy := make([]board.ExternalChange, len(b.changes))
|
||||
func (b *Base) ApplyAll() []field.ExternalChange {
|
||||
changesCopy := make([]field.ExternalChange, len(b.changes))
|
||||
copy(changesCopy, b.changes)
|
||||
|
||||
for _, change := range b.changes {
|
||||
@@ -53,9 +53,9 @@ func (b *Base) ApplyAll() []board.ExternalChange {
|
||||
return changesCopy
|
||||
}
|
||||
|
||||
func (b *Base) ApplyNext() board.ExternalChange {
|
||||
func (b *Base) ApplyNext() field.ExternalChange {
|
||||
if len(b.changes) < 1 {
|
||||
return board.ExternalChange{}
|
||||
return field.ExternalChange{}
|
||||
}
|
||||
|
||||
changeCopy := b.changes[0]
|
||||
|
||||
Reference in New Issue
Block a user