libchess/pkg/board/bitboard.go

83 lines
1.5 KiB
Go

package board
import (
"strconv"
)
// Bitboard is defined as
type Bitboard uint64
// NewBitboard returns an initialized Bitboard.
func NewBitboard(m map[Square]bool) Bitboard {
s := ""
for sq := 0; sq < 64; sq++ {
if m[Square(sq)] {
s += "1"
} else {
s += "0"
}
}
bb, err := strconv.ParseUint(s, 2, 64)
if err != nil {
panic(err)
}
return Bitboard(bb)
}
// Map returns a map[Square]bool representation of this Bitboard.
func (bb Bitboard) Map() map[Square]bool {
m := map[Square]bool{}
for sq := 0; sq < 64; sq++ {
if bb&Square(sq).Bitboard() > 0 {
m[Square(sq)] = true
}
}
return m
}
// Squares returns a []Square of all bits in this Bitboard.
func (bb Bitboard) Squares() []Square {
squares := []Square{}
for sq := 0; sq < 64; sq++ {
if bb&Square(sq).Bitboard() > 0 {
squares = append(squares, Square(sq))
}
}
return squares
}
// Occupied returns true if the given Square is occupied.
func (bb Bitboard) Occupied(sq Square) bool {
return (uint64(bb) >> uint64(63-sq) & 1) == 1
}
// Draw returns visual representation of the bitboard useful for debugging.
func (bb Bitboard) Draw() string {
s := "\n A B C D E F G H\n"
for r := 7; r >= 0; r-- {
s += Rank(r).String()
s += " "
for f := 0; f < 8; f++ {
sq := NewSquare(File(f), Rank(r))
if bb.Occupied(sq) {
s += "1"
} else {
s += "0"
}
s += " "
}
s += "\n"
}
return s
}
// Flip toggles the bit at the given square.
func (bb *Bitboard) Flip(sq Square) {
if !sq.IsValid() {
return
}
oldBB := *bb
newBB := oldBB ^ sq.Bitboard()
*bb = newBB
}