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(cell *Cell, action ChangeAction, value, from int, trigger string, marks []Mark) { change := Change{ Cell: cell, marks: marks, action: action, value: value, from: from, triggerdBy: trigger, } change.do() f.changes = append(f.changes, change) }