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) GetEachPartAtPos(pos *Position) []Part { row, err := f.GetRow(pos.row) if err != nil { return nil } column, err := f.GetColumn(pos.column) if err != nil { return nil } block, err := f.GetBlock(pos.blockRow, pos.blockColumn) if err != nil { return nil } return append([]Part{}, row, column, block) } 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) ForEachPartAtPos(pos *Position, fn func(part Part)) { parts := f.GetEachPartAtPos(pos) for _, part := range parts { fn(part) } } 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) }