149 lines
5.0 KiB
Go
149 lines
5.0 KiB
Go
package board
|
|
|
|
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
|
|
}
|