Files
Sudoku/field/parts.go
T

149 lines
5.0 KiB
Go

package field
import (
"fmt"
"strings"
)
type Part interface {
IsSolved() bool
ForEachCell(fn func(cell *Cell))
GetMissingNumbers() []int
RemoveNote(field *Field, note int, trigger string, marks []Mark)
String() string
}
// ────────────────────────────────────────────────────────────────────────────── //
// LINE STRUCTURE //
// ────────────────────────────────────────────────────────────────────────────── //
type Line struct {
cells []*Cell
}
func (l *Line) IsSolved() bool {
//TODO
return false
}
func (l *Line) ForEachCell(fn func(cell *Cell)) {
for _, cell := range l.cells {
fn(cell)
}
}
func (l *Line) GetMissingNumbers() []int {
return getMissingNumbersHelper(len(l.cells), l.ForEachCell)
}
func (l *Line) RemoveNote(field *Field, note int, trigger string, marks []Mark) {
l.ForEachCell(func(cell *Cell) {
cell.Notes.Remove(field, cell, note, trigger, marks)
})
}
func (l *Line) String() string {
return lineString(l, "Line")
}
// ────────────────────────────────────────────────────────────────────────────── //
// ROW STRUCTURE //
// ────────────────────────────────────────────────────────────────────────────── //
type Row struct {
Line
}
func (r *Row) String() string {
return lineString(r, "Row")
}
// ────────────────────────────────────────────────────────────────────────────── //
// COLUMN STRUCTURE //
// ────────────────────────────────────────────────────────────────────────────── //
type Column struct {
Line
}
func (c *Column) String() string {
return lineString(c, "Column")
}
// ────────────────────────────────────────────────────────────────────────────── //
// BLOCK STRUCTURE //
// ────────────────────────────────────────────────────────────────────────────── //
type Block struct {
cells [][]*Cell
}
func (b *Block) IsSolved() bool {
//TODO
return false
}
func (b *Block) ForEachCell(fn func(cell *Cell)) {
for _, row := range b.cells {
for _, cell := range row {
fn(cell)
}
}
}
func (b *Block) GetMissingNumbers() []int {
max := len(b.cells) * len(b.cells[0])
return getMissingNumbersHelper(max, b.ForEachCell)
}
func (b *Block) RemoveNote(field *Field, note int, trigger string, marks []Mark) {
b.ForEachCell(func(cell *Cell) {
cell.Notes.Remove(field, cell, note, trigger, marks)
})
}
func (b *Block) String() string {
var str strings.Builder
str.WriteString("Block:\t")
lastLine := 0
b.ForEachCell(func(cell *Cell) {
fmt.Fprintf(&str, "%d ", cell.number)
if lastLine == cell.Pos.inBlockRow {
}
})
return str.String()
}
// ────────────────────────────────────────────────────────────────────────────── //
// HELPER //
// ────────────────────────────────────────────────────────────────────────────── //
func lineString(part Part, name string) string {
var str strings.Builder
fmt.Fprintf(&str, "%s:\t", name)
part.ForEachCell(func(cell *Cell) {
fmt.Fprintf(&str, "%d ", cell.number)
})
return str.String()
}
func getMissingNumbersHelper(max int, iterate func(fn func(cell *Cell))) []int {
present := make(map[int]bool, max)
iterate(func(cell *Cell) {
if cell.number != 0 {
present[cell.number] = true
}
})
var missing []int
for i := 1; i <= max; i++ {
if !present[i] {
missing = append(missing, i)
}
}
return missing
}