Skip to content

Commit

Permalink
Merge pull request #452 from lenguyenthanh/specilization-by-color
Browse files Browse the repository at this point in the history
Specialize ByColor & ByRole for bitboard.Board
  • Loading branch information
ornicar authored Jul 18, 2023
2 parents 77f5f85 + 5ad7291 commit 925a99a
Showing 1 changed file with 95 additions and 4 deletions.
99 changes: 95 additions & 4 deletions src/main/scala/bitboard/Board.scala
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ import Bitboard.*
// Chess board representation
case class Board(
occupied: Bitboard,
byColor: ByColor[Bitboard],
byRole: ByRole[Bitboard]
byColor: ByColor,
byRole: ByRole
):
val white = byColor.white
val black = byColor.black
Expand Down Expand Up @@ -98,7 +98,7 @@ case class Board(
byRole.map(_ & notMask)
)

def byRoleOf(color: Color): ByRole[Bitboard] = byRole.map(_ & byColor(color))
def byRoleOf(color: Color): chess.ByRole[Bitboard] = byRole.mapTo(_ & byColor(color))

// put a piece to an empty square
def put(piece: Piece, at: Square): Option[Board] =
Expand Down Expand Up @@ -193,7 +193,7 @@ object Board:
val empty: Board = Board(
Bitboard.empty,
ByColor.fill(Bitboard.empty),
ByRole(Bitboard.empty)
ByRole.fill(Bitboard.empty)
)

def fromMap(pieces: PieceMap): Board =
Expand Down Expand Up @@ -223,3 +223,94 @@ object Board:
case Color.Black => black |= position

Board(occupied, ByColor(white, black), ByRole(pawns, knights, bishops, rooks, queens, kings))

private case class ByColor(white: Bitboard, black: Bitboard):

inline def apply(inline color: Color) = if color.white then white else black

inline def findColor(pred: Bitboard => Boolean): Option[Color] =
if pred(white) then White.some
else if pred(black) then Black.some
else None

def foreach(f: (Color, Bitboard) => Unit): Unit =
f(White, white)
f(Black, black)

inline def update(inline color: Color, f: Bitboard => Bitboard): ByColor =
if color.white then copy(white = f(white))
else copy(black = f(black))

def mapReduce[B, C](f: Bitboard => B)(r: (B, B) => C): C = r(f(white), f(black))

def map(f: Bitboard => Bitboard): ByColor = ByColor(f(white), f(black))

private object ByColor:
inline def fill(inline a: Bitboard): ByColor = ByColor(a, a)

private case class ByRole(
pawn: Bitboard,
knight: Bitboard,
bishop: Bitboard,
rook: Bitboard,
queen: Bitboard,
king: Bitboard
):
def apply(role: Role): Bitboard = role match
case Pawn => pawn
case Knight => knight
case Bishop => bishop
case Rook => rook
case Queen => queen
case King => king

inline def update(role: Role, f: Bitboard => Bitboard): ByRole = role match
case Pawn => copy(pawn = f(pawn))
case Knight => copy(knight = f(knight))
case Bishop => copy(bishop = f(bishop))
case Rook => copy(rook = f(rook))
case Queen => copy(queen = f(queen))
case King => copy(king = f(king))

inline def find(f: Bitboard => Boolean): Option[Bitboard] =
if f(pawn) then Some(pawn)
else if f(knight) then Some(knight)
else if f(bishop) then Some(bishop)
else if f(rook) then Some(rook)
else if f(queen) then Some(queen)
else if f(king) then Some(king)
else None

inline def foreach(f: (Role, Bitboard) => Unit): Unit =
f(Pawn, pawn)
f(Knight, knight)
f(Bishop, bishop)
f(Rook, rook)
f(Queen, queen)
f(King, king)

inline def findRole(f: Bitboard => Boolean): Option[Role] =
if f(pawn) then Some(Pawn)
else if f(knight) then Some(Knight)
else if f(bishop) then Some(Bishop)
else if f(rook) then Some(Rook)
else if f(queen) then Some(Queen)
else if f(king) then Some(King)
else None

inline def map(f: Bitboard => Bitboard): ByRole =
ByRole(
f(pawn),
f(knight),
f(bishop),
f(rook),
f(queen),
f(king)
)

def mapTo[B](f: Bitboard => B): chess.ByRole[B] =
chess.ByRole(f(pawn), f(knight), f(bishop), f(rook), f(queen), f(king))

private object ByRole:

inline def fill(inline a: Bitboard): ByRole = ByRole(a, a, a, a, a, a)

0 comments on commit 925a99a

Please sign in to comment.