first successful run to solve a simple puzzle

This commit is contained in:
2026-07-25 06:58:15 +02:00
parent 8e99087a30
commit 7bf4a8d725
15 changed files with 201 additions and 28 deletions
-4
View File
@@ -1,4 +0,0 @@
package logic
type Change struct {
}
-1
View File
@@ -1 +0,0 @@
package logic
+26 -6
View File
@@ -11,6 +11,8 @@ import (
type Solver struct {
strategies []strategies.Strategy
returnTo int
field *board.Field
conf struct {
all bool
repeat bool
@@ -22,19 +24,37 @@ func (s *Solver) Add(strategy strategies.Strategy) {
}
func (s *Solver) InitStragies(field *board.Field) {
s.returnTo = 1
s.field = field
for _, strategy := range s.strategies {
strategy.Init(field)
}
}
func (s *Solver) Run(i int) bool {
//TODO: clean und Fehlerauffangen
s.strategies[i].SearchProgressableCells()
numberOfChanges := s.strategies[i].ApplyAll()
if numberOfChanges == 0 {
return false
for j := 0; j < len(s.strategies); j++ {
if s.strategies[j].SearchProgressableCells() == 0 {
continue
}
for _, change := range s.strategies[j].ApplyAll() {
if change.Action != board.ActionSetNumber {
continue
}
s.field.ForEachPartAtPos(change.Cell.Pos, func(part board.Part) {
part.ForEachCell(func(cell *board.Cell) {
cell.Notes.Remove(s.field, cell, change.Value, "remove note after insert of a number", nil)
})
})
}
j = s.returnTo - 1
}
return true
if s.field.IsSolved() {
return true
}
return false
}
func (s *Solver) Search() {
+4 -4
View File
@@ -1,8 +1,6 @@
package strategies
import (
"fmt"
"git.kleiax.de/homepage/board"
)
@@ -24,6 +22,8 @@ func (ld *LastDigit) SearchProgressableCells() int {
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{
Cell: emptyCell,
Action: board.ActionSetNumber,
@@ -34,12 +34,12 @@ func (ld *LastDigit) SearchProgressableCells() int {
ld.changes = append(ld.changes, change)
}
})
fmt.Printf("LastDigit Changes %d\n", len(ld.changes))
// fmt.Printf("LastDigit Changes %d\n", len(ld.changes))
return len(ld.changes)
}
func (ld *LastDigit) getName() string {
return "Last Digit - Letzte Zahl"
return "Last Digit"
}
// ────────────────────────────────────────────────────────────────────────────── //
+5 -1
View File
@@ -14,7 +14,7 @@ func (ns *NakedSingle) SearchProgressableCells() int {
ns.field.ForEachPart(func(part board.Part) {
part.ForEachCell(func(cell *board.Cell) {
candidates := cell.Notes.Get()
if len(candidates) == 1 {
if len(candidates) == 1 && cell.GetNumber() == 0 {
change := board.ExternalChange{
Cell: cell,
Action: board.ActionSetNumber,
@@ -29,6 +29,10 @@ func (ns *NakedSingle) SearchProgressableCells() int {
return len(ns.changes)
}
func (ns *NakedSingle) getName() string {
return "Naked Single"
}
// ────────────────────────────────────────────────────────────────────────────── //
// NAKED_DOUBLE STRUCTURE //
// ────────────────────────────────────────────────────────────────────────────── //
+81
View File
@@ -0,0 +1,81 @@
package strategies
import (
"git.kleiax.de/homepage/board"
)
// ────────────────────────────────────────────────────────────────────────────── //
// NOTES STRUCTURE //
// ────────────────────────────────────────────────────────────────────────────── //
type Notes struct {
Base
}
func (n *Notes) SearchProgressableCells() int {
n.field.ForEachRow(func(row *board.Row) {
row.ForEachCell(func(cell *board.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())
for _, note := range candidates {
if cell.Notes.Has(note) || cell.GetNumber() != 0 {
continue
}
ch := board.ExternalChange{
Cell: cell,
Action: board.ActionSetNote,
Value: note,
TriggerdBy: n.getName(),
Marks: nil,
From: 0,
}
n.changes = append(n.changes, ch)
}
})
})
return len(n.changes)
}
func (n *Notes) getName() string {
return "Make Notes"
}
func intersection3(a, b, c []int) []int {
set := make(map[int]bool)
for _, v := range a {
set[v] = true
}
// Nur Werte behalten, die auch in b vorkommen
inB := make(map[int]bool)
for _, v := range b {
inB[v] = true
}
for v := range set {
if !inB[v] {
delete(set, v)
}
}
// Nur Werte behalten, die auch in c vorkommen
inC := make(map[int]bool)
for _, v := range c {
inC[v] = true
}
for v := range set {
if !inC[v] {
delete(set, v)
}
}
result := make([]int, 0, len(set))
for v := range set {
result = append(result, v)
}
return result
}
+16 -8
View File
@@ -12,8 +12,8 @@ import (
type Strategy interface {
Init(f *board.Field)
ApplyAll() int
ApplyNext() bool
ApplyAll() []board.ExternalChange
ApplyNext() board.ExternalChange
Name() string
SearchProgressableCells() int
}
@@ -40,23 +40,31 @@ func (b *Base) Init(f *board.Field) {
b.field = f
}
func (b *Base) ApplyAll() int {
func (b *Base) ApplyAll() []board.ExternalChange {
changesCopy := make([]board.ExternalChange, len(b.changes))
copy(changesCopy, b.changes)
for _, change := range b.changes {
b.field.AddChange(&change)
}
len := len(b.changes)
b.changes = b.changes[:0]
return len
return changesCopy
}
func (b *Base) ApplyNext() bool {
func (b *Base) ApplyNext() board.ExternalChange {
if len(b.changes) < 1 {
return false
return board.ExternalChange{}
}
changeCopy := b.changes[0]
b.field.AddChange(&b.changes[0])
b.changes = b.changes[1:]
return true
return changeCopy
}
func (b *Base) getName() string {