-module(board). -compile([no_auto_import, nowarn_unused_vars]). -export([get_positions_inner/2, get_positions/1, from_position/1, set_piece_at_position/3, get_piece_at_position/2, remove_piece_at_position/2]). -export_type([board_bb/0]). -type board_bb() :: {board_bb, bitboard:bitboard(), bitboard:bitboard(), bitboard:bitboard(), bitboard:bitboard(), bitboard:bitboard(), bitboard:bitboard(), bitboard:bitboard(), bitboard:bitboard(), bitboard:bitboard(), bitboard:bitboard(), bitboard:bitboard(), bitboard:bitboard()}. -spec get_positions_inner(bitboard:bitboard(), integer()) -> list(position:position()). get_positions_inner(Bitboard, Count) -> case Count < 0 of true -> []; false -> Just_first_bit_of_bb = bitboard:'and'( Bitboard, bitboard:new_bitboard(16#8000000000000000) ), case erlang:element(2, Just_first_bit_of_bb) of 0 -> get_positions_inner( bitboard:shift_left(Bitboard, 1), Count - 1 ); _ -> _assert_subject = position:from_int(Count), {some, Position_dest} = case _assert_subject of {some, _} -> _assert_subject; _assert_fail -> erlang:error(#{gleam_error => let_assert, message => <<"Assertion pattern match failed"/utf8>>, value => _assert_fail, module => <<"board"/utf8>>, function => <<"get_positions_inner"/utf8>>, line => 307}) end, [Position_dest | get_positions_inner( bitboard:shift_left(Bitboard, 1), Count - 1 )] end end. -spec get_positions(bitboard:bitboard()) -> list(position:position()). get_positions(Bitboard) -> Positions = [], case erlang:element(2, Bitboard) of 0 -> Positions; _ -> Count = 63, Just_first_bit_of_bb = bitboard:'and'( Bitboard, bitboard:new_bitboard(16#8000000000000000) ), case erlang:element(2, Just_first_bit_of_bb) of 0 -> get_positions_inner( bitboard:shift_left(Bitboard, 1), Count - 1 ); _ -> _assert_subject = position:from_int(Count), {some, Position_dest} = case _assert_subject of {some, _} -> _assert_subject; _assert_fail -> erlang:error(#{gleam_error => let_assert, message => <<"Assertion pattern match failed"/utf8>>, value => _assert_fail, module => <<"board"/utf8>>, function => <<"get_positions"/utf8>>, line => 288}) end, [Position_dest | get_positions_inner( bitboard:shift_left(Bitboard, 1), Count - 1 )] end end. -spec from_position(position:position()) -> bitboard:bitboard(). from_position(Position) -> Bitboard = bitboard:shift_left( bitboard:new_bitboard(1), position:to_int(Position) ), Bitboard. -spec set_piece_at_position(board_bb(), position:position(), piece:piece()) -> board_bb(). set_piece_at_position(Board, Position, Piece) -> Bitboard = from_position(Position), New_board = case Piece of {piece, Color, Kind} when (Color =:= white) andalso (Kind =:= king) -> erlang:setelement( 8, Board, bitboard:'or'(Bitboard, erlang:element(8, Board)) ); {piece, Color@1, Kind@1} when (Color@1 =:= white) andalso (Kind@1 =:= queen) -> erlang:setelement( 9, Board, bitboard:'or'(Bitboard, erlang:element(9, Board)) ); {piece, Color@2, Kind@2} when (Color@2 =:= white) andalso (Kind@2 =:= rook) -> erlang:setelement( 10, Board, bitboard:'or'(Bitboard, erlang:element(10, Board)) ); {piece, Color@3, Kind@3} when (Color@3 =:= white) andalso (Kind@3 =:= bishop) -> erlang:setelement( 11, Board, bitboard:'or'(Bitboard, erlang:element(11, Board)) ); {piece, Color@4, Kind@4} when (Color@4 =:= white) andalso (Kind@4 =:= knight) -> erlang:setelement( 12, Board, bitboard:'or'(Bitboard, erlang:element(12, Board)) ); {piece, Color@5, Kind@5} when (Color@5 =:= white) andalso (Kind@5 =:= pawn) -> erlang:setelement( 13, Board, bitboard:'or'(Bitboard, erlang:element(13, Board)) ); {piece, Color@6, Kind@6} when (Color@6 =:= black) andalso (Kind@6 =:= king) -> erlang:setelement( 2, Board, bitboard:'or'(Bitboard, erlang:element(2, Board)) ); {piece, Color@7, Kind@7} when (Color@7 =:= black) andalso (Kind@7 =:= queen) -> erlang:setelement( 3, Board, bitboard:'or'(Bitboard, erlang:element(3, Board)) ); {piece, Color@8, Kind@8} when (Color@8 =:= black) andalso (Kind@8 =:= rook) -> erlang:setelement( 4, Board, bitboard:'or'(Bitboard, erlang:element(4, Board)) ); {piece, Color@9, Kind@9} when (Color@9 =:= black) andalso (Kind@9 =:= bishop) -> erlang:setelement( 5, Board, bitboard:'or'(Bitboard, erlang:element(5, Board)) ); {piece, Color@10, Kind@10} when (Color@10 =:= black) andalso (Kind@10 =:= knight) -> erlang:setelement( 6, Board, bitboard:'or'(Bitboard, erlang:element(6, Board)) ); {piece, Color@11, Kind@11} when (Color@11 =:= black) andalso (Kind@11 =:= pawn) -> erlang:setelement( 7, Board, bitboard:'or'(Bitboard, erlang:element(7, Board)) ); _ -> (erlang:error(#{gleam_error => panic, message => <<"panic expression evaluated"/utf8>>, module => <<"board"/utf8>>, function => <<"set_piece_at_position"/utf8>>, line => 213}))(<<"Invalid piece"/utf8>>) end, New_board. -spec get_piece_at_position(board_bb(), position:position()) -> gleam@option:option(piece:piece()). get_piece_at_position(Board, Position) -> Bitboard = from_position(Position), Black_king_bb_compare = bitboard:'and'(erlang:element(2, Board), Bitboard), Black_queen_bb_compare = bitboard:'and'(erlang:element(3, Board), Bitboard), Black_rook_bb_compare = bitboard:'and'(erlang:element(4, Board), Bitboard), Black_bishop_bb_compare = bitboard:'and'(erlang:element(5, Board), Bitboard), Black_knight_bb_compare = bitboard:'and'(erlang:element(6, Board), Bitboard), Black_pawns_bb_compare = bitboard:'and'(erlang:element(7, Board), Bitboard), White_king_bb_compare = bitboard:'and'(erlang:element(8, Board), Bitboard), White_queen_bb_compare = bitboard:'and'(erlang:element(9, Board), Bitboard), White_rook_bb_compare = bitboard:'and'(erlang:element(10, Board), Bitboard), White_bishop_bb_compare = bitboard:'and'( erlang:element(11, Board), Bitboard ), White_knight_bb_compare = bitboard:'and'( erlang:element(12, Board), Bitboard ), White_pawns_bb_compare = bitboard:'and'(erlang:element(13, Board), Bitboard), Piece@1 = case erlang:element(2, Bitboard) of 0 -> none; _ -> Piece = case Bitboard of _ when Bitboard =:= Black_king_bb_compare -> {some, {piece, black, king}}; _ when Bitboard =:= Black_queen_bb_compare -> {some, {piece, black, queen}}; _ when Bitboard =:= Black_rook_bb_compare -> {some, {piece, black, rook}}; _ when Bitboard =:= Black_bishop_bb_compare -> {some, {piece, black, bishop}}; _ when Bitboard =:= Black_knight_bb_compare -> {some, {piece, black, knight}}; _ when Bitboard =:= Black_pawns_bb_compare -> {some, {piece, black, pawn}}; _ when Bitboard =:= White_king_bb_compare -> {some, {piece, white, king}}; _ when Bitboard =:= White_queen_bb_compare -> {some, {piece, white, queen}}; _ when Bitboard =:= White_rook_bb_compare -> {some, {piece, white, rook}}; _ when Bitboard =:= White_bishop_bb_compare -> {some, {piece, white, bishop}}; _ when Bitboard =:= White_knight_bb_compare -> {some, {piece, white, knight}}; _ when Bitboard =:= White_pawns_bb_compare -> {some, {piece, white, pawn}}; _ -> none end, Piece end, Piece@1. -spec remove_piece_at_position(board_bb(), position:position()) -> board_bb(). remove_piece_at_position(Board, Position) -> Bitboard = bitboard:'not'(from_position(Position)), New_board = case get_piece_at_position(Board, Position) of none -> Board; {some, {piece, Color, Kind}} when (Color =:= white) andalso (Kind =:= king) -> erlang:setelement( 8, Board, bitboard:'and'(Bitboard, erlang:element(8, Board)) ); {some, {piece, Color@1, Kind@1}} when (Color@1 =:= white) andalso (Kind@1 =:= queen) -> erlang:setelement( 9, Board, bitboard:'and'(Bitboard, erlang:element(9, Board)) ); {some, {piece, Color@2, Kind@2}} when (Color@2 =:= white) andalso (Kind@2 =:= rook) -> erlang:setelement( 10, Board, bitboard:'and'(Bitboard, erlang:element(10, Board)) ); {some, {piece, Color@3, Kind@3}} when (Color@3 =:= white) andalso (Kind@3 =:= bishop) -> erlang:setelement( 11, Board, bitboard:'and'(Bitboard, erlang:element(11, Board)) ); {some, {piece, Color@4, Kind@4}} when (Color@4 =:= white) andalso (Kind@4 =:= knight) -> erlang:setelement( 12, Board, bitboard:'and'(Bitboard, erlang:element(12, Board)) ); {some, {piece, Color@5, Kind@5}} when (Color@5 =:= white) andalso (Kind@5 =:= pawn) -> erlang:setelement( 13, Board, bitboard:'and'(Bitboard, erlang:element(13, Board)) ); {some, {piece, Color@6, Kind@6}} when (Color@6 =:= black) andalso (Kind@6 =:= king) -> erlang:setelement( 2, Board, bitboard:'and'(Bitboard, erlang:element(2, Board)) ); {some, {piece, Color@7, Kind@7}} when (Color@7 =:= black) andalso (Kind@7 =:= queen) -> erlang:setelement( 3, Board, bitboard:'and'(Bitboard, erlang:element(3, Board)) ); {some, {piece, Color@8, Kind@8}} when (Color@8 =:= black) andalso (Kind@8 =:= rook) -> erlang:setelement( 4, Board, bitboard:'and'(Bitboard, erlang:element(4, Board)) ); {some, {piece, Color@9, Kind@9}} when (Color@9 =:= black) andalso (Kind@9 =:= bishop) -> erlang:setelement( 5, Board, bitboard:'and'(Bitboard, erlang:element(5, Board)) ); {some, {piece, Color@10, Kind@10}} when (Color@10 =:= black) andalso (Kind@10 =:= knight) -> erlang:setelement( 6, Board, bitboard:'and'(Bitboard, erlang:element(6, Board)) ); {some, {piece, Color@11, Kind@11}} when (Color@11 =:= black) andalso (Kind@11 =:= pawn) -> erlang:setelement( 7, Board, bitboard:'and'(Bitboard, erlang:element(7, Board)) ); _ -> (erlang:error(#{gleam_error => panic, message => <<"panic expression evaluated"/utf8>>, module => <<"board"/utf8>>, function => <<"remove_piece_at_position"/utf8>>, line => 114}))(<<"Invalid piece"/utf8>>) end, New_board.