Files
Sudoku/board/field.go
T

162 lines
4.8 KiB
Go

package board
import (
"fmt"
)
// ────────────────────────────────────────────────────────────────────────────── //
// FIELD STRUCTURE //
// ────────────────────────────────────────────────────────────────────────────── //
type Field struct {
rows int
columns int
blockRows int
blockColumns int
blockSizeRow int
blockSizeColumn int
cells [][]Cell
changes []Change
sha1 []byte
rating float64
}
// ────────────────────────────────────────────────────────────────────────────── //
// GETTER //
// ────────────────────────────────────────────────────────────────────────────── //
func (f *Field) GetRow(r int) (*Line, error) {
if r >= f.rows || r < 0 {
return nil, outOfBound
}
return &Line{cells: append([]Cell(nil), f.cells[r]...)}, nil
}
func (f *Field) GetColumn(c int) (*Line, error) {
if c >= f.columns || c < 0 {
return nil, outOfBound
}
// Performance
result := &Line{
cells: make([]Cell, 0, f.rows),
}
// Copying
for _, row := range f.cells {
result.cells = append(result.cells, row[c])
}
return result, nil
}
func (f *Field) GetBlock(r, c int) (*Block, error) {
if r < 0 || r >= f.blockRows || c < 0 || c >= f.blockColumns {
return nil, outOfBound
}
startRow := r * f.blockSizeRow
startCol := c * f.blockSizeColumn
block := &Block{
cells: make([][]Cell, f.blockSizeRow),
}
for row := range block.cells {
// Effizientes Kopieren der Zeile
block.cells[row] = make([]Cell, f.blockSizeColumn)
copy(block.cells[row], f.cells[startRow+row][startCol:startCol+f.blockSizeColumn])
}
return block, nil
}
func (f *Field) GetCell(r, c int) (*Cell, error) {
if r > f.rows || c > f.columns {
return nil, outOfBound
}
return &f.cells[r][c], nil
}
// ────────────────────────────────────────────────────────────────────────────── //
// FOREACH FUNCTIONS //
// ────────────────────────────────────────────────────────────────────────────── //
func (f *Field) ForEachPart(fn func(part Part)) {
f.ForEachRow(func(line *Line) {
fn(line)
})
f.ForEachColumn(func(line *Line) {
fn(line)
})
f.ForEachBlock(func(block *Block) {
fn(block)
})
}
func (f *Field) ForEachRow(fn func(line *Line)) {
for i := range f.rows {
line, err := f.GetRow(i)
if err != nil {
fmt.Println(err.Error())
return
}
fn(line)
}
}
func (f *Field) ForEachColumn(fn func(line *Line)) {
for i := range f.columns {
column, err := f.GetColumn(i)
if err != nil {
fmt.Println(err.Error())
return
}
fn(column)
}
}
func (f *Field) ForEachBlock(fn func(block *Block)) {
for r := range f.blockRows {
for c := range f.blockColumns {
block, err := f.GetBlock(r, c)
if err != nil {
fmt.Println(err.Error())
return
}
fn(block)
}
}
}
func (f *Field) ForEachCell(fn func(cell *Cell)) {
for _, row := range f.cells {
for _, cell := range row {
fn(&cell)
}
}
}
// ────────────────────────────────────────────────────────────────────────────── //
// MODIFIER //
// ────────────────────────────────────────────────────────────────────────────── //
func (f *Field) AddChange(eChange *ExternalChange) {
change := Change{
Cell: eChange.Cell,
marks: eChange.Marks,
action: eChange.Action,
value: eChange.Value,
from: eChange.From,
triggerdBy: eChange.TriggerdBy,
}
change.do()
f.changes = append(f.changes, change)
}