Files
Sudoku/board/field.go
T

176 lines
5.0 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) (*Row, error) {
if r >= f.rows || r < 0 {
return nil, outOfBound
}
cellPtrs := make([]*Cell, len(f.cells[r]))
for i := range f.cells[r] {
cellPtrs[i] = &f.cells[r][i]
}
return &Row{
Line: Line{
cells: cellPtrs,
},
}, nil
}
func (f *Field) GetColumn(c int) (*Column, error) {
if c >= f.columns || c < 0 {
return nil, outOfBound
}
// Performance
result := &Column{
Line: 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)
for column := range block.cells[row] {
block.cells[row][column] = &f.cells[startRow+row][startCol+column]
}
}
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(row *Row) {
fn(row)
})
f.ForEachColumn(func(column *Column) {
fn(column)
})
f.ForEachBlock(func(block *Block) {
fn(block)
})
}
func (f *Field) ForEachRow(fn func(row *Row)) {
for i := range f.rows {
row, err := f.GetRow(i)
if err != nil {
fmt.Println(err.Error())
return
}
fn(row)
}
}
func (f *Field) ForEachColumn(fn func(column *Column)) {
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)
}