// Package queenattack handles chess.
package queenattack
import (
"fmt"
"strconv"
)
type chessPos struct {
row byte
col byte
}
// offset for converting from lowercase char to number
const offset = 96
// CanQueenAttack checks if two queens can attack each other or not.
func CanQueenAttack(white, black string) (bool, error) {
// invalid inputs
if len(white) != 2 && len(black) != 2 {
return false, fmt.Errorf("invalid input")
}
if white == black {
return false, fmt.Errorf("same position")
}
// reading in positions
var w, b chessPos
w.col = white[0] - offset
b.col = black[0] - offset
tmp, err := strconv.ParseUint(white[1:], 10, 8)
if err != nil {
return false, err
}
w.row = byte(tmp)
tmp, err = strconv.ParseUint(black[1:], 10, 8)
if err != nil {
return false, err
}
b.row = byte(tmp)
if w.row > 8 || b.row > 8 || w.row < 1 || b.row < 1 {
return false, fmt.Errorf("row out of the chessboard")
}
// check if position is within range
if w.col > 8 || b.col > 8 || w.col < 1 || b.col < 1 {
return false, fmt.Errorf("col out of the chessboard")
}
// same row or column can attack
if w.col == b.col || w.row == b.row {
return true, nil
}
// check diagonals, overrun does not matter, keeping it in range costs more
var i byte
for i = 1; i < 8; i++ {
if w.row+i == b.row {
if w.col-i == b.col || w.col+i == b.col {
return true, nil
}
}
if w.row-i == b.row {
if w.col-i == b.col || w.col+i == b.col {
return true, nil
}
}
}
return false, nil
}