func (b *Board) PlaceQueen(c Coordinates) error {
	if !b.withinBounds(c.X, c.Y) {
		return ErrorOutOfBounds
	}
	b.lock.Lock()
	defer b.lock.Unlock()
	if b.fields[c.Y][c.X].queen || b.fields[c.Y][c.X].attacks > 0 {
		return ErrorOperationNotPermitted
	}
	for j := 0; b.withinBounds(j, c.Y); j++ {
		b.fields[c.Y][j].attacks++
	}
	for i := 0; b.withinBounds(c.X, i); i++ {
		b.fields[i][c.X].attacks++
	}
	for j, i := c.X-1, c.Y-1; b.withinBounds(j, i); {
		b.fields[i][j].attacks++
		j--
		i--
	}
	for j, i := c.X+1, c.Y-1; b.withinBounds(j, i); {
		b.fields[i][j].attacks++
		j++
		i--
	}
	for j, i := c.X-1, c.Y+1; b.withinBounds(j, i); {
		b.fields[i][j].attacks++
		j--
		i++
	}
	for j, i := c.X+1, c.Y+1; b.withinBounds(j, i); {
		b.fields[i][j].attacks++
		j++
		i++
	}
	b.fields[c.Y][c.X].attacks = 0
	b.fields[c.Y][c.X].queen = true
	b.queens++
	return nil
}
PlaceQueen places a queen on the board and updates the attack counters of all
affected fields.
package queensboard
import (
	"bytes"
	"fmt"
	"io"
	"sync"
)
var (
	ErrorOperationNotPermitted = fmt.Errorf("operation not permitted")
	ErrorOutOfBounds = fmt.Errorf("out of bounds coordinates")
	ErrorInvalidBoardDimensions = fmt.Errorf("invalid board dimensions")
)
type Coordinates struct {
	X, Y int
}
type field struct {
	queen   bool  
	attacks int   
}
type Board struct {
	lock   sync.RWMutex
	fields [][]field
	queens int
	width  int
	height int
}
func New() *Board {
	b, _ := NewCustom(8, 8)
	return b
}
func NewCustom(width, height int) (*Board, error) {
	if width < 1 || height < 1 {
		return nil, ErrorInvalidBoardDimensions
	}
	b := &Board{
		width:  width,
		height: height,
	}
	b.fields = make([][]field, b.height, b.height)
	for i := range b.fields {
		b.fields[i] = make([]field, b.width, b.width)
	}
	return b, nil
}
func (b *Board) withinBounds(x, y int) bool {
	if x >= 0 && y >= 0 && x < b.width && y < b.height {
		return true
	}
	return false
}