-module(bitboard). -compile([no_auto_import, nowarn_unused_vars]). -export([new_bitboard/1, empty_bitboard/0, full_bitboard/0, 'and'/2, exclusive_or/2, 'or'/2, 'not'/1, shift_left/2, shift_right/2, bitscan_forward_inner/2, bitscan_forward/1, bitscan_backward_inner/2, bitscan_backward/1]). -export_type([bitboard/0]). -type bitboard() :: {bitboard, integer()}. -spec new_bitboard(integer()) -> bitboard(). new_bitboard(Bitboard) -> {bitboard, Bitboard}. -spec empty_bitboard() -> bitboard(). empty_bitboard() -> {bitboard, 0}. -spec full_bitboard() -> bitboard(). full_bitboard() -> {bitboard, 16#ffffffffffffffff}. -spec 'and'(bitboard(), bitboard()) -> bitboard(). 'and'(Bitboard1, Bitboard2) -> {bitboard, gleam@bitwise:'and'( erlang:element(2, Bitboard1), erlang:element(2, Bitboard2) )}. -spec exclusive_or(bitboard(), bitboard()) -> bitboard(). exclusive_or(Bitboard1, Bitboard2) -> {bitboard, gleam@bitwise:exclusive_or( erlang:element(2, Bitboard1), erlang:element(2, Bitboard2) )}. -spec 'or'(bitboard(), bitboard()) -> bitboard(). 'or'(Bitboard1, Bitboard2) -> {bitboard, gleam@bitwise:'or'( erlang:element(2, Bitboard1), erlang:element(2, Bitboard2) )}. -spec 'not'(bitboard()) -> bitboard(). 'not'(Bitboard) -> {bitboard, gleam@bitwise:'not'(erlang:element(2, Bitboard))}. -spec shift_left(bitboard(), integer()) -> bitboard(). shift_left(Bitboard, Shift) -> {bitboard, gleam@bitwise:shift_left(erlang:element(2, Bitboard), Shift)}. -spec shift_right(bitboard(), integer()) -> bitboard(). shift_right(Bitboard, Shift) -> {bitboard, gleam@bitwise:shift_right(erlang:element(2, Bitboard), Shift)}. -spec bitscan_forward_inner(bitboard(), integer()) -> integer(). bitscan_forward_inner(Bitboard, Index) -> case (erlang:element(2, Bitboard) =:= 0) orelse (Index > 63) of true -> -1; false -> Lsb_digit = 2#0000000000000000000000000000000000000000000000000000000000000001, First_digit_bitboard = 'and'(Bitboard, new_bitboard(Lsb_digit)), case erlang:element(2, First_digit_bitboard) of 0 -> bitscan_forward_inner(shift_right(Bitboard, 1), Index + 1); _ -> Index end end. -spec bitscan_forward(bitboard()) -> integer(). bitscan_forward(Bitboard) -> bitscan_forward_inner(Bitboard, 0). -spec bitscan_backward_inner(bitboard(), integer()) -> integer(). bitscan_backward_inner(Bitboard, Index) -> case (erlang:element(2, Bitboard) =:= 0) orelse (Index < 0) of true -> -1; false -> Msb_digit = 2#1000000000000000000000000000000000000000000000000000000000000000, First_digit_bitboard = 'and'(Bitboard, new_bitboard(Msb_digit)), case erlang:element(2, First_digit_bitboard) of 0 -> bitscan_backward_inner(shift_left(Bitboard, 1), Index - 1); _ -> Index end end. -spec bitscan_backward(bitboard()) -> integer(). bitscan_backward(Bitboard) -> bitscan_backward_inner(Bitboard, 63).