-module(game). -compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). -export([to_fen/1, new_game_without_status/0, new_game/0, from_fen_string/1, print_board/1, disable_status/1, apply_move_uci/2, undo_move/1, all_legal_moves/1, apply_move/2, apply_move_san_string/2, load_pgn/1, print_board_from_fen/1]). -export_type([game/0]). -type game() :: {game, board:board_bb(), color:color(), list(move:move()), gleam@option:option(status:status()), integer(), castle_rights:castle_rights(), castle_rights:castle_rights(), castle_rights:castle_rights(), castle_rights:castle_rights(), gleam@option:option(position:position())}. -spec to_fen(game()) -> binary(). to_fen(Game) -> Halfmove@1 = case erlang:element(5, Game) of none -> 0; {some, {in_progress, Halfmove, _}} -> Halfmove; {some, {draw, _}} -> 0; {some, _} -> 0 end, Game_fen = {fen, erlang:element(2, Game), erlang:element(3, Game), {castling_status, castle_rights:to_bool(erlang:element(7, Game)), castle_rights:to_bool(erlang:element(8, Game)), castle_rights:to_bool(erlang:element(9, Game)), castle_rights:to_bool(erlang:element(10, Game))}, erlang:element(11, Game), Halfmove@1, (erlang:element(6, Game) div 2) + 1}, fen:to_string(Game_fen). -spec new_game_without_status() -> game(). new_game_without_status() -> White_king_bitboard = {bitboard, 2#0000000000000000000000000000000000000000000000000000000000001000}, White_queen_bitboard = {bitboard, 2#0000000000000000000000000000000000000000000000000000000000010000}, White_rook_bitboard = {bitboard, 2#0000000000000000000000000000000000000000000000000000000010000001}, White_bishop_bitboard = {bitboard, 2#0000000000000000000000000000000000000000000000000000000000100100}, White_knight_bitboard = {bitboard, 2#0000000000000000000000000000000000000000000000000000000001000010}, White_pawns_bitboard = {bitboard, 2#0000000000000000000000000000000000000000000000001111111100000000}, Black_king_bitboard = {bitboard, 2#0000100000000000000000000000000000000000000000000000000000000000}, Black_queen_bitboard = {bitboard, 2#0001000000000000000000000000000000000000000000000000000000000000}, Black_rook_bitboard = {bitboard, 2#1000000100000000000000000000000000000000000000000000000000000000}, Black_bishop_bitboard = {bitboard, 2#0010010000000000000000000000000000000000000000000000000000000000}, Black_knight_bitboard = {bitboard, 2#0100001000000000000000000000000000000000000000000000000000000000}, Black_pawns_bitboard = {bitboard, 2#0000000011111111000000000000000000000000000000000000000000000000}, Board = {board_bb, Black_king_bitboard, Black_queen_bitboard, Black_rook_bitboard, Black_bishop_bitboard, Black_knight_bitboard, Black_pawns_bitboard, White_king_bitboard, White_queen_bitboard, White_rook_bitboard, White_bishop_bitboard, White_knight_bitboard, White_pawns_bitboard}, Turn = white, History = [], Status = none, Ply = 0, {game, Board, Turn, History, Status, Ply, yes, yes, yes, yes, none}. -spec new_game() -> game(). new_game() -> White_king_bitboard = {bitboard, 2#0000000000000000000000000000000000000000000000000000000000010000}, White_queen_bitboard = {bitboard, 2#0000000000000000000000000000000000000000000000000000000000001000}, White_rook_bitboard = {bitboard, 2#0000000000000000000000000000000000000000000000000000000010000001}, White_bishop_bitboard = {bitboard, 2#0000000000000000000000000000000000000000000000000000000000100100}, White_knight_bitboard = {bitboard, 2#0000000000000000000000000000000000000000000000000000000001000010}, White_pawns_bitboard = {bitboard, 2#0000000000000000000000000000000000000000000000001111111100000000}, Black_king_bitboard = {bitboard, 2#0001000000000000000000000000000000000000000000000000000000000000}, Black_queen_bitboard = {bitboard, 2#0000100000000000000000000000000000000000000000000000000000000000}, Black_rook_bitboard = {bitboard, 2#1000000100000000000000000000000000000000000000000000000000000000}, Black_bishop_bitboard = {bitboard, 2#0010010000000000000000000000000000000000000000000000000000000000}, Black_knight_bitboard = {bitboard, 2#0100001000000000000000000000000000000000000000000000000000000000}, Black_pawns_bitboard = {bitboard, 2#0000000011111111000000000000000000000000000000000000000000000000}, Board = {board_bb, Black_king_bitboard, Black_queen_bitboard, Black_rook_bitboard, Black_bishop_bitboard, Black_knight_bitboard, Black_pawns_bitboard, White_king_bitboard, White_queen_bitboard, White_rook_bitboard, White_bishop_bitboard, White_knight_bitboard, White_pawns_bitboard}, Turn = white, History = [], Status = {in_progress, 0, gleam@map:new()}, Ply = 0, {game, Board, Turn, History, {some, Status}, Ply, yes, yes, yes, yes, none}. -spec from_fen_string(binary()) -> game(). from_fen_string(Fen_string) -> Fen = fen:from_string(Fen_string), Status = {in_progress, erlang:element(6, Fen), gleam@map:new()}, Ply = case erlang:element(3, Fen) of white -> (erlang:element(7, Fen) - 1) * 2; black -> ((erlang:element(7, Fen) - 1) * 2) + 1 end, White_kingside_castle = case erlang:element(2, erlang:element(4, Fen)) of true -> yes; false -> {no, 1} end, White_queenside_castle = case erlang:element(3, erlang:element(4, Fen)) of true -> yes; false -> {no, 1} end, Black_kingside_castle = case erlang:element(4, erlang:element(4, Fen)) of true -> yes; false -> {no, 2} end, Black_queenside_castle = case erlang:element(5, erlang:element(4, Fen)) of true -> yes; false -> {no, 2} end, {game, erlang:element(2, Fen), erlang:element(3, Fen), [], {some, Status}, Ply, White_kingside_castle, White_queenside_castle, Black_kingside_castle, Black_queenside_castle, erlang:element(5, Fen)}. -spec apply_pseudo_legal_move(game(), move:move()) -> game(). apply_pseudo_legal_move(Game, Move) -> case Move of {normal, From, To, Captured_piece, Promo_piece} -> _assert_subject = board:get_piece_at_position( erlang:element(2, Game), From ), {some, Moving_piece} = 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 => <<"game"/utf8>>, function => <<"apply_pseudo_legal_move"/utf8>>, line => 538}) end, New_game_state = case Captured_piece of none -> Game; {some, _} -> _assert_subject@1 = board:remove_piece_at_position( erlang:element(2, Game), To ), {some, New_board} = case _assert_subject@1 of {some, _} -> _assert_subject@1; _assert_fail@1 -> erlang:error(#{gleam_error => let_assert, message => <<"Assertion pattern match failed"/utf8>>, value => _assert_fail@1, module => <<"game"/utf8>>, function => <<"apply_pseudo_legal_move"/utf8>>, line => 543}) end, erlang:setelement(2, Game, New_board) end, New_game_state@1 = case Promo_piece of none -> erlang:setelement( 2, New_game_state, board:set_piece_at_position( erlang:element(2, New_game_state), To, Moving_piece ) ); {some, Promo_piece@1} -> erlang:setelement( 2, New_game_state, board:set_piece_at_position( erlang:element(2, New_game_state), To, Promo_piece@1 ) ) end, _assert_subject@2 = board:remove_piece_at_position( erlang:element(2, New_game_state@1), From ), {some, New_board@1} = case _assert_subject@2 of {some, _} -> _assert_subject@2; _assert_fail@2 -> erlang:error(#{gleam_error => let_assert, message => <<"Assertion pattern match failed"/utf8>>, value => _assert_fail@2, module => <<"game"/utf8>>, function => <<"apply_pseudo_legal_move"/utf8>>, line => 571}) end, New_game_state@2 = erlang:setelement( 2, New_game_state@1, New_board@1 ), New_ply = erlang:element(6, New_game_state@2) + 1, New_white_king_castle = case erlang:element(3, Game) of white -> case erlang:element(7, Game) of yes -> case From of {position, e, one} -> {no, New_ply}; {position, h, one} -> {no, New_ply}; _ -> yes end; {no, Some_ply} -> {no, Some_ply} end; black -> erlang:element(7, Game) end, New_white_queen_castle = case erlang:element(3, Game) of white -> case erlang:element(8, Game) of yes -> case From of {position, e, one} -> {no, New_ply}; {position, a, one} -> {no, New_ply}; _ -> yes end; {no, Some_ply@1} -> {no, Some_ply@1} end; black -> erlang:element(8, Game) end, New_black_king_castle = case erlang:element(3, Game) of white -> erlang:element(9, Game); black -> case erlang:element(9, Game) of yes -> case From of {position, e, eight} -> {no, New_ply}; {position, h, eight} -> {no, New_ply}; _ -> yes end; {no, Some_ply@2} -> {no, Some_ply@2} end end, New_black_queen_castle = case erlang:element(3, Game) of white -> erlang:element(10, Game); black -> case erlang:element(10, Game) of yes -> case From of {position, e, eight} -> {no, New_ply}; {position, a, eight} -> {no, New_ply}; _ -> yes end; {no, Some_ply@3} -> {no, Some_ply@3} end end, New_turn = (case erlang:element(3, Game) of white -> black; black -> white end), New_history = [Move | erlang:element(4, Game)], New_en_passant = case Moving_piece of {piece, Color, pawn} -> case Color of white -> case From of {position, _, two} -> case To of {position, _, four} -> {some, {position, erlang:element(2, From), three}}; _ -> none end; _ -> none end; black -> case From of {position, _, seven} -> case To of {position, _, five} -> {some, {position, erlang:element(2, From), six}}; _ -> none end; _ -> none end end; _ -> none end, New_status@2 = case erlang:element(5, Game) of none -> none; {some, {in_progress, Fifty_move_rule, Threefold_repetition_rule}} -> New_fifty_move_rule = case Captured_piece of {some, _} -> 0; none -> case Moving_piece of {piece, _, pawn} -> 0; _ -> Fifty_move_rule + 1 end end, New_status = case (New_fifty_move_rule div 2) + 1 of 50 -> {some, {draw, fifty_move_rule}}; _ -> {some, {in_progress, New_fifty_move_rule, Threefold_repetition_rule}} end, {New_threefold_repetition_rule@3, Count@2} = case Captured_piece of {some, _} -> {Threefold_repetition_rule, 0}; none -> New_threefold_position = {three_fold_position, erlang:element(3, Game), erlang:element(2, Game), erlang:element(11, Game), erlang:element(7, Game), erlang:element(8, Game), erlang:element(9, Game), erlang:element(10, Game)}, {New_threefold_repetition_rule@2, Count@1} = case gleam@map:get( Threefold_repetition_rule, New_threefold_position ) of {error, _} -> New_threefold_repetition_rule = gleam@map:insert( Threefold_repetition_rule, New_threefold_position, 1 ), {New_threefold_repetition_rule, 1}; {ok, Count} -> New_threefold_repetition_rule@1 = gleam@map:insert( Threefold_repetition_rule, New_threefold_position, Count + 1 ), {New_threefold_repetition_rule@1, Count + 1} end, {New_threefold_repetition_rule@2, Count@1} end, New_status@1 = case New_status of {some, {in_progress, Fifty_move_rule@1, _}} -> case Count@2 of 3 -> {some, {draw, threefold_repetition}}; _ -> {some, {in_progress, Fifty_move_rule@1, New_threefold_repetition_rule@3}} end; _ -> New_status end, New_status@1; {some, _} -> (erlang:error(#{gleam_error => panic, message => <<"panic expression evaluated"/utf8>>, module => <<"game"/utf8>>, function => <<"apply_pseudo_legal_move"/utf8>>, line => 757}))( <<"game is over, unable to apply moves to board"/utf8>> ) end, New_game_state@3 = erlang:setelement( 11, erlang:setelement( 10, erlang:setelement( 9, erlang:setelement( 8, erlang:setelement( 7, erlang:setelement( 5, erlang:setelement( 6, erlang:setelement( 4, erlang:setelement( 3, New_game_state@2, New_turn ), New_history ), New_ply ), New_status@2 ), New_white_king_castle ), New_white_queen_castle ), New_black_king_castle ), New_black_queen_castle ), New_en_passant ), New_game_state@3; {castle, From@1, To@1} -> New_game_state@4 = erlang:setelement( 2, Game, board:set_piece_at_position( erlang:element(2, Game), To@1, {piece, erlang:element(3, Game), king} ) ), Rook_castling_target_square = case To@1 of {position, g, one} -> {position, f, one}; {position, g, eight} -> {position, f, eight}; {position, c, one} -> {position, d, one}; {position, c, eight} -> {position, d, eight}; _ -> (erlang:error(#{gleam_error => panic, message => <<"panic expression evaluated"/utf8>>, module => <<"game"/utf8>>, function => <<"apply_pseudo_legal_move"/utf8>>, line => 794}))(<<"Invalid castle move"/utf8>>) end, New_game_state@5 = erlang:setelement( 2, New_game_state@4, board:set_piece_at_position( erlang:element(2, New_game_state@4), Rook_castling_target_square, {piece, erlang:element(3, Game), rook} ) ), _assert_subject@3 = board:remove_piece_at_position( erlang:element(2, New_game_state@5), From@1 ), {some, New_board@2} = case _assert_subject@3 of {some, _} -> _assert_subject@3; _assert_fail@3 -> erlang:error(#{gleam_error => let_assert, message => <<"Assertion pattern match failed"/utf8>>, value => _assert_fail@3, module => <<"game"/utf8>>, function => <<"apply_pseudo_legal_move"/utf8>>, line => 806}) end, New_game_state@6 = erlang:setelement( 2, New_game_state@5, New_board@2 ), Rook_castling_origin_square = case To@1 of {position, g, one} -> {position, h, one}; {position, g, eight} -> {position, h, eight}; {position, c, one} -> {position, a, one}; {position, c, eight} -> {position, a, eight}; _ -> (erlang:error(#{gleam_error => panic, message => <<"panic expression evaluated"/utf8>>, module => <<"game"/utf8>>, function => <<"apply_pseudo_legal_move"/utf8>>, line => 819}))(<<"Invalid castle move"/utf8>>) end, _assert_subject@4 = board:remove_piece_at_position( erlang:element(2, New_game_state@6), Rook_castling_origin_square ), {some, New_board@3} = case _assert_subject@4 of {some, _} -> _assert_subject@4; _assert_fail@4 -> erlang:error(#{gleam_error => let_assert, message => <<"Assertion pattern match failed"/utf8>>, value => _assert_fail@4, module => <<"game"/utf8>>, function => <<"apply_pseudo_legal_move"/utf8>>, line => 822}) end, New_game_state@7 = erlang:setelement( 2, New_game_state@6, New_board@3 ), New_ply@1 = erlang:element(6, New_game_state@7) + 1, [New_white_king_castle@1, New_white_queen_castle@1, New_black_king_castle@1, New_black_queen_castle@1] = case erlang:element(3, Game) of white -> [{no, New_ply@1}, {no, New_ply@1}, erlang:element(9, Game), erlang:element(10, Game)]; black -> [erlang:element(7, Game), erlang:element(8, Game), {no, New_ply@1}, {no, New_ply@1}] end, New_turn@1 = (case erlang:element(3, Game) of white -> black; black -> white end), New_history@1 = [Move | erlang:element(4, Game)], New_status@3 = case erlang:element(5, Game) of none -> none; {some, {in_progress, Fifty_move_rule@2, Threefold_repetition_rule@1}} -> New_fifty_move_rule@1 = Fifty_move_rule@2 + 1, case (New_fifty_move_rule@1 div 2) + 1 of 50 -> {some, {draw, fifty_move_rule}}; _ -> {some, {in_progress, New_fifty_move_rule@1, Threefold_repetition_rule@1}} end; {some, _} -> (erlang:error(#{gleam_error => panic, message => <<"panic expression evaluated"/utf8>>, module => <<"game"/utf8>>, function => <<"apply_pseudo_legal_move"/utf8>>, line => 878}))( <<"game is over, unable to apply moves to board"/utf8>> ) end, New_game_state@8 = erlang:setelement( 10, erlang:setelement( 9, erlang:setelement( 8, erlang:setelement( 7, erlang:setelement( 5, erlang:setelement( 6, erlang:setelement( 4, erlang:setelement( 3, New_game_state@7, New_turn@1 ), New_history@1 ), New_ply@1 ), New_status@3 ), New_white_king_castle@1 ), New_white_queen_castle@1 ), New_black_king_castle@1 ), New_black_queen_castle@1 ), New_game_state@8; {en_passant, From@2, To@2} -> New_game_state@9 = erlang:setelement( 2, Game, board:set_piece_at_position( erlang:element(2, Game), To@2, {piece, erlang:element(3, Game), pawn} ) ), _assert_subject@5 = board:remove_piece_at_position( erlang:element(2, New_game_state@9), From@2 ), {some, New_board@4} = case _assert_subject@5 of {some, _} -> _assert_subject@5; _assert_fail@5 -> erlang:error(#{gleam_error => let_assert, message => <<"Assertion pattern match failed"/utf8>>, value => _assert_fail@5, module => <<"game"/utf8>>, function => <<"apply_pseudo_legal_move"/utf8>>, line => 906}) end, New_game_state@10 = erlang:setelement( 2, New_game_state@9, New_board@4 ), Captured_pawn_square = case To@2 of {position, a, three} -> {position, a, four}; {position, a, six} -> {position, a, five}; {position, b, three} -> {position, b, four}; {position, b, six} -> {position, b, five}; {position, c, three} -> {position, c, four}; {position, c, six} -> {position, c, five}; {position, d, three} -> {position, d, four}; {position, d, six} -> {position, d, five}; {position, e, three} -> {position, e, four}; {position, e, six} -> {position, e, five}; {position, f, three} -> {position, f, four}; {position, f, six} -> {position, f, five}; {position, g, three} -> {position, g, four}; {position, g, six} -> {position, g, five}; {position, h, three} -> {position, h, four}; {position, h, six} -> {position, h, five}; _ -> (erlang:error(#{gleam_error => panic, message => <<"panic expression evaluated"/utf8>>, module => <<"game"/utf8>>, function => <<"apply_pseudo_legal_move"/utf8>>, line => 943}))(<<"Invalid en passant move"/utf8>>) end, New_board@6 = case board:remove_piece_at_position( erlang:element(2, New_game_state@10), Captured_pawn_square ) of {some, New_board@5} -> New_board@5; none -> (erlang:error(#{gleam_error => panic, message => <<"panic expression evaluated"/utf8>>, module => <<"game"/utf8>>, function => <<"apply_pseudo_legal_move"/utf8>>, line => 954}))(<<"Invalid en passant move"/utf8>>) end, New_game_state@11 = erlang:setelement( 2, New_game_state@10, New_board@6 ), New_history@2 = [Move | erlang:element(4, Game)], New_ply@2 = erlang:element(6, New_game_state@11) + 1, New_status@4 = case erlang:element(5, Game) of none -> none; {some, {in_progress, _, Threefold_repetition_rule@2}} -> {some, {in_progress, 0, Threefold_repetition_rule@2}}; {some, _} -> (erlang:error(#{gleam_error => panic, message => <<"panic expression evaluated"/utf8>>, module => <<"game"/utf8>>, function => <<"apply_pseudo_legal_move"/utf8>>, line => 974}))( <<"game is over, unable to apply moves to board"/utf8>> ) end, New_game_state@12 = erlang:setelement( 5, erlang:setelement( 6, erlang:setelement(4, New_game_state@11, New_history@2), New_ply@2 ), New_status@4 ), New_game_state@12 end. -spec look_up_east_ray_bb(position:position()) -> bitboard:bitboard(). look_up_east_ray_bb(Origin_square) -> case Origin_square of {position, a, one} -> {bitboard, 2#0000000000000000000000000000000000000000000000000000000011111110}; {position, a, two} -> {bitboard, 2#0000000000000000000000000000000000000000000000001111111000000000}; {position, a, three} -> {bitboard, 2#0000000000000000000000000000000000000000111111100000000000000000}; {position, a, four} -> {bitboard, 2#0000000000000000000000000000000011111110000000000000000000000000}; {position, a, five} -> {bitboard, 2#0000000000000000000000001111111000000000000000000000000000000000}; {position, a, six} -> {bitboard, 2#0000000000000000111111100000000000000000000000000000000000000000}; {position, a, seven} -> {bitboard, 2#0000000011111110000000000000000000000000000000000000000000000000}; {position, a, eight} -> {bitboard, 2#1111111000000000000000000000000000000000000000000000000000000000}; {position, b, one} -> {bitboard, 2#0000000000000000000000000000000000000000000000000000000011111100}; {position, b, two} -> {bitboard, 2#0000000000000000000000000000000000000000000000001111110000000000}; {position, b, three} -> {bitboard, 2#0000000000000000000000000000000000000000111111000000000000000000}; {position, b, four} -> {bitboard, 2#0000000000000000000000000000000011111100000000000000000000000000}; {position, b, five} -> {bitboard, 2#0000000000000000000000001111110000000000000000000000000000000000}; {position, b, six} -> {bitboard, 2#0000000000000000111111000000000000000000000000000000000000000000}; {position, b, seven} -> {bitboard, 2#0000000011111100000000000000000000000000000000000000000000000000}; {position, b, eight} -> {bitboard, 2#1111110000000000000000000000000000000000000000000000000000000000}; {position, c, one} -> {bitboard, 2#0000000000000000000000000000000000000000000000000000000011111000}; {position, c, two} -> {bitboard, 2#0000000000000000000000000000000000000000000000001111100000000000}; {position, c, three} -> {bitboard, 2#0000000000000000000000000000000000000000111110000000000000000000}; {position, c, four} -> {bitboard, 2#0000000000000000000000000000000011111000000000000000000000000000}; {position, c, five} -> {bitboard, 2#0000000000000000000000001111100000000000000000000000000000000000}; {position, c, six} -> {bitboard, 2#0000000000000000111110000000000000000000000000000000000000000000}; {position, c, seven} -> {bitboard, 2#0000000011111000000000000000000000000000000000000000000000000000}; {position, c, eight} -> {bitboard, 2#1111100000000000000000000000000000000000000000000000000000000000}; {position, d, one} -> {bitboard, 2#0000000000000000000000000000000000000000000000000000000011110000}; {position, d, two} -> {bitboard, 2#0000000000000000000000000000000000000000000000001111000000000000}; {position, d, three} -> {bitboard, 2#0000000000000000000000000000000000000000111100000000000000000000}; {position, d, four} -> {bitboard, 2#0000000000000000000000000000000011110000000000000000000000000000}; {position, d, five} -> {bitboard, 2#0000000000000000000000001111000000000000000000000000000000000000}; {position, d, six} -> {bitboard, 2#0000000000000000111100000000000000000000000000000000000000000000}; {position, d, seven} -> {bitboard, 2#0000000011110000000000000000000000000000000000000000000000000000}; {position, d, eight} -> {bitboard, 2#1111000000000000000000000000000000000000000000000000000000000000}; {position, e, one} -> {bitboard, 2#0000000000000000000000000000000000000000000000000000000011100000}; {position, e, two} -> {bitboard, 2#0000000000000000000000000000000000000000000000001110000000000000}; {position, e, three} -> {bitboard, 2#0000000000000000000000000000000000000000111000000000000000000000}; {position, e, four} -> {bitboard, 2#0000000000000000000000000000000011100000000000000000000000000000}; {position, e, five} -> {bitboard, 2#0000000000000000000000001110000000000000000000000000000000000000}; {position, e, six} -> {bitboard, 2#0000000000000000111000000000000000000000000000000000000000000000}; {position, e, seven} -> {bitboard, 2#0000000011100000000000000000000000000000000000000000000000000000}; {position, e, eight} -> {bitboard, 2#1110000000000000000000000000000000000000000000000000000000000000}; {position, f, one} -> {bitboard, 2#0000000000000000000000000000000000000000000000000000000011000000}; {position, f, two} -> {bitboard, 2#0000000000000000000000000000000000000000000000001100000000000000}; {position, f, three} -> {bitboard, 2#0000000000000000000000000000000000000000110000000000000000000000}; {position, f, four} -> {bitboard, 2#0000000000000000000000000000000011000000000000000000000000000000}; {position, f, five} -> {bitboard, 2#0000000000000000000000001100000000000000000000000000000000000000}; {position, f, six} -> {bitboard, 2#0000000000000000110000000000000000000000000000000000000000000000}; {position, f, seven} -> {bitboard, 2#0000000011000000000000000000000000000000000000000000000000000000}; {position, f, eight} -> {bitboard, 2#1100000000000000000000000000000000000000000000000000000000000000}; {position, g, one} -> {bitboard, 2#0000000000000000000000000000000000000000000000000000000010000000}; {position, g, two} -> {bitboard, 2#0000000000000000000000000000000000000000000000001000000000000000}; {position, g, three} -> {bitboard, 2#0000000000000000000000000000000000000000100000000000000000000000}; {position, g, four} -> {bitboard, 2#0000000000000000000000000000000010000000000000000000000000000000}; {position, g, five} -> {bitboard, 2#0000000000000000000000001000000000000000000000000000000000000000}; {position, g, six} -> {bitboard, 2#0000000000000000100000000000000000000000000000000000000000000000}; {position, g, seven} -> {bitboard, 2#0000000010000000000000000000000000000000000000000000000000000000}; {position, g, eight} -> {bitboard, 2#1000000000000000000000000000000000000000000000000000000000000000}; {position, h, one} -> {bitboard, 2#0000000000000000000000000000000000000000000000000000000000000000}; {position, h, two} -> {bitboard, 2#0000000000000000000000000000000000000000000000000000000000000000}; {position, h, three} -> {bitboard, 2#0000000000000000000000000000000000000000000000000000000000000000}; {position, h, four} -> {bitboard, 2#0000000000000000000000000000000000000000000000000000000000000000}; {position, h, five} -> {bitboard, 2#0000000000000000000000000000000000000000000000000000000000000000}; {position, h, six} -> {bitboard, 2#0000000000000000000000000000000000000000000000000000000000000000}; {position, h, seven} -> {bitboard, 2#0000000000000000000000000000000000000000000000000000000000000000}; {position, h, eight} -> {bitboard, 2#0000000000000000000000000000000000000000000000000000000000000000} end. -spec look_up_north_ray_bb(position:position()) -> bitboard:bitboard(). look_up_north_ray_bb(Origin_square) -> case Origin_square of {position, a, eight} -> {bitboard, 2#0000000000000000000000000000000000000000000000000000000000000000}; {position, a, seven} -> {bitboard, 2#0000000100000000000000000000000000000000000000000000000000000000}; {position, a, six} -> {bitboard, 2#0000000100000001000000000000000000000000000000000000000000000000}; {position, a, five} -> {bitboard, 2#0000000100000001000000010000000000000000000000000000000000000000}; {position, a, four} -> {bitboard, 2#0000000100000001000000010000000100000000000000000000000000000000}; {position, a, three} -> {bitboard, 2#0000000100000001000000010000000100000001000000000000000000000000}; {position, a, two} -> {bitboard, 2#0000000100000001000000010000000100000001000000010000000000000000}; {position, a, one} -> {bitboard, 2#0000000100000001000000010000000100000001000000010000000100000000}; {position, b, eight} -> {bitboard, 2#0000000000000000000000000000000000000000000000000000000000000000}; {position, b, seven} -> {bitboard, 2#0000001000000000000000000000000000000000000000000000000000000000}; {position, b, six} -> {bitboard, 2#0000001000000010000000000000000000000000000000000000000000000000}; {position, b, five} -> {bitboard, 2#0000001000000010000000100000000000000000000000000000000000000000}; {position, b, four} -> {bitboard, 2#0000001000000010000000100000001000000000000000000000000000000000}; {position, b, three} -> {bitboard, 2#0000001000000010000000100000001000000010000000000000000000000000}; {position, b, two} -> {bitboard, 2#0000001000000010000000100000001000000010000000100000000000000000}; {position, b, one} -> {bitboard, 2#0000001000000010000000100000001000000010000000100000001000000000}; {position, c, eight} -> {bitboard, 2#0000000000000000000000000000000000000000000000000000000000000000}; {position, c, seven} -> {bitboard, 2#0000010000000000000000000000000000000000000000000000000000000000}; {position, c, six} -> {bitboard, 2#0000010000000100000000000000000000000000000000000000000000000000}; {position, c, five} -> {bitboard, 2#0000010000000100000001000000000000000000000000000000000000000000}; {position, c, four} -> {bitboard, 2#0000010000000100000001000000010000000000000000000000000000000000}; {position, c, three} -> {bitboard, 2#0000010000000100000001000000010000000100000000000000000000000000}; {position, c, two} -> {bitboard, 2#0000010000000100000001000000010000000100000001000000000000000000}; {position, c, one} -> {bitboard, 2#0000010000000100000001000000010000000100000001000000010000000000}; {position, d, eight} -> {bitboard, 2#0000000000000000000000000000000000000000000000000000000000000000}; {position, d, seven} -> {bitboard, 2#0000100000000000000000000000000000000000000000000000000000000000}; {position, d, six} -> {bitboard, 2#0000100000001000000000000000000000000000000000000000000000000000}; {position, d, five} -> {bitboard, 2#0000100000001000000010000000000000000000000000000000000000000000}; {position, d, four} -> {bitboard, 2#0000100000001000000010000000100000000000000000000000000000000000}; {position, d, three} -> {bitboard, 2#0000100000001000000010000000100000001000000000000000000000000000}; {position, d, two} -> {bitboard, 2#0000100000001000000010000000100000001000000010000000000000000000}; {position, d, one} -> {bitboard, 2#0000100000001000000010000000100000001000000010000000100000000000}; {position, e, eight} -> {bitboard, 2#0000000000000000000000000000000000000000000000000000000000000000}; {position, e, seven} -> {bitboard, 2#0001000000000000000000000000000000000000000000000000000000000000}; {position, e, six} -> {bitboard, 2#0001000000010000000000000000000000000000000000000000000000000000}; {position, e, five} -> {bitboard, 2#0001000000010000000100000000000000000000000000000000000000000000}; {position, e, four} -> {bitboard, 2#0001000000010000000100000001000000000000000000000000000000000000}; {position, e, three} -> {bitboard, 2#0001000000010000000100000001000000010000000000000000000000000000}; {position, e, two} -> {bitboard, 2#0001000000010000000100000001000000010000000100000000000000000000}; {position, e, one} -> {bitboard, 2#0001000000010000000100000001000000010000000100000001000000000000}; {position, f, eight} -> {bitboard, 2#0000000000000000000000000000000000000000000000000000000000000000}; {position, f, seven} -> {bitboard, 2#0010000000000000000000000000000000000000000000000000000000000000}; {position, f, six} -> {bitboard, 2#0010000000100000000000000000000000000000000000000000000000000000}; {position, f, five} -> {bitboard, 2#0010000000100000001000000000000000000000000000000000000000000000}; {position, f, four} -> {bitboard, 2#0010000000100000001000000010000000000000000000000000000000000000}; {position, f, three} -> {bitboard, 2#0010000000100000001000000010000000100000000000000000000000000000}; {position, f, two} -> {bitboard, 2#0010000000100000001000000010000000100000001000000000000000000000}; {position, f, one} -> {bitboard, 2#0010000000100000001000000010000000100000001000000010000000000000}; {position, g, eight} -> {bitboard, 2#0000000000000000000000000000000000000000000000000000000000000000}; {position, g, seven} -> {bitboard, 2#0100000000000000000000000000000000000000000000000000000000000000}; {position, g, six} -> {bitboard, 2#0100000001000000000000000000000000000000000000000000000000000000}; {position, g, five} -> {bitboard, 2#0100000001000000010000000000000000000000000000000000000000000000}; {position, g, four} -> {bitboard, 2#0100000001000000010000000100000000000000000000000000000000000000}; {position, g, three} -> {bitboard, 2#0100000001000000010000000100000001000000000000000000000000000000}; {position, g, two} -> {bitboard, 2#0100000001000000010000000100000001000000010000000000000000000000}; {position, g, one} -> {bitboard, 2#0100000001000000010000000100000001000000010000000100000000000000}; {position, h, eight} -> {bitboard, 2#0000000000000000000000000000000000000000000000000000000000000000}; {position, h, seven} -> {bitboard, 2#1000000000000000000000000000000000000000000000000000000000000000}; {position, h, six} -> {bitboard, 2#1000000010000000000000000000000000000000000000000000000000000000}; {position, h, five} -> {bitboard, 2#1000000010000000100000000000000000000000000000000000000000000000}; {position, h, four} -> {bitboard, 2#1000000010000000100000001000000000000000000000000000000000000000}; {position, h, three} -> {bitboard, 2#1000000010000000100000001000000010000000000000000000000000000000}; {position, h, two} -> {bitboard, 2#1000000010000000100000001000000010000000100000000000000000000000}; {position, h, one} -> {bitboard, 2#1000000010000000100000001000000010000000100000001000000000000000} end. -spec look_up_west_ray_bb(position:position()) -> bitboard:bitboard(). look_up_west_ray_bb(Origin_square) -> case Origin_square of {position, h, eight} -> {bitboard, 2#0111111100000000000000000000000000000000000000000000000000000000}; {position, h, seven} -> {bitboard, 2#0000000001111111000000000000000000000000000000000000000000000000}; {position, h, six} -> {bitboard, 2#0000000000000000011111110000000000000000000000000000000000000000}; {position, h, five} -> {bitboard, 2#0000000000000000000000000111111100000000000000000000000000000000}; {position, h, four} -> {bitboard, 2#0000000000000000000000000000000001111111000000000000000000000000}; {position, h, three} -> {bitboard, 2#0000000000000000000000000000000000000000011111110000000000000000}; {position, h, two} -> {bitboard, 2#0000000000000000000000000000000000000000000000000111111100000000}; {position, h, one} -> {bitboard, 2#0000000000000000000000000000000000000000000000000000000001111111}; {position, g, eight} -> {bitboard, 2#0011111100000000000000000000000000000000000000000000000000000000}; {position, g, seven} -> {bitboard, 2#0000000000111111000000000000000000000000000000000000000000000000}; {position, g, six} -> {bitboard, 2#0000000000000000001111110000000000000000000000000000000000000000}; {position, g, five} -> {bitboard, 2#0000000000000000000000000011111100000000000000000000000000000000}; {position, g, four} -> {bitboard, 2#0000000000000000000000000000000000111111000000000000000000000000}; {position, g, three} -> {bitboard, 2#0000000000000000000000000000000000000000001111110000000000000000}; {position, g, two} -> {bitboard, 2#0000000000000000000000000000000000000000000000000011111100000000}; {position, g, one} -> {bitboard, 2#0000000000000000000000000000000000000000000000000000000000111111}; {position, f, eight} -> {bitboard, 2#0001111100000000000000000000000000000000000000000000000000000000}; {position, f, seven} -> {bitboard, 2#0000000000011111000000000000000000000000000000000000000000000000}; {position, f, six} -> {bitboard, 2#0000000000000000000111110000000000000000000000000000000000000000}; {position, f, five} -> {bitboard, 2#0000000000000000000000000001111100000000000000000000000000000000}; {position, f, four} -> {bitboard, 2#0000000000000000000000000000000000011111000000000000000000000000}; {position, f, three} -> {bitboard, 2#0000000000000000000000000000000000000000000111110000000000000000}; {position, f, two} -> {bitboard, 2#0000000000000000000000000000000000000000000000000001111100000000}; {position, f, one} -> {bitboard, 2#0000000000000000000000000000000000000000000000000000000000011111}; {position, e, eight} -> {bitboard, 2#0000111100000000000000000000000000000000000000000000000000000000}; {position, e, seven} -> {bitboard, 2#0000000000001111000000000000000000000000000000000000000000000000}; {position, e, six} -> {bitboard, 2#0000000000000000000011110000000000000000000000000000000000000000}; {position, e, five} -> {bitboard, 2#0000000000000000000000000000111100000000000000000000000000000000}; {position, e, four} -> {bitboard, 2#0000000000000000000000000000000000001111000000000000000000000000}; {position, e, three} -> {bitboard, 2#0000000000000000000000000000000000000000000011110000000000000000}; {position, e, two} -> {bitboard, 2#0000000000000000000000000000000000000000000000000000111100000000}; {position, e, one} -> {bitboard, 2#0000000000000000000000000000000000000000000000000000000000001111}; {position, d, eight} -> {bitboard, 2#0000011100000000000000000000000000000000000000000000000000000000}; {position, d, seven} -> {bitboard, 2#0000000000000111000000000000000000000000000000000000000000000000}; {position, d, six} -> {bitboard, 2#0000000000000000000001110000000000000000000000000000000000000000}; {position, d, five} -> {bitboard, 2#0000000000000000000000000000011100000000000000000000000000000000}; {position, d, four} -> {bitboard, 2#0000000000000000000000000000000000000111000000000000000000000000}; {position, d, three} -> {bitboard, 2#0000000000000000000000000000000000000000000001110000000000000000}; {position, d, two} -> {bitboard, 2#0000000000000000000000000000000000000000000000000000011100000000}; {position, d, one} -> {bitboard, 2#0000000000000000000000000000000000000000000000000000000000000111}; {position, c, eight} -> {bitboard, 2#0000001100000000000000000000000000000000000000000000000000000000}; {position, c, seven} -> {bitboard, 2#0000000000000011000000000000000000000000000000000000000000000000}; {position, c, six} -> {bitboard, 2#0000000000000000000000110000000000000000000000000000000000000000}; {position, c, five} -> {bitboard, 2#0000000000000000000000000000001100000000000000000000000000000000}; {position, c, four} -> {bitboard, 2#0000000000000000000000000000000000000011000000000000000000000000}; {position, c, three} -> {bitboard, 2#0000000000000000000000000000000000000000000000110000000000000000}; {position, c, two} -> {bitboard, 2#0000000000000000000000000000000000000000000000000000001100000000}; {position, c, one} -> {bitboard, 2#0000000000000000000000000000000000000000000000000000000000000011}; {position, b, eight} -> {bitboard, 2#0000000100000000000000000000000000000000000000000000000000000000}; {position, b, seven} -> {bitboard, 2#0000000000000001000000000000000000000000000000000000000000000000}; {position, b, six} -> {bitboard, 2#0000000000000000000000010000000000000000000000000000000000000000}; {position, b, five} -> {bitboard, 2#0000000000000000000000000000000100000000000000000000000000000000}; {position, b, four} -> {bitboard, 2#0000000000000000000000000000000000000001000000000000000000000000}; {position, b, three} -> {bitboard, 2#0000000000000000000000000000000000000000000000010000000000000000}; {position, b, two} -> {bitboard, 2#0000000000000000000000000000000000000000000000000000000100000000}; {position, b, one} -> {bitboard, 2#0000000000000000000000000000000000000000000000000000000000000001}; {position, a, eight} -> {bitboard, 2#0000000000000000000000000000000000000000000000000000000000000000}; {position, a, seven} -> {bitboard, 2#0000000000000000000000000000000000000000000000000000000000000000}; {position, a, six} -> {bitboard, 2#0000000000000000000000000000000000000000000000000000000000000000}; {position, a, five} -> {bitboard, 2#0000000000000000000000000000000000000000000000000000000000000000}; {position, a, four} -> {bitboard, 2#0000000000000000000000000000000000000000000000000000000000000000}; {position, a, three} -> {bitboard, 2#0000000000000000000000000000000000000000000000000000000000000000}; {position, a, two} -> {bitboard, 2#0000000000000000000000000000000000000000000000000000000000000000}; {position, a, one} -> {bitboard, 2#0000000000000000000000000000000000000000000000000000000000000000} end. -spec look_up_south_ray_bb(position:position()) -> bitboard:bitboard(). look_up_south_ray_bb(Origin_square) -> case Origin_square of {position, a, eight} -> {bitboard, 2#0000000000000001000000010000000100000001000000010000000100000001}; {position, a, seven} -> {bitboard, 2#0000000000000000000000010000000100000001000000010000000100000001}; {position, a, six} -> {bitboard, 2#0000000000000000000000000000000100000001000000010000000100000001}; {position, a, five} -> {bitboard, 2#0000000000000000000000000000000000000001000000010000000100000001}; {position, a, four} -> {bitboard, 2#0000000000000000000000000000000000000000000000010000000100000001}; {position, a, three} -> {bitboard, 2#0000000000000000000000000000000000000000000000000000000100000001}; {position, a, two} -> {bitboard, 2#0000000000000000000000000000000000000000000000000000000000000001}; {position, a, one} -> {bitboard, 2#0000000000000000000000000000000000000000000000000000000000000000}; {position, b, eight} -> {bitboard, 2#0000000000000010000000100000001000000010000000100000001000000010}; {position, b, seven} -> {bitboard, 2#0000000000000000000000100000001000000010000000100000001000000010}; {position, b, six} -> {bitboard, 2#0000000000000000000000000000001000000010000000100000001000000010}; {position, b, five} -> {bitboard, 2#0000000000000000000000000000000000000010000000100000001000000010}; {position, b, four} -> {bitboard, 2#0000000000000000000000000000000000000000000000100000001000000010}; {position, b, three} -> {bitboard, 2#0000000000000000000000000000000000000000000000000000001000000010}; {position, b, two} -> {bitboard, 2#0000000000000000000000000000000000000000000000000000000000000010}; {position, b, one} -> {bitboard, 2#0000000000000000000000000000000000000000000000000000000000000000}; {position, c, eight} -> {bitboard, 2#0000000000000100000001000000010000000100000001000000010000000100}; {position, c, seven} -> {bitboard, 2#0000000000000000000001000000010000000100000001000000010000000100}; {position, c, six} -> {bitboard, 2#0000000000000000000000000000010000000100000001000000010000000100}; {position, c, five} -> {bitboard, 2#0000000000000000000000000000000000000100000001000000010000000100}; {position, c, four} -> {bitboard, 2#0000000000000000000000000000000000000000000001000000010000000100}; {position, c, three} -> {bitboard, 2#0000000000000000000000000000000000000000000000000000010000000100}; {position, c, two} -> {bitboard, 2#0000000000000000000000000000000000000000000000000000000000000100}; {position, c, one} -> {bitboard, 2#0000000000000000000000000000000000000000000000000000000000000000}; {position, d, eight} -> {bitboard, 2#0000000000001000000010000000100000001000000010000000100000001000}; {position, d, seven} -> {bitboard, 2#0000000000000000000010000000100000001000000010000000100000001000}; {position, d, six} -> {bitboard, 2#0000000000000000000000000000100000001000000010000000100000001000}; {position, d, five} -> {bitboard, 2#0000000000000000000000000000000000001000000010000000100000001000}; {position, d, four} -> {bitboard, 2#0000000000000000000000000000000000000000000010000000100000001000}; {position, d, three} -> {bitboard, 2#0000000000000000000000000000000000000000000000000000100000001000}; {position, d, two} -> {bitboard, 2#0000000000000000000000000000000000000000000000000000000000001000}; {position, d, one} -> {bitboard, 2#0000000000000000000000000000000000000000000000000000000000000000}; {position, e, eight} -> {bitboard, 2#0000000000010000000100000001000000010000000100000001000000010000}; {position, e, seven} -> {bitboard, 2#0000000000000000000100000001000000010000000100000001000000010000}; {position, e, six} -> {bitboard, 2#0000000000000000000000000001000000010000000100000001000000010000}; {position, e, five} -> {bitboard, 2#0000000000000000000000000000000000010000000100000001000000010000}; {position, e, four} -> {bitboard, 2#0000000000000000000000000000000000000000000100000001000000010000}; {position, e, three} -> {bitboard, 2#0000000000000000000000000000000000000000000000000001000000010000}; {position, e, two} -> {bitboard, 2#0000000000000000000000000000000000000000000000000000000000010000}; {position, e, one} -> {bitboard, 2#0000000000000000000000000000000000000000000000000000000000000000}; {position, f, eight} -> {bitboard, 2#0000000000100000001000000010000000100000001000000010000000100000}; {position, f, seven} -> {bitboard, 2#0000000000000000001000000010000000100000001000000010000000100000}; {position, f, six} -> {bitboard, 2#0000000000000000000000000010000000100000001000000010000000100000}; {position, f, five} -> {bitboard, 2#0000000000000000000000000000000000100000001000000010000000100000}; {position, f, four} -> {bitboard, 2#0000000000000000000000000000000000000000001000000010000000100000}; {position, f, three} -> {bitboard, 2#0000000000000000000000000000000000000000000000000010000000100000}; {position, f, two} -> {bitboard, 2#0000000000000000000000000000000000000000000000000000000000100000}; {position, f, one} -> {bitboard, 2#0000000000000000000000000000000000000000000000000000000000000000}; {position, g, eight} -> {bitboard, 2#0000000001000000010000000100000001000000010000000100000001000000}; {position, g, seven} -> {bitboard, 2#0000000000000000010000000100000001000000010000000100000001000000}; {position, g, six} -> {bitboard, 2#0000000000000000000000000100000001000000010000000100000001000000}; {position, g, five} -> {bitboard, 2#0000000000000000000000000000000001000000010000000100000001000000}; {position, g, four} -> {bitboard, 2#0000000000000000000000000000000000000000010000000100000001000000}; {position, g, three} -> {bitboard, 2#0000000000000000000000000000000000000000000000000100000001000000}; {position, g, two} -> {bitboard, 2#0000000000000000000000000000000000000000000000000000000001000000}; {position, g, one} -> {bitboard, 2#0000000000000000000000000000000000000000000000000000000000000000}; {position, h, eight} -> {bitboard, 2#0000000010000000100000001000000010000000100000001000000010000000}; {position, h, seven} -> {bitboard, 2#0000000000000000100000001000000010000000100000001000000010000000}; {position, h, six} -> {bitboard, 2#0000000000000000000000001000000010000000100000001000000010000000}; {position, h, five} -> {bitboard, 2#0000000000000000000000000000000010000000100000001000000010000000}; {position, h, four} -> {bitboard, 2#0000000000000000000000000000000000000000100000001000000010000000}; {position, h, three} -> {bitboard, 2#0000000000000000000000000000000000000000000000001000000010000000}; {position, h, two} -> {bitboard, 2#0000000000000000000000000000000000000000000000000000000010000000}; {position, h, one} -> {bitboard, 2#0000000000000000000000000000000000000000000000000000000000000000} end. -spec look_up_south_west_ray_bb(position:position()) -> bitboard:bitboard(). look_up_south_west_ray_bb(Origin_square) -> case Origin_square of {position, a, eight} -> {bitboard, 2#0000000000000000000000000000000000000000000000000000000000000000}; {position, a, seven} -> {bitboard, 2#0000000000000000000000000000000000000000000000000000000000000000}; {position, a, six} -> {bitboard, 2#0000000000000000000000000000000000000000000000000000000000000000}; {position, a, five} -> {bitboard, 2#0000000000000000000000000000000000000000000000000000000000000000}; {position, a, four} -> {bitboard, 2#0000000000000000000000000000000000000000000000000000000000000000}; {position, a, three} -> {bitboard, 2#0000000000000000000000000000000000000000000000000000000000000000}; {position, a, two} -> {bitboard, 2#0000000000000000000000000000000000000000000000000000000000000000}; {position, a, one} -> {bitboard, 2#0000000000000000000000000000000000000000000000000000000000000000}; {position, b, eight} -> {bitboard, 2#0000000000000001000000000000000000000000000000000000000000000000}; {position, b, seven} -> {bitboard, 2#0000000000000000000000010000000000000000000000000000000000000000}; {position, b, six} -> {bitboard, 2#0000000000000000000000000000000100000000000000000000000000000000}; {position, b, five} -> {bitboard, 2#0000000000000000000000000000000000000001000000000000000000000000}; {position, b, four} -> {bitboard, 2#0000000000000000000000000000000000000000000000010000000000000000}; {position, b, three} -> {bitboard, 2#0000000000000000000000000000000000000000000000000000000100000000}; {position, b, two} -> {bitboard, 2#0000000000000000000000000000000000000000000000000000000000000001}; {position, b, one} -> {bitboard, 2#0000000000000000000000000000000000000000000000000000000000000000}; {position, c, eight} -> {bitboard, 2#0000000000000010000000010000000000000000000000000000000000000000}; {position, c, seven} -> {bitboard, 2#0000000000000000000000100000000100000000000000000000000000000000}; {position, c, six} -> {bitboard, 2#0000000000000000000000000000001000000001000000000000000000000000}; {position, c, five} -> {bitboard, 2#0000000000000000000000000000000000000010000000010000000000000000}; {position, c, four} -> {bitboard, 2#0000000000000000000000000000000000000000000000100000000100000000}; {position, c, three} -> {bitboard, 2#0000000000000000000000000000000000000000000000000000001000000001}; {position, c, two} -> {bitboard, 2#0000000000000000000000000000000000000000000000000000000000000010}; {position, c, one} -> {bitboard, 2#0000000000000000000000000000000000000000000000000000000000000000}; {position, d, eight} -> {bitboard, 2#0000000000000100000000100000000100000000000000000000000000000000}; {position, d, seven} -> {bitboard, 2#0000000000000000000001000000001000000001000000000000000000000000}; {position, d, six} -> {bitboard, 2#0000000000000000000000000000010000000010000000010000000000000000}; {position, d, five} -> {bitboard, 2#0000000000000000000000000000000000000100000000100000000100000000}; {position, d, four} -> {bitboard, 2#0000000000000000000000000000000000000000000001000000001000000001}; {position, d, three} -> {bitboard, 2#0000000000000000000000000000000000000000000000000000010000000010}; {position, d, two} -> {bitboard, 2#0000000000000000000000000000000000000000000000000000000000000100}; {position, d, one} -> {bitboard, 2#0000000000000000000000000000000000000000000000000000000000000000}; {position, e, eight} -> {bitboard, 2#0000000000001000000001000000001000000001000000000000000000000000}; {position, e, seven} -> {bitboard, 2#0000000000000000000010000000010000000010000000010000000000000000}; {position, e, six} -> {bitboard, 2#0000000000000000000000000000100000000100000000100000000100000000}; {position, e, five} -> {bitboard, 2#0000000000000000000000000000000000001000000001000000001000000001}; {position, e, four} -> {bitboard, 2#0000000000000000000000000000000000000000000010000000010000000010}; {position, e, three} -> {bitboard, 2#0000000000000000000000000000000000000000000000000000100000000100}; {position, e, two} -> {bitboard, 2#0000000000000000000000000000000000000000000000000000000000001000}; {position, e, one} -> {bitboard, 2#0000000000000000000000000000000000000000000000000000000000000000}; {position, f, eight} -> {bitboard, 2#0000000000010000000010000000010000000010000000010000000000000000}; {position, f, seven} -> {bitboard, 2#0000000000000000000100000000100000000100000000100000000100000000}; {position, f, six} -> {bitboard, 2#0000000000000000000000000001000000001000000001000000001000000001}; {position, f, five} -> {bitboard, 2#0000000000000000000000000000000000010000000010000000010000000010}; {position, f, four} -> {bitboard, 2#0000000000000000000000000000000000000000000100000000100000000100}; {position, f, three} -> {bitboard, 2#0000000000000000000000000000000000000000000000000001000000001000}; {position, f, two} -> {bitboard, 2#0000000000000000000000000000000000000000000000000000000000010000}; {position, f, one} -> {bitboard, 2#0000000000000000000000000000000000000000000000000000000000000000}; {position, g, eight} -> {bitboard, 2#0000000000100000000100000000100000000100000000100000000100000000}; {position, g, seven} -> {bitboard, 2#0000000000000000001000000001000000001000000001000000001000000001}; {position, g, six} -> {bitboard, 2#0000000000000000000000000010000000010000000010000000010000000010}; {position, g, five} -> {bitboard, 2#0000000000000000000000000000000000100000000100000000100000000100}; {position, g, four} -> {bitboard, 2#0000000000000000000000000000000000000000001000000001000000001000}; {position, g, three} -> {bitboard, 2#0000000000000000000000000000000000000000000000000010000000010000}; {position, g, two} -> {bitboard, 2#0000000000000000000000000000000000000000000000000000000000100000}; {position, g, one} -> {bitboard, 2#0000000000000000000000000000000000000000000000000000000000000000}; {position, h, eight} -> {bitboard, 2#0000000001000000001000000001000000001000000001000000001000000001}; {position, h, seven} -> {bitboard, 2#0000000000000000010000000010000000010000000010000000010000000010}; {position, h, six} -> {bitboard, 2#0000000000000000000000000100000000100000000100000000100000000100}; {position, h, five} -> {bitboard, 2#0000000000000000000000000000000001000000001000000001000000001000}; {position, h, four} -> {bitboard, 2#0000000000000000000000000000000000000000010000000010000000010000}; {position, h, three} -> {bitboard, 2#0000000000000000000000000000000000000000000000000100000000100000}; {position, h, two} -> {bitboard, 2#0000000000000000000000000000000000000000000000000000000001000000}; {position, h, one} -> {bitboard, 2#0000000000000000000000000000000000000000000000000000000000000000} end. -spec look_up_south_east_ray_bb(position:position()) -> bitboard:bitboard(). look_up_south_east_ray_bb(Origin_square) -> case Origin_square of {position, a, eight} -> {bitboard, 2#0000000000000010000001000000100000010000001000000100000010000000}; {position, a, seven} -> {bitboard, 2#0000000000000000000000100000010000001000000100000010000001000000}; {position, a, six} -> {bitboard, 2#0000000000000000000000000000001000000100000010000001000000100000}; {position, a, five} -> {bitboard, 2#0000000000000000000000000000000000000010000001000000100000010000}; {position, a, four} -> {bitboard, 2#0000000000000000000000000000000000000000000000100000010000001000}; {position, a, three} -> {bitboard, 2#0000000000000000000000000000000000000000000000000000001000000100}; {position, a, two} -> {bitboard, 2#0000000000000000000000000000000000000000000000000000000000000010}; {position, a, one} -> {bitboard, 2#0000000000000000000000000000000000000000000000000000000000000000}; {position, b, eight} -> {bitboard, 2#0000000000000100000010000001000000100000010000001000000000000000}; {position, b, seven} -> {bitboard, 2#0000000000000000000001000000100000010000001000000100000010000000}; {position, b, six} -> {bitboard, 2#0000000000000000000000000000010000001000000100000010000001000000}; {position, b, five} -> {bitboard, 2#0000000000000000000000000000000000000100000010000001000000100000}; {position, b, four} -> {bitboard, 2#0000000000000000000000000000000000000000000001000000100000010000}; {position, b, three} -> {bitboard, 2#0000000000000000000000000000000000000000000000000000010000001000}; {position, b, two} -> {bitboard, 2#0000000000000000000000000000000000000000000000000000000000000100}; {position, b, one} -> {bitboard, 2#0000000000000000000000000000000000000000000000000000000000000000}; {position, c, eight} -> {bitboard, 2#0000000000001000000100000010000001000000100000000000000000000000}; {position, c, seven} -> {bitboard, 2#0000000000000000000010000001000000100000010000001000000000000000}; {position, c, six} -> {bitboard, 2#0000000000000000000000000000100000010000001000000100000010000000}; {position, c, five} -> {bitboard, 2#0000000000000000000000000000000000001000000100000010000001000000}; {position, c, four} -> {bitboard, 2#0000000000000000000000000000000000000000000010000001000000100000}; {position, c, three} -> {bitboard, 2#0000000000000000000000000000000000000000000000000000100000010000}; {position, c, two} -> {bitboard, 2#0000000000000000000000000000000000000000000000000000000000001000}; {position, c, one} -> {bitboard, 2#0000000000000000000000000000000000000000000000000000000000000000}; {position, d, eight} -> {bitboard, 2#0000000000010000001000000100000010000000000000000000000000000000}; {position, d, seven} -> {bitboard, 2#0000000000000000000100000010000001000000100000000000000000000000}; {position, d, six} -> {bitboard, 2#0000000000000000000000000001000000100000010000001000000000000000}; {position, d, five} -> {bitboard, 2#0000000000000000000000000000000000010000001000000100000010000000}; {position, d, four} -> {bitboard, 2#0000000000000000000000000000000000000000000100000010000001000000}; {position, d, three} -> {bitboard, 2#0000000000000000000000000000000000000000000000000001000000100000}; {position, d, two} -> {bitboard, 2#0000000000000000000000000000000000000000000000000000000000010000}; {position, d, one} -> {bitboard, 2#0000000000000000000000000000000000000000000000000000000000000000}; {position, e, eight} -> {bitboard, 2#0000000000100000010000001000000000000000000000000000000000000000}; {position, e, seven} -> {bitboard, 2#0000000000000000001000000100000010000000000000000000000000000000}; {position, e, six} -> {bitboard, 2#0000000000000000000000000010000001000000100000000000000000000000}; {position, e, five} -> {bitboard, 2#0000000000000000000000000000000000100000010000001000000000000000}; {position, e, four} -> {bitboard, 2#0000000000000000000000000000000000000000001000000100000010000000}; {position, e, three} -> {bitboard, 2#0000000000000000000000000000000000000000000000000010000001000000}; {position, e, two} -> {bitboard, 2#0000000000000000000000000000000000000000000000000000000000100000}; {position, e, one} -> {bitboard, 2#0000000000000000000000000000000000000000000000000000000000000000}; {position, f, eight} -> {bitboard, 2#0000000001000000100000000000000000000000000000000000000000000000}; {position, f, seven} -> {bitboard, 2#0000000000000000010000001000000000000000000000000000000000000000}; {position, f, six} -> {bitboard, 2#0000000000000000000000000100000010000000000000000000000000000000}; {position, f, five} -> {bitboard, 2#0000000000000000000000000000000001000000100000000000000000000000}; {position, f, four} -> {bitboard, 2#0000000000000000000000000000000000000000010000001000000000000000}; {position, f, three} -> {bitboard, 2#0000000000000000000000000000000000000000000000000100000010000000}; {position, f, two} -> {bitboard, 2#0000000000000000000000000000000000000000000000000000000001000000}; {position, f, one} -> {bitboard, 2#0000000000000000000000000000000000000000000000000000000000000000}; {position, g, eight} -> {bitboard, 2#0000000010000000000000000000000000000000000000000000000000000000}; {position, g, seven} -> {bitboard, 2#0000000000000000100000000000000000000000000000000000000000000000}; {position, g, six} -> {bitboard, 2#0000000000000000000000001000000000000000000000000000000000000000}; {position, g, five} -> {bitboard, 2#0000000000000000000000000000000010000000000000000000000000000000}; {position, g, four} -> {bitboard, 2#0000000000000000000000000000000000000000100000000000000000000000}; {position, g, three} -> {bitboard, 2#0000000000000000000000000000000000000000000000001000000000000000}; {position, g, two} -> {bitboard, 2#0000000000000000000000000000000000000000000000000000000010000000}; {position, g, one} -> {bitboard, 2#0000000000000000000000000000000000000000000000000000000000000000}; {position, h, eight} -> {bitboard, 2#0000000000000000000000000000000000000000000000000000000000000000}; {position, h, seven} -> {bitboard, 2#0000000000000000000000000000000000000000000000000000000000000000}; {position, h, six} -> {bitboard, 2#0000000000000000000000000000000000000000000000000000000000000000}; {position, h, five} -> {bitboard, 2#0000000000000000000000000000000000000000000000000000000000000000}; {position, h, four} -> {bitboard, 2#0000000000000000000000000000000000000000000000000000000000000000}; {position, h, three} -> {bitboard, 2#0000000000000000000000000000000000000000000000000000000000000000}; {position, h, two} -> {bitboard, 2#0000000000000000000000000000000000000000000000000000000000000000}; {position, h, one} -> {bitboard, 2#0000000000000000000000000000000000000000000000000000000000000000} end. -spec look_up_north_east_ray_bb(position:position()) -> bitboard:bitboard(). look_up_north_east_ray_bb(Origin_square) -> case Origin_square of {position, a, one} -> {bitboard, 2#1000000001000000001000000001000000001000000001000000001000000000}; {position, a, two} -> {bitboard, 2#0100000000100000000100000000100000000100000000100000000000000000}; {position, a, three} -> {bitboard, 2#0010000000010000000010000000010000000010000000000000000000000000}; {position, a, four} -> {bitboard, 2#0001000000001000000001000000001000000000000000000000000000000000}; {position, a, five} -> {bitboard, 2#0000100000000100000000100000000000000000000000000000000000000000}; {position, a, six} -> {bitboard, 2#0000010000000010000000000000000000000000000000000000000000000000}; {position, a, seven} -> {bitboard, 2#0000001000000000000000000000000000000000000000000000000000000000}; {position, a, eight} -> {bitboard, 2#0000000000000000000000000000000000000000000000000000000000000000}; {position, b, one} -> {bitboard, 2#0000000010000000010000000010000000010000000010000000010000000000}; {position, b, two} -> {bitboard, 2#1000000001000000001000000001000000001000000001000000000000000000}; {position, b, three} -> {bitboard, 2#0100000000100000000100000000100000000100000000000000000000000000}; {position, b, four} -> {bitboard, 2#0010000000010000000010000000010000000000000000000000000000000000}; {position, b, five} -> {bitboard, 2#0001000000001000000001000000000000000000000000000000000000000000}; {position, b, six} -> {bitboard, 2#0000100000000100000000000000000000000000000000000000000000000000}; {position, b, seven} -> {bitboard, 2#0000010000000000000000000000000000000000000000000000000000000000}; {position, b, eight} -> {bitboard, 2#0000000000000000000000000000000000000000000000000000000000000000}; {position, c, one} -> {bitboard, 2#0000000000000000100000000100000000100000000100000000100000000000}; {position, c, two} -> {bitboard, 2#0000000010000000010000000010000000010000000010000000000000000000}; {position, c, three} -> {bitboard, 2#1000000001000000001000000001000000001000000000000000000000000000}; {position, c, four} -> {bitboard, 2#0100000000100000000100000000100000000000000000000000000000000000}; {position, c, five} -> {bitboard, 2#0010000000010000000010000000000000000000000000000000000000000000}; {position, c, six} -> {bitboard, 2#0001000000001000000000000000000000000000000000000000000000000000}; {position, c, seven} -> {bitboard, 2#0000100000000000000000000000000000000000000000000000000000000000}; {position, c, eight} -> {bitboard, 2#0000000000000000000000000000000000000000000000000000000000000000}; {position, d, one} -> {bitboard, 2#0000000000000000000000001000000001000000001000000001000000000000}; {position, d, two} -> {bitboard, 2#0000000000000000100000000100000000100000000100000000000000000000}; {position, d, three} -> {bitboard, 2#0000000010000000010000000010000000010000000000000000000000000000}; {position, d, four} -> {bitboard, 2#1000000001000000001000000001000000000000000000000000000000000000}; {position, d, five} -> {bitboard, 2#0100000000100000000100000000000000000000000000000000000000000000}; {position, d, six} -> {bitboard, 2#0010000000010000000000000000000000000000000000000000000000000000}; {position, d, seven} -> {bitboard, 2#0001000000000000000000000000000000000000000000000000000000000000}; {position, d, eight} -> {bitboard, 2#0000000000000000000000000000000000000000000000000000000000000000}; {position, e, one} -> {bitboard, 2#0000000000000000000000000000000010000000010000000010000000000000}; {position, e, two} -> {bitboard, 2#0000000000000000000000001000000001000000001000000000000000000000}; {position, e, three} -> {bitboard, 2#0000000000000000100000000100000000100000000000000000000000000000}; {position, e, four} -> {bitboard, 2#0000000010000000010000000010000000000000000000000000000000000000}; {position, e, five} -> {bitboard, 2#1000000001000000001000000000000000000000000000000000000000000000}; {position, e, six} -> {bitboard, 2#0100000000100000000000000000000000000000000000000000000000000000}; {position, e, seven} -> {bitboard, 2#0010000000000000000000000000000000000000000000000000000000000000}; {position, e, eight} -> {bitboard, 2#0000000000000000000000000000000000000000000000000000000000000000}; {position, f, one} -> {bitboard, 2#0000000000000000000000000000000000000000100000000100000000000000}; {position, f, two} -> {bitboard, 2#0000000000000000000000000000000010000000010000000000000000000000}; {position, f, three} -> {bitboard, 2#0000000000000000000000001000000001000000000000000000000000000000}; {position, f, four} -> {bitboard, 2#0000000000000000100000000100000000000000000000000000000000000000}; {position, f, five} -> {bitboard, 2#0000000010000000010000000000000000000000000000000000000000000000}; {position, f, six} -> {bitboard, 2#1000000001000000000000000000000000000000000000000000000000000000}; {position, f, seven} -> {bitboard, 2#0100000000000000000000000000000000000000000000000000000000000000}; {position, f, eight} -> {bitboard, 2#0000000000000000000000000000000000000000000000000000000000000000}; {position, g, one} -> {bitboard, 2#0000000000000000000000000000000000000000000000001000000000000000}; {position, g, two} -> {bitboard, 2#0000000000000000000000000000000000000000100000000000000000000000}; {position, g, three} -> {bitboard, 2#0000000000000000000000000000000010000000000000000000000000000000}; {position, g, four} -> {bitboard, 2#0000000000000000000000001000000000000000000000000000000000000000}; {position, g, five} -> {bitboard, 2#0000000000000000100000000000000000000000000000000000000000000000}; {position, g, six} -> {bitboard, 2#0000000010000000000000000000000000000000000000000000000000000000}; {position, g, seven} -> {bitboard, 2#1000000000000000000000000000000000000000000000000000000000000000}; {position, g, eight} -> {bitboard, 2#0000000000000000000000000000000000000000000000000000000000000000}; {position, h, one} -> {bitboard, 2#0000000000000000000000000000000000000000000000000000000010000000}; {position, h, two} -> {bitboard, 2#0000000000000000000000000000000000000000000000000000000000000000}; {position, h, three} -> {bitboard, 2#0000000000000000000000000000000000000000000000000000000000000000}; {position, h, four} -> {bitboard, 2#0000000000000000000000000000000000000000000000000000000000000000}; {position, h, five} -> {bitboard, 2#0000000000000000000000000000000000000000000000000000000000000000}; {position, h, six} -> {bitboard, 2#0000000000000000000000000000000000000000000000000000000000000000}; {position, h, seven} -> {bitboard, 2#0000000000000000000000000000000000000000000000000000000000000000}; {position, h, eight} -> {bitboard, 2#0000000000000000000000000000000000000000000000000000000000000000} end. -spec look_up_north_west_ray_bb(position:position()) -> bitboard:bitboard(). look_up_north_west_ray_bb(Origin_square) -> case Origin_square of {position, a, one} -> {bitboard, 2#0000000000000000000000000000000000000000000000000000000000000000}; {position, a, two} -> {bitboard, 2#0000000000000000000000000000000000000000000000000000000000000000}; {position, a, three} -> {bitboard, 2#0000000000000000000000000000000000000000000000000000000000000000}; {position, a, four} -> {bitboard, 2#0000000000000000000000000000000000000000000000000000000000000000}; {position, a, five} -> {bitboard, 2#0000000000000000000000000000000000000000000000000000000000000000}; {position, a, six} -> {bitboard, 2#0000000000000000000000000000000000000000000000000000000000000000}; {position, a, seven} -> {bitboard, 2#0000000000000000000000000000000000000000000000000000000000000000}; {position, a, eight} -> {bitboard, 2#0000000000000000000000000000000000000000000000000000000000000000}; {position, b, one} -> {bitboard, 2#0000000000000000000000000000000000000000000000000000000100000000}; {position, b, two} -> {bitboard, 2#0000000000000000000000000000000000000000000000010000000000000000}; {position, b, three} -> {bitboard, 2#0000000000000000000000000000000000000001000000000000000000000000}; {position, b, four} -> {bitboard, 2#0000000000000000000000000000000100000000000000000000000000000000}; {position, b, five} -> {bitboard, 2#0000000000000000000000010000000000000000000000000000000000000000}; {position, b, six} -> {bitboard, 2#0000000000000001000000000000000000000000000000000000000000000000}; {position, b, seven} -> {bitboard, 2#0000000100000000000000000000000000000000000000000000000000000000}; {position, b, eight} -> {bitboard, 2#0000000000000000000000000000000000000000000000000000000000000000}; {position, c, one} -> {bitboard, 2#0000000000000000000000000000000000000000000000010000001000000000}; {position, c, two} -> {bitboard, 2#0000000000000000000000000000000000000001000000100000000000000000}; {position, c, three} -> {bitboard, 2#0000000000000000000000000000000100000010000000000000000000000000}; {position, c, four} -> {bitboard, 2#0000000000000000000000010000001000000000000000000000000000000000}; {position, c, five} -> {bitboard, 2#0000000000000001000000100000000000000000000000000000000000000000}; {position, c, six} -> {bitboard, 2#0000000100000010000000000000000000000000000000000000000000000000}; {position, c, seven} -> {bitboard, 2#0000001000000000000000000000000000000000000000000000000000000000}; {position, c, eight} -> {bitboard, 2#0000000000000000000000000000000000000000000000000000000000000000}; {position, d, one} -> {bitboard, 2#0000000000000000000000000000000000000001000000100000010000000000}; {position, d, two} -> {bitboard, 2#0000000000000000000000000000000100000010000001000000000000000000}; {position, d, three} -> {bitboard, 2#0000000000000000000000010000001000000100000000000000000000000000}; {position, d, four} -> {bitboard, 2#0000000000000001000000100000010000000000000000000000000000000000}; {position, d, five} -> {bitboard, 2#0000000100000010000001000000000000000000000000000000000000000000}; {position, d, six} -> {bitboard, 2#0000001000000100000000000000000000000000000000000000000000000000}; {position, d, seven} -> {bitboard, 2#0000010000000000000000000000000000000000000000000000000000000000}; {position, d, eight} -> {bitboard, 2#0000000000000000000000000000000000000000000000000000000000000000}; {position, e, one} -> {bitboard, 2#0000000000000000000000000000000100000010000001000000100000000000}; {position, e, two} -> {bitboard, 2#0000000000000000000000010000001000000100000010000000000000000000}; {position, e, three} -> {bitboard, 2#0000000000000001000000100000010000001000000000000000000000000000}; {position, e, four} -> {bitboard, 2#0000000100000010000001000000100000000000000000000000000000000000}; {position, e, five} -> {bitboard, 2#0000001000000100000010000000000000000000000000000000000000000000}; {position, e, six} -> {bitboard, 2#0000010000001000000000000000000000000000000000000000000000000000}; {position, e, seven} -> {bitboard, 2#0000100000000000000000000000000000000000000000000000000000000000}; {position, e, eight} -> {bitboard, 2#0000000000000000000000000000000000000000000000000000000000000000}; {position, f, one} -> {bitboard, 2#0000000000000000000000010000001000000100000010000001000000000000}; {position, f, two} -> {bitboard, 2#0000000000000001000000100000010000001000000100000000000000000000}; {position, f, three} -> {bitboard, 2#0000000100000010000001000000100000010000000000000000000000000000}; {position, f, four} -> {bitboard, 2#0000001000000100000010000001000000000000000000000000000000000000}; {position, f, five} -> {bitboard, 2#0000010000001000000100000000000000000000000000000000000000000000}; {position, f, six} -> {bitboard, 2#0000100000010000000000000000000000000000000000000000000000000000}; {position, f, seven} -> {bitboard, 2#0001000000000000000000000000000000000000000000000000000000000000}; {position, f, eight} -> {bitboard, 2#0000000000000000000000000000000000000000000000000000000000000000}; {position, g, one} -> {bitboard, 2#0000000000000001000000100000010000001000000100000010000000000000}; {position, g, two} -> {bitboard, 2#0000000100000010000001000000100000010000001000000000000000000000}; {position, g, three} -> {bitboard, 2#0000001000000100000010000001000000100000000000000000000000000000}; {position, g, four} -> {bitboard, 2#0000010000001000000100000010000000000000000000000000000000000000}; {position, g, five} -> {bitboard, 2#0000100000010000001000000000000000000000000000000000000000000000}; {position, g, six} -> {bitboard, 2#0001000000100000000000000000000000000000000000000000000000000000}; {position, g, seven} -> {bitboard, 2#0010000000000000000000000000000000000000000000000000000000000000}; {position, g, eight} -> {bitboard, 2#0000000000000000000000000000000000000000000000000000000000000000}; {position, h, one} -> {bitboard, 2#0000000100000010000001000000100000010000001000000100000000000000}; {position, h, two} -> {bitboard, 2#0000001000000100000010000001000000100000010000000000000000000000}; {position, h, three} -> {bitboard, 2#0000010000001000000100000010000001000000000000000000000000000000}; {position, h, four} -> {bitboard, 2#0000100000010000001000000100000000000000000000000000000000000000}; {position, h, five} -> {bitboard, 2#0001000000100000010000000000000000000000000000000000000000000000}; {position, h, six} -> {bitboard, 2#0010000001000000000000000000000000000000000000000000000000000000}; {position, h, seven} -> {bitboard, 2#0100000000000000000000000000000000000000000000000000000000000000}; {position, h, eight} -> {bitboard, 2#0000000000000000000000000000000000000000000000000000000000000000} end. -spec occupied_squares(board:board_bb()) -> bitboard:bitboard(). occupied_squares(Board) -> List_of_all_piece_bitboards = [erlang:element(8, Board), erlang:element(9, Board), erlang:element(10, Board), erlang:element(11, Board), erlang:element(12, Board), erlang:element(13, Board), erlang:element(2, Board), erlang:element(3, Board), erlang:element(4, Board), erlang:element(5, Board), erlang:element(6, Board), erlang:element(7, Board)], gleam@list:fold( List_of_all_piece_bitboards, {bitboard, 0}, fun(Collector, Next) -> bitboard:'or'(Collector, Next) end ). -spec occupied_squares_white(board:board_bb()) -> bitboard:bitboard(). occupied_squares_white(Board) -> List_of_all_piece_bitboards = [erlang:element(8, Board), erlang:element(9, Board), erlang:element(10, Board), erlang:element(11, Board), erlang:element(12, Board), erlang:element(13, Board)], gleam@list:fold( List_of_all_piece_bitboards, {bitboard, 0}, fun(Collector, Next) -> bitboard:'or'(Collector, Next) end ). -spec occupied_squares_black(board:board_bb()) -> bitboard:bitboard(). occupied_squares_black(Board) -> List_of_all_piece_bitboards = [erlang:element(2, Board), erlang:element(3, Board), erlang:element(4, Board), erlang:element(5, Board), erlang:element(6, Board), erlang:element(7, Board)], gleam@list:fold( List_of_all_piece_bitboards, {bitboard, 0}, fun(Collector, Next) -> bitboard:'or'(Collector, Next) end ). -spec pawn_squares(color:color(), board:board_bb()) -> bitboard:bitboard(). pawn_squares(Color, Board) -> case Color of white -> erlang:element(13, Board); black -> erlang:element(7, Board) end. -spec generate_en_passant_pseudo_legal_move_list(color:color(), game()) -> list(move:move()). generate_en_passant_pseudo_legal_move_list(Color, Game) -> case erlang:element(11, Game) of none -> []; {some, Ep_position} -> Ep_bitboard = position:to_bitboard(Ep_position), Pawn_bitboard = pawn_squares(Color, erlang:element(2, Game)), Ep_attacker_bitboard = case Color of white -> West_east_attacker_bb = bitboard:'and'( bitboard:'and'( bitboard:shift_right(Ep_bitboard, 7), Pawn_bitboard ), {bitboard, 2#1111111011111110111111101111111011111110111111101111111011111110} ), East_west_attacker_bb = bitboard:'and'( bitboard:'and'( bitboard:shift_right(Ep_bitboard, 9), Pawn_bitboard ), {bitboard, 2#0111111101111111011111110111111101111111011111110111111101111111} ), bitboard:'or'(West_east_attacker_bb, East_west_attacker_bb); black -> West_east_attacker_bb@1 = bitboard:'and'( bitboard:'and'( bitboard:shift_left(Ep_bitboard, 7), Pawn_bitboard ), {bitboard, 2#0111111101111111011111110111111101111111011111110111111101111111} ), East_west_attacker_bb@1 = bitboard:'and'( bitboard:'and'( bitboard:shift_left(Ep_bitboard, 9), Pawn_bitboard ), {bitboard, 2#1111111011111110111111101111111011111110111111101111111011111110} ), bitboard:'or'( West_east_attacker_bb@1, East_west_attacker_bb@1 ) end, Ep_attacker_positions = board:get_positions(Ep_attacker_bitboard), Ep_moves = gleam@list:map( Ep_attacker_positions, fun(Position) -> {en_passant, Position, Ep_position} end ), Ep_moves end. -spec generate_castling_pseudo_legal_move_list(color:color(), game()) -> list(move:move()). generate_castling_pseudo_legal_move_list(Color, Game) -> King_bitboard = case Color of white -> erlang:element(8, erlang:element(2, Game)); black -> erlang:element(2, erlang:element(2, Game)) end, [King_position] = case board:get_positions(King_bitboard) of [] -> (erlang:error(#{gleam_error => panic, message => <<"panic expression evaluated"/utf8>>, module => <<"game"/utf8>>, function => <<"generate_castling_pseudo_legal_move_list"/utf8>>, line => 1718}))(<<"No king found on the board"/utf8>>); [Position] -> [Position]; _ -> (erlang:error(#{gleam_error => panic, message => <<"panic expression evaluated"/utf8>>, module => <<"game"/utf8>>, function => <<"generate_castling_pseudo_legal_move_list"/utf8>>, line => 1722}))( <<"More than one king found on the board"/utf8>> ) end, King_position_flag = case King_position of {position, e, one} when Color =:= white -> true; {position, e, eight} when Color =:= black -> true; _ -> false end, Rook_bitboard = case Color of white -> erlang:element(10, erlang:element(2, Game)); black -> erlang:element(4, erlang:element(2, Game)) end, Queenside_rook_flag = case Color of white -> case bitboard:'and'( bitboard:'and'( Rook_bitboard, {bitboard, 2#0000000100000001000000010000000100000001000000010000000100000001} ), {bitboard, 2#0000000000000000000000000000000000000000000000000000000011111111} ) of {bitboard, 0} -> false; _ -> true end; black -> case bitboard:'and'( bitboard:'and'( Rook_bitboard, {bitboard, 2#0000000100000001000000010000000100000001000000010000000100000001} ), {bitboard, 2#1111111100000000000000000000000000000000000000000000000000000000} ) of {bitboard, 0} -> false; _ -> true end end, Kingside_rook_flag = case Color of white -> case bitboard:'and'( bitboard:'and'( Rook_bitboard, {bitboard, 2#1000000010000000100000001000000010000000100000001000000010000000} ), {bitboard, 2#0000000000000000000000000000000000000000000000000000000011111111} ) of {bitboard, 0} -> false; _ -> true end; black -> case bitboard:'and'( bitboard:'and'( Rook_bitboard, {bitboard, 2#1000000010000000100000001000000010000000100000001000000010000000} ), {bitboard, 2#1111111100000000000000000000000000000000000000000000000000000000} ) of {bitboard, 0} -> false; _ -> true end end, Queenside_clear_flag = case Color of white -> case bitboard:'and'( {bitboard, 2#0000000000000000000000000000000000000000000000000000000000001110}, occupied_squares(erlang:element(2, Game)) ) of {bitboard, 0} -> true; _ -> false end; black -> case bitboard:'and'( {bitboard, 2#0000111000000000000000000000000000000000000000000000000000000000}, occupied_squares(erlang:element(2, Game)) ) of {bitboard, 0} -> true; _ -> false end end, Kingside_clear_flag = case Color of white -> case bitboard:'and'( {bitboard, 2#0000000000000000000000000000000000000000000000000000000001100000}, occupied_squares(erlang:element(2, Game)) ) of {bitboard, 0} -> true; _ -> false end; black -> case bitboard:'and'( {bitboard, 2#0110000000000000000000000000000000000000000000000000000000000000}, occupied_squares(erlang:element(2, Game)) ) of {bitboard, 0} -> true; _ -> false end end, Queenside_castle = case Color of white -> erlang:element(8, Game); black -> erlang:element(10, Game) end, Kingside_castle = case Color of white -> erlang:element(7, Game); black -> erlang:element(9, Game) end, Castling_moves = gleam@list:append( case [Queenside_rook_flag, Queenside_clear_flag, King_position_flag] of [true, true, true] when Queenside_castle =:= yes -> case Color of white -> [{castle, King_position, {position, c, one}}]; black -> [{castle, King_position, {position, c, eight}}] end; _ -> [] end, case [Kingside_rook_flag, Kingside_clear_flag, King_position_flag] of [true, true, true] when Kingside_castle =:= yes -> case Color of white -> [{castle, King_position, {position, g, one}}]; black -> [{castle, King_position, {position, g, eight}}] end; _ -> [] end ), Castling_moves. -spec piece_at_position(game(), position:position()) -> gleam@option:option(piece:piece()). piece_at_position(Game, Position) -> Position_bb_masked = bitboard:'and'( position:to_bitboard(Position), occupied_squares(erlang:element(2, Game)) ), Position_white_king = bitboard:'and'( Position_bb_masked, erlang:element(8, erlang:element(2, Game)) ), Position_white_queen = bitboard:'and'( Position_bb_masked, erlang:element(9, erlang:element(2, Game)) ), Position_white_rook = bitboard:'and'( Position_bb_masked, erlang:element(10, erlang:element(2, Game)) ), Position_white_bishop = bitboard:'and'( Position_bb_masked, erlang:element(11, erlang:element(2, Game)) ), Position_white_knight = bitboard:'and'( Position_bb_masked, erlang:element(12, erlang:element(2, Game)) ), Position_white_pawn = bitboard:'and'( Position_bb_masked, erlang:element(13, erlang:element(2, Game)) ), Position_black_king = bitboard:'and'( Position_bb_masked, erlang:element(2, erlang:element(2, Game)) ), Position_black_queen = bitboard:'and'( Position_bb_masked, erlang:element(3, erlang:element(2, Game)) ), Position_black_rook = bitboard:'and'( Position_bb_masked, erlang:element(4, erlang:element(2, Game)) ), Position_black_bishop = bitboard:'and'( Position_bb_masked, erlang:element(5, erlang:element(2, Game)) ), Position_black_knight = bitboard:'and'( Position_bb_masked, erlang:element(6, erlang:element(2, Game)) ), Position_black_pawn = bitboard:'and'( Position_bb_masked, erlang:element(7, erlang:element(2, Game)) ), case Position_bb_masked of {bitboard, 0} -> none; _ when erlang:element(2, Position_white_king) =/= 0 -> {some, {piece, white, king}}; _ when erlang:element(2, Position_white_queen) =/= 0 -> {some, {piece, white, queen}}; _ when erlang:element(2, Position_white_rook) =/= 0 -> {some, {piece, white, rook}}; _ when erlang:element(2, Position_white_bishop) =/= 0 -> {some, {piece, white, bishop}}; _ when erlang:element(2, Position_white_knight) =/= 0 -> {some, {piece, white, knight}}; _ when erlang:element(2, Position_white_pawn) =/= 0 -> {some, {piece, white, pawn}}; _ when erlang:element(2, Position_black_king) =/= 0 -> {some, {piece, black, king}}; _ when erlang:element(2, Position_black_queen) =/= 0 -> {some, {piece, black, queen}}; _ when erlang:element(2, Position_black_rook) =/= 0 -> {some, {piece, black, rook}}; _ when erlang:element(2, Position_black_bishop) =/= 0 -> {some, {piece, black, bishop}}; _ when erlang:element(2, Position_black_knight) =/= 0 -> {some, {piece, black, knight}}; _ when erlang:element(2, Position_black_pawn) =/= 0 -> {some, {piece, black, pawn}} end. -spec generate_king_pseudo_legal_move_list(color:color(), game()) -> list(move:move()). generate_king_pseudo_legal_move_list(Color, Game) -> King_bitboard = case Color of white -> erlang:element(8, erlang:element(2, Game)); black -> erlang:element(2, erlang:element(2, Game)) end, King_origin_squares = board:get_positions(King_bitboard), gleam@list:fold( King_origin_squares, [], fun(Collector, Origin) -> King_bitboard@1 = board:from_position(Origin), North_west_north_east_target_squares = bitboard:'or'( bitboard:'and'( bitboard:shift_left(King_bitboard@1, 9), {bitboard, 2#1111111011111110111111101111111011111110111111101111111011111110} ), bitboard:'and'( bitboard:shift_left(King_bitboard@1, 7), {bitboard, 2#0111111101111111011111110111111101111111011111110111111101111111} ) ), South_west_south_east_target_squares = bitboard:'or'( bitboard:'and'( bitboard:shift_right(King_bitboard@1, 9), {bitboard, 2#0111111101111111011111110111111101111111011111110111111101111111} ), bitboard:'and'( bitboard:shift_right(King_bitboard@1, 7), {bitboard, 2#1111111011111110111111101111111011111110111111101111111011111110} ) ), West_east_target_squares = bitboard:'or'( bitboard:'and'( bitboard:shift_left(King_bitboard@1, 1), {bitboard, 2#1111111011111110111111101111111011111110111111101111111011111110} ), bitboard:'and'( bitboard:shift_right(King_bitboard@1, 1), {bitboard, 2#0111111101111111011111110111111101111111011111110111111101111111} ) ), North_south_target_squares = bitboard:'or'( bitboard:shift_left(King_bitboard@1, 8), bitboard:shift_right(King_bitboard@1, 8) ), King_target_squares = bitboard:'or'( bitboard:'or'( North_west_north_east_target_squares, South_west_south_east_target_squares ), bitboard:'or'( West_east_target_squares, North_south_target_squares ) ), List_of_friendly_piece_bitboards = case Color of white -> [erlang:element(8, erlang:element(2, Game)), erlang:element(9, erlang:element(2, Game)), erlang:element(10, erlang:element(2, Game)), erlang:element(11, erlang:element(2, Game)), erlang:element(12, erlang:element(2, Game)), erlang:element(13, erlang:element(2, Game))]; black -> [erlang:element(2, erlang:element(2, Game)), erlang:element(3, erlang:element(2, Game)), erlang:element(4, erlang:element(2, Game)), erlang:element(5, erlang:element(2, Game)), erlang:element(6, erlang:element(2, Game)), erlang:element(7, erlang:element(2, Game))] end, Friendly_pieces = gleam@list:fold( List_of_friendly_piece_bitboards, {bitboard, 0}, fun(Collector@1, Next) -> bitboard:'or'(Collector@1, Next) end ), King_unblocked_target_square_bb = bitboard:'and'( King_target_squares, bitboard:'not'(Friendly_pieces) ), Captures = case Color of white -> bitboard:'and'( King_unblocked_target_square_bb, occupied_squares_black(erlang:element(2, Game)) ); black -> bitboard:'and'( King_unblocked_target_square_bb, occupied_squares_white(erlang:element(2, Game)) ) end, Simple_moves = case Color of white -> bitboard:exclusive_or( King_unblocked_target_square_bb, Captures ); black -> bitboard:exclusive_or( King_unblocked_target_square_bb, Captures ) end, Simple_moves@1 = gleam@list:map( board:get_positions(Simple_moves), fun(Dest) -> {normal, Origin, Dest, none, none} end ), Captures@1 = gleam@list:map( board:get_positions(Captures), fun(Dest@1) -> {normal, Origin, Dest@1, begin _assert_subject = piece_at_position(Game, Dest@1), {some, Piece} = 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 => <<"game"/utf8>>, function => <<"generate_king_pseudo_legal_move_list"/utf8>>, line => 1988}) end, {some, Piece} end, none} end ), All_moves = gleam@list:append(Simple_moves@1, Captures@1), gleam@list:append(Collector, All_moves) end ). -spec generate_queen_pseudo_legal_move_list(color:color(), game()) -> list(move:move()). generate_queen_pseudo_legal_move_list(Color, Game) -> Queen_bitboard = case Color of white -> erlang:element(9, erlang:element(2, Game)); black -> erlang:element(3, erlang:element(2, Game)) end, Queen_origin_squares = board:get_positions(Queen_bitboard), gleam@list:fold( Queen_origin_squares, [], fun(Collector, Queen_origin_square) -> South_mask_bb = look_up_south_ray_bb(Queen_origin_square), East_mask_bb = look_up_east_ray_bb(Queen_origin_square), North_mask_bb = look_up_north_ray_bb(Queen_origin_square), West_mask_bb = look_up_west_ray_bb(Queen_origin_square), Occupied_squares_bb = occupied_squares(erlang:element(2, Game)), South_blockers_bb = bitboard:'and'( South_mask_bb, Occupied_squares_bb ), East_blockers_bb = bitboard:'and'(East_mask_bb, Occupied_squares_bb), North_blockers_bb = bitboard:'and'( North_mask_bb, Occupied_squares_bb ), West_blockers_bb = bitboard:'and'(West_mask_bb, Occupied_squares_bb), First_blocker_south = position:from_int( bitboard:bitscan_backward(South_blockers_bb) ), First_blocker_east = position:from_int( bitboard:bitscan_forward(East_blockers_bb) ), First_blocker_north = position:from_int( bitboard:bitscan_forward(North_blockers_bb) ), First_blocker_west = position:from_int( bitboard:bitscan_backward(West_blockers_bb) ), First_blocker_south_mask_bb = case First_blocker_south of none -> {bitboard, 0}; {some, Position} -> look_up_south_ray_bb(Position) end, First_blocker_east_mask_bb = case First_blocker_east of none -> {bitboard, 0}; {some, Position@1} -> look_up_east_ray_bb(Position@1) end, First_blocker_north_mask_bb = case First_blocker_north of none -> {bitboard, 0}; {some, Position@2} -> look_up_north_ray_bb(Position@2) end, First_blocker_west_mask_bb = case First_blocker_west of none -> {bitboard, 0}; {some, Position@3} -> look_up_west_ray_bb(Position@3) end, South_ray_bb_with_blocker = bitboard:exclusive_or( South_mask_bb, First_blocker_south_mask_bb ), East_ray_bb_with_blocker = bitboard:exclusive_or( East_mask_bb, First_blocker_east_mask_bb ), North_ray_bb_with_blocker = bitboard:exclusive_or( North_mask_bb, First_blocker_north_mask_bb ), West_ray_bb_with_blocker = bitboard:exclusive_or( West_mask_bb, First_blocker_west_mask_bb ), South_ray_bb = case Color of white -> bitboard:'and'( South_ray_bb_with_blocker, bitboard:'not'( occupied_squares_white(erlang:element(2, Game)) ) ); black -> bitboard:'and'( South_ray_bb_with_blocker, bitboard:'not'( occupied_squares_black(erlang:element(2, Game)) ) ) end, East_ray_bb = case Color of white -> bitboard:'and'( East_ray_bb_with_blocker, bitboard:'not'( occupied_squares_white(erlang:element(2, Game)) ) ); black -> bitboard:'and'( East_ray_bb_with_blocker, bitboard:'not'( occupied_squares_black(erlang:element(2, Game)) ) ) end, North_ray_bb = case Color of white -> bitboard:'and'( North_ray_bb_with_blocker, bitboard:'not'( occupied_squares_white(erlang:element(2, Game)) ) ); black -> bitboard:'and'( North_ray_bb_with_blocker, bitboard:'not'( occupied_squares_black(erlang:element(2, Game)) ) ) end, West_ray_bb = case Color of white -> bitboard:'and'( West_ray_bb_with_blocker, bitboard:'not'( occupied_squares_white(erlang:element(2, Game)) ) ); black -> bitboard:'and'( West_ray_bb_with_blocker, bitboard:'not'( occupied_squares_black(erlang:element(2, Game)) ) ) end, Rook_moves = gleam@list:fold( [South_ray_bb, East_ray_bb, North_ray_bb, West_ray_bb], [], fun(Collector@1, Next) -> Captures = case Color of white -> bitboard:'and'( Next, occupied_squares_black(erlang:element(2, Game)) ); black -> bitboard:'and'( Next, occupied_squares_white(erlang:element(2, Game)) ) end, Rook_simple_moves = case Color of white -> bitboard:exclusive_or(Next, Captures); black -> bitboard:exclusive_or(Next, Captures) end, Simple_moves = gleam@list:map( board:get_positions(Rook_simple_moves), fun(Dest) -> {normal, Queen_origin_square, Dest, none, none} end ), Captures@1 = gleam@list:map( board:get_positions(Captures), fun(Dest@1) -> {normal, Queen_origin_square, Dest@1, begin _assert_subject = piece_at_position( Game, Dest@1 ), {some, Piece} = 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 => <<"game"/utf8>>, function => <<"generate_queen_pseudo_legal_move_list"/utf8>>, line => 2166} ) end, {some, Piece} end, none} end ), Simple_moves@1 = gleam@list:append( Collector@1, Simple_moves ), All_moves = gleam@list:append(Simple_moves@1, Captures@1), All_moves end ), South_west_mask_bb = look_up_south_west_ray_bb(Queen_origin_square), South_east_mask_bb = look_up_south_east_ray_bb(Queen_origin_square), North_east_mask_bb = look_up_north_east_ray_bb(Queen_origin_square), North_west_mask_bb = look_up_north_west_ray_bb(Queen_origin_square), Occupied_squares_bb@1 = occupied_squares(erlang:element(2, Game)), South_west_blockers_bb = bitboard:'and'( South_west_mask_bb, Occupied_squares_bb@1 ), South_east_blockers_bb = bitboard:'and'( South_east_mask_bb, Occupied_squares_bb@1 ), North_east_blockers_bb = bitboard:'and'( North_east_mask_bb, Occupied_squares_bb@1 ), North_west_blockers_bb = bitboard:'and'( North_west_mask_bb, Occupied_squares_bb@1 ), First_blocker_south_west = position:from_int( bitboard:bitscan_backward(South_west_blockers_bb) ), First_blocker_south_east = position:from_int( bitboard:bitscan_backward(South_east_blockers_bb) ), First_blocker_north_east = position:from_int( bitboard:bitscan_forward(North_east_blockers_bb) ), First_blocker_north_west = position:from_int( bitboard:bitscan_forward(North_west_blockers_bb) ), First_blocker_south_west_mask_bb = case First_blocker_south_west of none -> {bitboard, 0}; {some, Position@4} -> look_up_south_west_ray_bb(Position@4) end, First_blocker_south_east_mask_bb = case First_blocker_south_east of none -> {bitboard, 0}; {some, Position@5} -> look_up_south_east_ray_bb(Position@5) end, First_blocker_north_east_mask_bb = case First_blocker_north_east of none -> {bitboard, 0}; {some, Position@6} -> look_up_north_east_ray_bb(Position@6) end, First_blocker_north_west_mask_bb = case First_blocker_north_west of none -> {bitboard, 0}; {some, Position@7} -> look_up_north_west_ray_bb(Position@7) end, South_west_ray_bb_with_blocker = bitboard:exclusive_or( South_west_mask_bb, First_blocker_south_west_mask_bb ), South_east_ray_bb_with_blocker = bitboard:exclusive_or( South_east_mask_bb, First_blocker_south_east_mask_bb ), North_east_ray_bb_with_blocker = bitboard:exclusive_or( North_east_mask_bb, First_blocker_north_east_mask_bb ), North_west_ray_bb_with_blocker = bitboard:exclusive_or( North_west_mask_bb, First_blocker_north_west_mask_bb ), South_west_ray_bb = case Color of white -> bitboard:'and'( South_west_ray_bb_with_blocker, bitboard:'not'( occupied_squares_white(erlang:element(2, Game)) ) ); black -> bitboard:'and'( South_west_ray_bb_with_blocker, bitboard:'not'( occupied_squares_black(erlang:element(2, Game)) ) ) end, South_east_ray_bb = case Color of white -> bitboard:'and'( South_east_ray_bb_with_blocker, bitboard:'not'( occupied_squares_white(erlang:element(2, Game)) ) ); black -> bitboard:'and'( South_east_ray_bb_with_blocker, bitboard:'not'( occupied_squares_black(erlang:element(2, Game)) ) ) end, North_east_ray_bb = case Color of white -> bitboard:'and'( North_east_ray_bb_with_blocker, bitboard:'not'( occupied_squares_white(erlang:element(2, Game)) ) ); black -> bitboard:'and'( North_east_ray_bb_with_blocker, bitboard:'not'( occupied_squares_black(erlang:element(2, Game)) ) ) end, North_west_ray_bb = case Color of white -> bitboard:'and'( North_west_ray_bb_with_blocker, bitboard:'not'( occupied_squares_white(erlang:element(2, Game)) ) ); black -> bitboard:'and'( North_west_ray_bb_with_blocker, bitboard:'not'( occupied_squares_black(erlang:element(2, Game)) ) ) end, Bishop_moves = gleam@list:fold( [South_west_ray_bb, South_east_ray_bb, North_east_ray_bb, North_west_ray_bb], [], fun(Collector@2, Next@1) -> Captures@2 = case Color of white -> bitboard:'and'( Next@1, occupied_squares_black(erlang:element(2, Game)) ); black -> bitboard:'and'( Next@1, occupied_squares_white(erlang:element(2, Game)) ) end, Rook_simple_moves@1 = case Color of white -> bitboard:exclusive_or(Next@1, Captures@2); black -> bitboard:exclusive_or(Next@1, Captures@2) end, Simple_moves@2 = gleam@list:map( board:get_positions(Rook_simple_moves@1), fun(Dest@2) -> {normal, Queen_origin_square, Dest@2, none, none} end ), Captures@3 = gleam@list:map( board:get_positions(Captures@2), fun(Dest@3) -> {normal, Queen_origin_square, Dest@3, begin _assert_subject@1 = piece_at_position( Game, Dest@3 ), {some, Piece@1} = case _assert_subject@1 of {some, _} -> _assert_subject@1; _assert_fail@1 -> erlang:error( #{gleam_error => let_assert, message => <<"Assertion pattern match failed"/utf8>>, value => _assert_fail@1, module => <<"game"/utf8>>, function => <<"generate_queen_pseudo_legal_move_list"/utf8>>, line => 2351} ) end, {some, Piece@1} end, none} end ), Simple_moves@3 = gleam@list:append( Collector@2, Simple_moves@2 ), All_moves@1 = gleam@list:append(Simple_moves@3, Captures@3), All_moves@1 end ), All_moves@2 = gleam@list:append( gleam@list:append(Collector, Rook_moves), Bishop_moves ), All_moves@2 end ). -spec generate_rook_pseudo_legal_move_list(color:color(), game()) -> list(move:move()). generate_rook_pseudo_legal_move_list(Color, Game) -> Rook_bitboard = case Color of white -> erlang:element(10, erlang:element(2, Game)); black -> erlang:element(4, erlang:element(2, Game)) end, Rook_origin_squares = board:get_positions(Rook_bitboard), gleam@list:fold( Rook_origin_squares, [], fun(Collector, Rook_origin_square) -> South_mask_bb = look_up_south_ray_bb(Rook_origin_square), East_mask_bb = look_up_east_ray_bb(Rook_origin_square), North_mask_bb = look_up_north_ray_bb(Rook_origin_square), West_mask_bb = look_up_west_ray_bb(Rook_origin_square), Occupied_squares_bb = occupied_squares(erlang:element(2, Game)), South_blockers_bb = bitboard:'and'( South_mask_bb, Occupied_squares_bb ), East_blockers_bb = bitboard:'and'(East_mask_bb, Occupied_squares_bb), North_blockers_bb = bitboard:'and'( North_mask_bb, Occupied_squares_bb ), West_blockers_bb = bitboard:'and'(West_mask_bb, Occupied_squares_bb), First_blocker_south = position:from_int( bitboard:bitscan_backward(South_blockers_bb) ), First_blocker_east = position:from_int( bitboard:bitscan_forward(East_blockers_bb) ), First_blocker_north = position:from_int( bitboard:bitscan_forward(North_blockers_bb) ), First_blocker_west = position:from_int( bitboard:bitscan_backward(West_blockers_bb) ), First_blocker_south_mask_bb = case First_blocker_south of none -> {bitboard, 0}; {some, Position} -> look_up_south_ray_bb(Position) end, First_blocker_east_mask_bb = case First_blocker_east of none -> {bitboard, 0}; {some, Position@1} -> look_up_east_ray_bb(Position@1) end, First_blocker_north_mask_bb = case First_blocker_north of none -> {bitboard, 0}; {some, Position@2} -> look_up_north_ray_bb(Position@2) end, First_blocker_west_mask_bb = case First_blocker_west of none -> {bitboard, 0}; {some, Position@3} -> look_up_west_ray_bb(Position@3) end, South_ray_bb_with_blocker = bitboard:exclusive_or( South_mask_bb, First_blocker_south_mask_bb ), East_ray_bb_with_blocker = bitboard:exclusive_or( East_mask_bb, First_blocker_east_mask_bb ), North_ray_bb_with_blocker = bitboard:exclusive_or( North_mask_bb, First_blocker_north_mask_bb ), West_ray_bb_with_blocker = bitboard:exclusive_or( West_mask_bb, First_blocker_west_mask_bb ), South_ray_bb = case Color of white -> bitboard:'and'( South_ray_bb_with_blocker, bitboard:'not'( occupied_squares_white(erlang:element(2, Game)) ) ); black -> bitboard:'and'( South_ray_bb_with_blocker, bitboard:'not'( occupied_squares_black(erlang:element(2, Game)) ) ) end, East_ray_bb = case Color of white -> bitboard:'and'( East_ray_bb_with_blocker, bitboard:'not'( occupied_squares_white(erlang:element(2, Game)) ) ); black -> bitboard:'and'( East_ray_bb_with_blocker, bitboard:'not'( occupied_squares_black(erlang:element(2, Game)) ) ) end, North_ray_bb = case Color of white -> bitboard:'and'( North_ray_bb_with_blocker, bitboard:'not'( occupied_squares_white(erlang:element(2, Game)) ) ); black -> bitboard:'and'( North_ray_bb_with_blocker, bitboard:'not'( occupied_squares_black(erlang:element(2, Game)) ) ) end, West_ray_bb = case Color of white -> bitboard:'and'( West_ray_bb_with_blocker, bitboard:'not'( occupied_squares_white(erlang:element(2, Game)) ) ); black -> bitboard:'and'( West_ray_bb_with_blocker, bitboard:'not'( occupied_squares_black(erlang:element(2, Game)) ) ) end, Rook_moves = gleam@list:fold( [South_ray_bb, East_ray_bb, North_ray_bb, West_ray_bb], [], fun(Collector@1, Next) -> Rook_captures = case Color of white -> bitboard:'and'( Next, occupied_squares_black(erlang:element(2, Game)) ); black -> bitboard:'and'( Next, occupied_squares_white(erlang:element(2, Game)) ) end, Rook_simple_moves = case Color of white -> bitboard:exclusive_or(Next, Rook_captures); black -> bitboard:exclusive_or(Next, Rook_captures) end, Simple_moves = gleam@list:map( board:get_positions(Rook_simple_moves), fun(Dest) -> {normal, Rook_origin_square, Dest, none, none} end ), Captures = gleam@list:map( board:get_positions(Rook_captures), fun(Dest@1) -> {normal, Rook_origin_square, Dest@1, begin _assert_subject = piece_at_position( Game, Dest@1 ), {some, Piece} = 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 => <<"game"/utf8>>, function => <<"generate_rook_pseudo_legal_move_list"/utf8>>, line => 2535} ) end, {some, Piece} end, none} end ), Simple_moves@1 = gleam@list:append( Collector@1, Simple_moves ), All_moves = gleam@list:append(Simple_moves@1, Captures), All_moves end ), gleam@list:append(Collector, Rook_moves) end ). -spec generate_bishop_pseudo_legal_move_list(color:color(), game()) -> list(move:move()). generate_bishop_pseudo_legal_move_list(Color, Game) -> Bishop_bitboard = case Color of white -> erlang:element(11, erlang:element(2, Game)); black -> erlang:element(5, erlang:element(2, Game)) end, Bishop_origin_squares = board:get_positions(Bishop_bitboard), gleam@list:fold( Bishop_origin_squares, [], fun(Collector, Bishop_origin_square) -> South_west_mask_bb = look_up_south_west_ray_bb(Bishop_origin_square), South_east_mask_bb = look_up_south_east_ray_bb(Bishop_origin_square), North_east_mask_bb = look_up_north_east_ray_bb(Bishop_origin_square), North_west_mask_bb = look_up_north_west_ray_bb(Bishop_origin_square), Occupied_squares_bb = occupied_squares(erlang:element(2, Game)), South_west_blockers_bb = bitboard:'and'( South_west_mask_bb, Occupied_squares_bb ), South_east_blockers_bb = bitboard:'and'( South_east_mask_bb, Occupied_squares_bb ), North_east_blockers_bb = bitboard:'and'( North_east_mask_bb, Occupied_squares_bb ), North_west_blockers_bb = bitboard:'and'( North_west_mask_bb, Occupied_squares_bb ), First_blocker_south_west = position:from_int( bitboard:bitscan_backward(South_west_blockers_bb) ), First_blocker_south_east = position:from_int( bitboard:bitscan_backward(South_east_blockers_bb) ), First_blocker_north_east = position:from_int( bitboard:bitscan_forward(North_east_blockers_bb) ), First_blocker_north_west = position:from_int( bitboard:bitscan_forward(North_west_blockers_bb) ), First_blocker_south_west_mask_bb = case First_blocker_south_west of none -> {bitboard, 0}; {some, Position} -> look_up_south_west_ray_bb(Position) end, First_blocker_south_east_mask_bb = case First_blocker_south_east of none -> {bitboard, 0}; {some, Position@1} -> look_up_south_east_ray_bb(Position@1) end, First_blocker_north_east_mask_bb = case First_blocker_north_east of none -> {bitboard, 0}; {some, Position@2} -> look_up_north_east_ray_bb(Position@2) end, First_blocker_north_west_mask_bb = case First_blocker_north_west of none -> {bitboard, 0}; {some, Position@3} -> look_up_north_west_ray_bb(Position@3) end, South_west_ray_bb_with_blocker = bitboard:exclusive_or( South_west_mask_bb, First_blocker_south_west_mask_bb ), South_east_ray_bb_with_blocker = bitboard:exclusive_or( South_east_mask_bb, First_blocker_south_east_mask_bb ), North_east_ray_bb_with_blocker = bitboard:exclusive_or( North_east_mask_bb, First_blocker_north_east_mask_bb ), North_west_ray_bb_with_blocker = bitboard:exclusive_or( North_west_mask_bb, First_blocker_north_west_mask_bb ), South_west_ray_bb = case Color of white -> bitboard:'and'( South_west_ray_bb_with_blocker, bitboard:'not'( occupied_squares_white(erlang:element(2, Game)) ) ); black -> bitboard:'and'( South_west_ray_bb_with_blocker, bitboard:'not'( occupied_squares_black(erlang:element(2, Game)) ) ) end, South_east_ray_bb = case Color of white -> bitboard:'and'( South_east_ray_bb_with_blocker, bitboard:'not'( occupied_squares_white(erlang:element(2, Game)) ) ); black -> bitboard:'and'( South_east_ray_bb_with_blocker, bitboard:'not'( occupied_squares_black(erlang:element(2, Game)) ) ) end, North_east_ray_bb = case Color of white -> bitboard:'and'( North_east_ray_bb_with_blocker, bitboard:'not'( occupied_squares_white(erlang:element(2, Game)) ) ); black -> bitboard:'and'( North_east_ray_bb_with_blocker, bitboard:'not'( occupied_squares_black(erlang:element(2, Game)) ) ) end, North_west_ray_bb = case Color of white -> bitboard:'and'( North_west_ray_bb_with_blocker, bitboard:'not'( occupied_squares_white(erlang:element(2, Game)) ) ); black -> bitboard:'and'( North_west_ray_bb_with_blocker, bitboard:'not'( occupied_squares_black(erlang:element(2, Game)) ) ) end, Bishop_moves = gleam@list:fold( [South_west_ray_bb, South_east_ray_bb, North_east_ray_bb, North_west_ray_bb], [], fun(Collector@1, Next) -> Captures = case Color of white -> bitboard:'and'( Next, occupied_squares_black(erlang:element(2, Game)) ); black -> bitboard:'and'( Next, occupied_squares_white(erlang:element(2, Game)) ) end, Rook_simple_moves = case Color of white -> bitboard:exclusive_or(Next, Captures); black -> bitboard:exclusive_or(Next, Captures) end, Simple_moves = gleam@list:map( board:get_positions(Rook_simple_moves), fun(Dest) -> {normal, Bishop_origin_square, Dest, none, none} end ), Captures@1 = gleam@list:map( board:get_positions(Captures), fun(Dest@1) -> {normal, Bishop_origin_square, Dest@1, begin _assert_subject = piece_at_position( Game, Dest@1 ), {some, Piece} = 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 => <<"game"/utf8>>, function => <<"generate_bishop_pseudo_legal_move_list"/utf8>>, line => 2797} ) end, {some, Piece} end, none} end ), Simple_moves@1 = gleam@list:append( Collector@1, Simple_moves ), All_moves = gleam@list:append(Simple_moves@1, Captures@1), All_moves end ), gleam@list:append(Collector, Bishop_moves) end ). -spec generate_knight_pseudo_legal_move_list(color:color(), game()) -> list(move:move()). generate_knight_pseudo_legal_move_list(Color, Game) -> Knight_bitboard = case Color of white -> erlang:element(12, erlang:element(2, Game)); black -> erlang:element(6, erlang:element(2, Game)) end, Knight_origin_squares = board:get_positions(Knight_bitboard), gleam@list:fold( Knight_origin_squares, [], fun(Collector, Origin) -> Knight_bitboard@1 = board:from_position(Origin), North_target_squares = bitboard:'or'( bitboard:'and'( bitboard:shift_left(Knight_bitboard@1, 17), {bitboard, 2#1111111011111110111111101111111011111110111111101111111011111110} ), bitboard:'and'( bitboard:shift_left(Knight_bitboard@1, 15), {bitboard, 2#0111111101111111011111110111111101111111011111110111111101111111} ) ), South_target_squares = bitboard:'or'( bitboard:'and'( bitboard:shift_right(Knight_bitboard@1, 17), {bitboard, 2#0111111101111111011111110111111101111111011111110111111101111111} ), bitboard:'and'( bitboard:shift_right(Knight_bitboard@1, 15), {bitboard, 2#1111111011111110111111101111111011111110111111101111111011111110} ) ), West_target_squares = bitboard:'or'( bitboard:'and'( bitboard:'and'( bitboard:shift_right(Knight_bitboard@1, 10), {bitboard, 2#0111111101111111011111110111111101111111011111110111111101111111} ), {bitboard, 2#1011111110111111101111111011111110111111101111111011111110111111} ), bitboard:'and'( bitboard:'and'( bitboard:shift_left(Knight_bitboard@1, 6), {bitboard, 2#0111111101111111011111110111111101111111011111110111111101111111} ), {bitboard, 2#1011111110111111101111111011111110111111101111111011111110111111} ) ), East_target_squares = bitboard:'or'( bitboard:'and'( bitboard:'and'( bitboard:shift_right(Knight_bitboard@1, 6), {bitboard, 2#1111111011111110111111101111111011111110111111101111111011111110} ), {bitboard, 2#1111110111111101111111011111110111111101111111011111110111111101} ), bitboard:'and'( bitboard:'and'( bitboard:shift_left(Knight_bitboard@1, 10), {bitboard, 2#1111111011111110111111101111111011111110111111101111111011111110} ), {bitboard, 2#1111110111111101111111011111110111111101111111011111110111111101} ) ), Knight_target_squares = bitboard:'or'( bitboard:'or'(North_target_squares, South_target_squares), bitboard:'or'(West_target_squares, East_target_squares) ), List_of_friendly_piece_bitboards = case Color of white -> [erlang:element(8, erlang:element(2, Game)), erlang:element(9, erlang:element(2, Game)), erlang:element(10, erlang:element(2, Game)), erlang:element(11, erlang:element(2, Game)), erlang:element(12, erlang:element(2, Game)), erlang:element(13, erlang:element(2, Game))]; black -> [erlang:element(2, erlang:element(2, Game)), erlang:element(3, erlang:element(2, Game)), erlang:element(4, erlang:element(2, Game)), erlang:element(5, erlang:element(2, Game)), erlang:element(6, erlang:element(2, Game)), erlang:element(7, erlang:element(2, Game))] end, Friendly_pieces = gleam@list:fold( List_of_friendly_piece_bitboards, {bitboard, 0}, fun(Collector@1, Next) -> bitboard:'or'(Collector@1, Next) end ), Knight_unblocked_target_square_bb = bitboard:'and'( Knight_target_squares, bitboard:'not'(Friendly_pieces) ), Captures = case Color of white -> bitboard:'and'( Knight_unblocked_target_square_bb, occupied_squares_black(erlang:element(2, Game)) ); black -> bitboard:'and'( Knight_unblocked_target_square_bb, occupied_squares_white(erlang:element(2, Game)) ) end, Simple_moves = case Color of white -> bitboard:exclusive_or( Knight_unblocked_target_square_bb, Captures ); black -> bitboard:exclusive_or( Knight_unblocked_target_square_bb, Captures ) end, Simple_moves@1 = gleam@list:map( board:get_positions(Simple_moves), fun(Dest) -> {normal, Origin, Dest, none, none} end ), Captures@1 = gleam@list:map( board:get_positions(Captures), fun(Dest@1) -> {normal, Origin, Dest@1, begin _assert_subject = piece_at_position(Game, Dest@1), {some, Piece} = 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 => <<"game"/utf8>>, function => <<"generate_knight_pseudo_legal_move_list"/utf8>>, line => 2942}) end, {some, Piece} end, none} end ), All_moves = gleam@list:append(Simple_moves@1, Captures@1), gleam@list:append(Collector, All_moves) end ). -spec generate_pawn_starting_rank_double_move_bitboard(color:color(), game()) -> bitboard:bitboard(). generate_pawn_starting_rank_double_move_bitboard(Color, Game) -> case Color of white -> White_pawn_target_squares = bitboard:'and'( erlang:element(13, erlang:element(2, Game)), {bitboard, 2#0000000000000000000000000000000000000000000000001111111100000000} ), White_pawn_target_squares@1 = bitboard:'or'( bitboard:shift_left(White_pawn_target_squares, 16), bitboard:shift_left(White_pawn_target_squares, 8) ), Occupied_squares = occupied_squares(erlang:element(2, Game)), Moves = bitboard:'and'( Occupied_squares, White_pawn_target_squares@1 ), Moves@1 = bitboard:'or'( bitboard:shift_left( bitboard:'and'( Moves, {bitboard, 2#0000000000000000000000000000000000000000111111110000000000000000} ), 8 ), Moves ), Moves@2 = bitboard:exclusive_or( Moves@1, White_pawn_target_squares@1 ), Moves@3 = bitboard:'and'( Moves@2, bitboard:'not'( {bitboard, 2#0000000000000000000000000000000000000000111111110000000000000000} ) ), Moves@3; black -> Black_pawn_target_squares = bitboard:'and'( erlang:element(7, erlang:element(2, Game)), {bitboard, 2#0000000011111111000000000000000000000000000000000000000000000000} ), Black_pawn_target_squares@1 = bitboard:'or'( bitboard:shift_right(Black_pawn_target_squares, 16), bitboard:shift_right(Black_pawn_target_squares, 8) ), Occupied_squares@1 = occupied_squares(erlang:element(2, Game)), Moves@4 = bitboard:'and'( Occupied_squares@1, Black_pawn_target_squares@1 ), Moves@5 = bitboard:'or'( bitboard:shift_right( bitboard:'and'( Moves@4, {bitboard, 2#0000000000000000111111110000000000000000000000000000000000000000} ), 8 ), Moves@4 ), Moves@6 = bitboard:exclusive_or( Moves@5, Black_pawn_target_squares@1 ), Moves@7 = bitboard:'and'( Moves@6, bitboard:'not'( {bitboard, 2#0000000000000000111111110000000000000000000000000000000000000000} ) ), Moves@7 end. -spec generate_pawn_non_capture_move_bitboard(color:color(), game()) -> bitboard:bitboard(). generate_pawn_non_capture_move_bitboard(Color, Game) -> case Color of white -> White_pawn_target_squares = bitboard:shift_left( erlang:element(13, erlang:element(2, Game)), 8 ), List_of_enemy_piece_bitboards = [erlang:element( 2, erlang:element(2, Game) ), erlang:element(3, erlang:element(2, Game)), erlang:element(4, erlang:element(2, Game)), erlang:element(5, erlang:element(2, Game)), erlang:element(6, erlang:element(2, Game)), erlang:element(7, erlang:element(2, Game))], Occupied_squares_white = occupied_squares_white( erlang:element(2, Game) ), Enemy_pieces = gleam@list:fold( List_of_enemy_piece_bitboards, {bitboard, 0}, fun(Collector, Next) -> bitboard:'or'(Collector, Next) end ), Moves = bitboard:exclusive_or( White_pawn_target_squares, Enemy_pieces ), Moves@1 = bitboard:'and'(Moves, White_pawn_target_squares), Moves@2 = bitboard:'and'( Moves@1, bitboard:'not'(Occupied_squares_white) ), Moves@2; black -> Black_pawn_target_squares = bitboard:shift_right( erlang:element(7, erlang:element(2, Game)), 8 ), List_of_enemy_piece_bitboards@1 = [erlang:element( 8, erlang:element(2, Game) ), erlang:element(9, erlang:element(2, Game)), erlang:element(10, erlang:element(2, Game)), erlang:element(11, erlang:element(2, Game)), erlang:element(12, erlang:element(2, Game)), erlang:element(13, erlang:element(2, Game))], Occupied_squares_black = occupied_squares_black( erlang:element(2, Game) ), Enemy_pieces@1 = gleam@list:fold( List_of_enemy_piece_bitboards@1, {bitboard, 0}, fun(Collector@1, Next@1) -> bitboard:'or'(Collector@1, Next@1) end ), Moves@3 = bitboard:exclusive_or( Black_pawn_target_squares, Enemy_pieces@1 ), Moves@4 = bitboard:'and'(Moves@3, Black_pawn_target_squares), Moves@5 = bitboard:'and'( Moves@4, bitboard:'not'(Occupied_squares_black) ), Moves@5 end. -spec generate_pawn_attack_set(bitboard:bitboard(), color:color()) -> bitboard:bitboard(). generate_pawn_attack_set(Pawn_bitboard, Color) -> case Color of white -> East_attack = bitboard:'and'( bitboard:shift_left(Pawn_bitboard, 9), {bitboard, 2#1111111011111110111111101111111011111110111111101111111011111110} ), West_attack = bitboard:'and'( bitboard:shift_left(Pawn_bitboard, 7), {bitboard, 2#0111111101111111011111110111111101111111011111110111111101111111} ), All_attacks = bitboard:'or'(East_attack, West_attack), All_attacks; black -> East_attack@1 = bitboard:'and'( bitboard:shift_right(Pawn_bitboard, 7), {bitboard, 2#1111111011111110111111101111111011111110111111101111111011111110} ), West_attack@1 = bitboard:'and'( bitboard:shift_right(Pawn_bitboard, 9), {bitboard, 2#0111111101111111011111110111111101111111011111110111111101111111} ), All_attacks@1 = bitboard:'or'(East_attack@1, West_attack@1), All_attacks@1 end. -spec generate_pawn_capture_move_list(color:color(), game()) -> list(move:move()). generate_pawn_capture_move_list(Color, Game) -> Pawn_attack_set = case Color of white -> generate_pawn_attack_set( erlang:element(13, erlang:element(2, Game)), Color ); black -> generate_pawn_attack_set( erlang:element(7, erlang:element(2, Game)), Color ) end, generate_pawn_attack_set(erlang:element(13, erlang:element(2, Game)), Color), List_of_enemy_piece_bitboards = case Color of white -> [erlang:element(2, erlang:element(2, Game)), erlang:element(3, erlang:element(2, Game)), erlang:element(4, erlang:element(2, Game)), erlang:element(5, erlang:element(2, Game)), erlang:element(6, erlang:element(2, Game)), erlang:element(7, erlang:element(2, Game))]; black -> [erlang:element(8, erlang:element(2, Game)), erlang:element(9, erlang:element(2, Game)), erlang:element(10, erlang:element(2, Game)), erlang:element(11, erlang:element(2, Game)), erlang:element(12, erlang:element(2, Game)), erlang:element(13, erlang:element(2, Game))] end, Enemy_pieces = gleam@list:fold( List_of_enemy_piece_bitboards, {bitboard, 0}, fun(Collector, Next) -> bitboard:'or'(Collector, Next) end ), Pawn_capture_destination_set = bitboard:'and'(Pawn_attack_set, Enemy_pieces), [East_origins@2, West_origins@2] = case Color of white -> East_origins = bitboard:'and'( bitboard:shift_right(Pawn_capture_destination_set, 9), {bitboard, 2#0111111101111111011111110111111101111111011111110111111101111111} ), West_origins = bitboard:'and'( bitboard:shift_right(Pawn_capture_destination_set, 7), {bitboard, 2#1111111011111110111111101111111011111110111111101111111011111110} ), [bitboard:'and'( East_origins, erlang:element(13, erlang:element(2, Game)) ), bitboard:'and'( West_origins, erlang:element(13, erlang:element(2, Game)) )]; black -> West_origins@1 = bitboard:'and'( bitboard:shift_left(Pawn_capture_destination_set, 9), {bitboard, 2#1111111011111110111111101111111011111110111111101111111011111110} ), East_origins@1 = bitboard:'and'( bitboard:shift_left(Pawn_capture_destination_set, 7), {bitboard, 2#0111111101111111011111110111111101111111011111110111111101111111} ), [bitboard:'and'( East_origins@1, erlang:element(7, erlang:element(2, Game)) ), bitboard:'and'( West_origins@1, erlang:element(7, erlang:element(2, Game)) )] end, Pawn_capture_origin_set = bitboard:'or'(East_origins@2, West_origins@2), Pawn_capture_origin_list = board:get_positions(Pawn_capture_origin_set), Pawn_capture_destination_list = board:get_positions( Pawn_capture_destination_set ), Pawn_capture_move_list = gleam@list:fold( Pawn_capture_origin_list, [], fun(Collector@1, Position) -> East_attack = case Color of white -> board:get_positions( bitboard:'and'( bitboard:shift_left( position:to_bitboard(Position), 9 ), {bitboard, 2#1111111011111110111111101111111011111110111111101111111011111110} ) ); black -> board:get_positions( bitboard:'and'( bitboard:shift_right( position:to_bitboard(Position), 7 ), {bitboard, 2#1111111011111110111111101111111011111110111111101111111011111110} ) ) end, East_moves@2 = case East_attack of [] -> []; [East_attack@1] -> East_attack_in_dest_list = gleam@list:contains( Pawn_capture_destination_list, East_attack@1 ), East_moves@1 = case East_attack_in_dest_list of false -> []; true -> East_moves = case East_attack@1 of {position, _, eight} when Color =:= white -> [{normal, Position, East_attack@1, begin _assert_subject = piece_at_position( Game, East_attack@1 ), {some, Piece} = 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 => <<"game"/utf8>>, function => <<"generate_pawn_capture_move_list"/utf8>>, line => 3445} ) end, {some, Piece} end, {some, {piece, Color, queen}}}, {normal, Position, East_attack@1, begin _assert_subject@1 = piece_at_position( Game, East_attack@1 ), {some, Piece@1} = case _assert_subject@1 of {some, _} -> _assert_subject@1; _assert_fail@1 -> erlang:error( #{gleam_error => let_assert, message => <<"Assertion pattern match failed"/utf8>>, value => _assert_fail@1, module => <<"game"/utf8>>, function => <<"generate_pawn_capture_move_list"/utf8>>, line => 3455} ) end, {some, Piece@1} end, {some, {piece, Color, rook}}}, {normal, Position, East_attack@1, begin _assert_subject@2 = piece_at_position( Game, East_attack@1 ), {some, Piece@2} = case _assert_subject@2 of {some, _} -> _assert_subject@2; _assert_fail@2 -> erlang:error( #{gleam_error => let_assert, message => <<"Assertion pattern match failed"/utf8>>, value => _assert_fail@2, module => <<"game"/utf8>>, function => <<"generate_pawn_capture_move_list"/utf8>>, line => 3465} ) end, {some, Piece@2} end, {some, {piece, Color, bishop}}}, {normal, Position, East_attack@1, begin _assert_subject@3 = piece_at_position( Game, East_attack@1 ), {some, Piece@3} = case _assert_subject@3 of {some, _} -> _assert_subject@3; _assert_fail@3 -> erlang:error( #{gleam_error => let_assert, message => <<"Assertion pattern match failed"/utf8>>, value => _assert_fail@3, module => <<"game"/utf8>>, function => <<"generate_pawn_capture_move_list"/utf8>>, line => 3475} ) end, {some, Piece@3} end, {some, {piece, Color, knight}}}]; {position, _, one} when Color =:= black -> [{normal, Position, East_attack@1, begin _assert_subject@4 = piece_at_position( Game, East_attack@1 ), {some, Piece@4} = case _assert_subject@4 of {some, _} -> _assert_subject@4; _assert_fail@4 -> erlang:error( #{gleam_error => let_assert, message => <<"Assertion pattern match failed"/utf8>>, value => _assert_fail@4, module => <<"game"/utf8>>, function => <<"generate_pawn_capture_move_list"/utf8>>, line => 3487} ) end, {some, Piece@4} end, {some, {piece, Color, queen}}}, {normal, Position, East_attack@1, begin _assert_subject@5 = piece_at_position( Game, East_attack@1 ), {some, Piece@5} = case _assert_subject@5 of {some, _} -> _assert_subject@5; _assert_fail@5 -> erlang:error( #{gleam_error => let_assert, message => <<"Assertion pattern match failed"/utf8>>, value => _assert_fail@5, module => <<"game"/utf8>>, function => <<"generate_pawn_capture_move_list"/utf8>>, line => 3497} ) end, {some, Piece@5} end, {some, {piece, Color, rook}}}, {normal, Position, East_attack@1, begin _assert_subject@6 = piece_at_position( Game, East_attack@1 ), {some, Piece@6} = case _assert_subject@6 of {some, _} -> _assert_subject@6; _assert_fail@6 -> erlang:error( #{gleam_error => let_assert, message => <<"Assertion pattern match failed"/utf8>>, value => _assert_fail@6, module => <<"game"/utf8>>, function => <<"generate_pawn_capture_move_list"/utf8>>, line => 3507} ) end, {some, Piece@6} end, {some, {piece, Color, bishop}}}, {normal, Position, East_attack@1, begin _assert_subject@7 = piece_at_position( Game, East_attack@1 ), {some, Piece@7} = case _assert_subject@7 of {some, _} -> _assert_subject@7; _assert_fail@7 -> erlang:error( #{gleam_error => let_assert, message => <<"Assertion pattern match failed"/utf8>>, value => _assert_fail@7, module => <<"game"/utf8>>, function => <<"generate_pawn_capture_move_list"/utf8>>, line => 3517} ) end, {some, Piece@7} end, {some, {piece, Color, knight}}}]; _ -> [{normal, Position, East_attack@1, begin _assert_subject@8 = piece_at_position( Game, East_attack@1 ), {some, Piece@8} = case _assert_subject@8 of {some, _} -> _assert_subject@8; _assert_fail@8 -> erlang:error( #{gleam_error => let_assert, message => <<"Assertion pattern match failed"/utf8>>, value => _assert_fail@8, module => <<"game"/utf8>>, function => <<"generate_pawn_capture_move_list"/utf8>>, line => 3529} ) end, {some, Piece@8} end, none}] end, East_moves end, East_moves@1 end, West_attack = case Color of white -> board:get_positions( bitboard:'and'( bitboard:shift_left( position:to_bitboard(Position), 7 ), {bitboard, 2#0111111101111111011111110111111101111111011111110111111101111111} ) ); black -> board:get_positions( bitboard:'and'( bitboard:shift_right( position:to_bitboard(Position), 9 ), {bitboard, 2#0111111101111111011111110111111101111111011111110111111101111111} ) ) end, West_moves@2 = case West_attack of [] -> []; [West_attack@1] -> West_attack_in_dest_list = gleam@list:contains( Pawn_capture_destination_list, West_attack@1 ), West_moves@1 = case West_attack_in_dest_list of false -> []; true -> West_moves = case West_attack@1 of {position, _, eight} when Color =:= white -> [{normal, Position, West_attack@1, begin _assert_subject@9 = piece_at_position( Game, West_attack@1 ), {some, Piece@9} = case _assert_subject@9 of {some, _} -> _assert_subject@9; _assert_fail@9 -> erlang:error( #{gleam_error => let_assert, message => <<"Assertion pattern match failed"/utf8>>, value => _assert_fail@9, module => <<"game"/utf8>>, function => <<"generate_pawn_capture_move_list"/utf8>>, line => 3572} ) end, {some, Piece@9} end, {some, {piece, Color, queen}}}, {normal, Position, West_attack@1, begin _assert_subject@10 = piece_at_position( Game, West_attack@1 ), {some, Piece@10} = case _assert_subject@10 of {some, _} -> _assert_subject@10; _assert_fail@10 -> erlang:error( #{gleam_error => let_assert, message => <<"Assertion pattern match failed"/utf8>>, value => _assert_fail@10, module => <<"game"/utf8>>, function => <<"generate_pawn_capture_move_list"/utf8>>, line => 3582} ) end, {some, Piece@10} end, {some, {piece, Color, rook}}}, {normal, Position, West_attack@1, begin _assert_subject@11 = piece_at_position( Game, West_attack@1 ), {some, Piece@11} = case _assert_subject@11 of {some, _} -> _assert_subject@11; _assert_fail@11 -> erlang:error( #{gleam_error => let_assert, message => <<"Assertion pattern match failed"/utf8>>, value => _assert_fail@11, module => <<"game"/utf8>>, function => <<"generate_pawn_capture_move_list"/utf8>>, line => 3592} ) end, {some, Piece@11} end, {some, {piece, Color, bishop}}}, {normal, Position, West_attack@1, begin _assert_subject@12 = piece_at_position( Game, West_attack@1 ), {some, Piece@12} = case _assert_subject@12 of {some, _} -> _assert_subject@12; _assert_fail@12 -> erlang:error( #{gleam_error => let_assert, message => <<"Assertion pattern match failed"/utf8>>, value => _assert_fail@12, module => <<"game"/utf8>>, function => <<"generate_pawn_capture_move_list"/utf8>>, line => 3602} ) end, {some, Piece@12} end, {some, {piece, Color, knight}}}]; {position, _, one} when Color =:= black -> [{normal, Position, West_attack@1, begin _assert_subject@13 = piece_at_position( Game, West_attack@1 ), {some, Piece@13} = case _assert_subject@13 of {some, _} -> _assert_subject@13; _assert_fail@13 -> erlang:error( #{gleam_error => let_assert, message => <<"Assertion pattern match failed"/utf8>>, value => _assert_fail@13, module => <<"game"/utf8>>, function => <<"generate_pawn_capture_move_list"/utf8>>, line => 3614} ) end, {some, Piece@13} end, {some, {piece, Color, queen}}}, {normal, Position, West_attack@1, begin _assert_subject@14 = piece_at_position( Game, West_attack@1 ), {some, Piece@14} = case _assert_subject@14 of {some, _} -> _assert_subject@14; _assert_fail@14 -> erlang:error( #{gleam_error => let_assert, message => <<"Assertion pattern match failed"/utf8>>, value => _assert_fail@14, module => <<"game"/utf8>>, function => <<"generate_pawn_capture_move_list"/utf8>>, line => 3624} ) end, {some, Piece@14} end, {some, {piece, Color, rook}}}, {normal, Position, West_attack@1, begin _assert_subject@15 = piece_at_position( Game, West_attack@1 ), {some, Piece@15} = case _assert_subject@15 of {some, _} -> _assert_subject@15; _assert_fail@15 -> erlang:error( #{gleam_error => let_assert, message => <<"Assertion pattern match failed"/utf8>>, value => _assert_fail@15, module => <<"game"/utf8>>, function => <<"generate_pawn_capture_move_list"/utf8>>, line => 3634} ) end, {some, Piece@15} end, {some, {piece, Color, bishop}}}, {normal, Position, West_attack@1, begin _assert_subject@16 = piece_at_position( Game, West_attack@1 ), {some, Piece@16} = case _assert_subject@16 of {some, _} -> _assert_subject@16; _assert_fail@16 -> erlang:error( #{gleam_error => let_assert, message => <<"Assertion pattern match failed"/utf8>>, value => _assert_fail@16, module => <<"game"/utf8>>, function => <<"generate_pawn_capture_move_list"/utf8>>, line => 3644} ) end, {some, Piece@16} end, {some, {piece, Color, knight}}}]; _ -> [{normal, Position, West_attack@1, begin _assert_subject@17 = piece_at_position( Game, West_attack@1 ), {some, Piece@17} = case _assert_subject@17 of {some, _} -> _assert_subject@17; _assert_fail@17 -> erlang:error( #{gleam_error => let_assert, message => <<"Assertion pattern match failed"/utf8>>, value => _assert_fail@17, module => <<"game"/utf8>>, function => <<"generate_pawn_capture_move_list"/utf8>>, line => 3656} ) end, {some, Piece@17} end, none}] end, West_moves end, West_moves@1 end, gleam@list:append( gleam@list:append(Collector@1, East_moves@2), West_moves@2 ) end ), Pawn_capture_move_list. -spec generate_pawn_pseudo_legal_move_list(color:color(), game()) -> list(move:move()). generate_pawn_pseudo_legal_move_list(Color, Game) -> Capture_list = generate_pawn_capture_move_list(Color, Game), Moves_no_captures = generate_pawn_non_capture_move_bitboard(Color, Game), Non_capture_dest_list = board:get_positions(Moves_no_captures), Non_capture_move_list = gleam@list:fold( Non_capture_dest_list, [], fun(Acc, Dest) -> Origin = position:get_rear_position(Dest, Color), Moves = case Dest of {position, _, eight} when Color =:= white -> [{normal, Origin, Dest, none, {some, {piece, Color, queen}}}, {normal, Origin, Dest, none, {some, {piece, Color, rook}}}, {normal, Origin, Dest, none, {some, {piece, Color, bishop}}}, {normal, Origin, Dest, none, {some, {piece, Color, knight}}}]; {position, _, one} when Color =:= black -> [{normal, Origin, Dest, none, {some, {piece, Color, queen}}}, {normal, Origin, Dest, none, {some, {piece, Color, rook}}}, {normal, Origin, Dest, none, {some, {piece, Color, bishop}}}, {normal, Origin, Dest, none, {some, {piece, Color, knight}}}]; _ -> [{normal, Origin, Dest, none, none}] end, gleam@list:append(Acc, Moves) end ), Initial_rank_double_move_list = generate_pawn_starting_rank_double_move_bitboard( Color, Game ), Initial_rank_double_dest_list = board:get_positions( Initial_rank_double_move_list ), Initial_rank_double_move_list@1 = gleam@list:map( Initial_rank_double_dest_list, fun(Dest@1) -> case Color of white -> case erlang:element(2, Dest@1) of a -> {normal, {position, a, two}, Dest@1, none, none}; b -> {normal, {position, b, two}, Dest@1, none, none}; c -> {normal, {position, c, two}, Dest@1, none, none}; d -> {normal, {position, d, two}, Dest@1, none, none}; e -> {normal, {position, e, two}, Dest@1, none, none}; f -> {normal, {position, f, two}, Dest@1, none, none}; g -> {normal, {position, g, two}, Dest@1, none, none}; h -> {normal, {position, h, two}, Dest@1, none, none} end; black -> case erlang:element(2, Dest@1) of a -> {normal, {position, a, seven}, Dest@1, none, none}; b -> {normal, {position, b, seven}, Dest@1, none, none}; c -> {normal, {position, c, seven}, Dest@1, none, none}; d -> {normal, {position, d, seven}, Dest@1, none, none}; e -> {normal, {position, e, seven}, Dest@1, none, none}; f -> {normal, {position, f, seven}, Dest@1, none, none}; g -> {normal, {position, g, seven}, Dest@1, none, none}; h -> {normal, {position, h, seven}, Dest@1, none, none} end end end ), gleam@list:append( gleam@list:append(Capture_list, Non_capture_move_list), Initial_rank_double_move_list@1 ). -spec generate_pseudo_legal_move_list(game(), color:color()) -> list(move:move()). generate_pseudo_legal_move_list(Game, Color) -> List_of_move_lists = [generate_rook_pseudo_legal_move_list(Color, Game), generate_pawn_pseudo_legal_move_list(Color, Game), generate_knight_pseudo_legal_move_list(Color, Game), generate_bishop_pseudo_legal_move_list(Color, Game), generate_queen_pseudo_legal_move_list(Color, Game), generate_king_pseudo_legal_move_list(Color, Game), generate_castling_pseudo_legal_move_list(Color, Game), generate_en_passant_pseudo_legal_move_list(Color, Game)], Move_list = gleam@list:fold( List_of_move_lists, [], fun(Collector, Next) -> gleam@list:append(Collector, Next) end ), Move_list. -spec is_king_in_check(game(), color:color()) -> boolean(). is_king_in_check(Game, Color) -> Enemy_color = (case Color of white -> black; black -> white end), Enemy_move_list = (generate_pseudo_legal_move_list(Game, Enemy_color)), Enemy_move_list@1 = begin _pipe = Enemy_move_list, gleam@list:filter(_pipe, fun(Move) -> case Move of {normal, _, _, {some, Piece}, _} -> Piece =:= {piece, Color, king}; _ -> false end end) end, gleam@list:length(Enemy_move_list@1) > 0. -spec is_move_legal(game(), move:move()) -> boolean(). is_move_legal(Game, Move) -> New_game_state = apply_pseudo_legal_move(Game, Move), case Move of {normal, _, _, _, _} -> not is_king_in_check(New_game_state, erlang:element(3, Game)); {en_passant, _, _} -> not is_king_in_check(New_game_state, erlang:element(3, Game)); {castle, _, To} -> case is_king_in_check(Game, erlang:element(3, Game)) of true -> false; false -> case is_king_in_check( New_game_state, erlang:element(3, Game) ) of true -> false; false -> King_castling_target_square = case To of {position, g, one} -> {position, f, one}; {position, g, eight} -> {position, f, eight}; {position, c, one} -> {position, d, one}; {position, c, eight} -> {position, d, eight}; _ -> (erlang:error(#{gleam_error => panic, message => <<"panic expression evaluated"/utf8>>, module => <<"game"/utf8>>, function => <<"is_move_legal"/utf8>>, line => 497}))( <<"Invalid castle move"/utf8>> ) end, New_game_state@1 = erlang:setelement( 2, New_game_state, board:set_piece_at_position( erlang:element(2, New_game_state), King_castling_target_square, {piece, erlang:element(3, Game), king} ) ), _assert_subject = board:remove_piece_at_position( erlang:element(2, New_game_state@1), To ), {some, New_board} = 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 => <<"game"/utf8>>, function => <<"is_move_legal"/utf8>>, line => 510}) end, New_game_state@2 = erlang:setelement( 2, New_game_state@1, New_board ), case is_king_in_check( New_game_state@2, erlang:element(3, Game) ) of true -> false; false -> true end end end; _ -> true end. -spec bitboard_repr_to_map_repr(board:board_bb()) -> gleam@map:map_(position:position(), gleam@option:option(piece:piece())). bitboard_repr_to_map_repr(Board) -> White_king_bitboard = erlang:element(8, Board), White_queen_bitboard = erlang:element(9, Board), White_rook_bitboard = erlang:element(10, Board), White_bishop_bitboard = erlang:element(11, Board), White_knight_bitboard = erlang:element(12, Board), White_pawns_bitboard = erlang:element(13, Board), Black_king_bitboard = erlang:element(2, Board), Black_queen_bitboard = erlang:element(3, Board), Black_rook_bitboard = erlang:element(4, Board), Black_bishop_bitboard = erlang:element(5, Board), Black_knight_bitboard = erlang:element(6, Board), Black_pawns_bitboard = erlang:element(7, Board), Board_map = gleam@map:from_list( [{{position, a, one}, none}, {{position, b, one}, none}, {{position, c, one}, none}, {{position, d, one}, none}, {{position, e, one}, none}, {{position, f, one}, none}, {{position, g, one}, none}, {{position, h, one}, none}, {{position, a, two}, none}, {{position, b, two}, none}, {{position, c, two}, none}, {{position, d, two}, none}, {{position, e, two}, none}, {{position, f, two}, none}, {{position, g, two}, none}, {{position, h, two}, none}, {{position, a, three}, none}, {{position, b, three}, none}, {{position, c, three}, none}, {{position, d, three}, none}, {{position, e, three}, none}, {{position, f, three}, none}, {{position, g, three}, none}, {{position, h, three}, none}, {{position, a, four}, none}, {{position, b, four}, none}, {{position, c, four}, none}, {{position, d, four}, none}, {{position, e, four}, none}, {{position, f, four}, none}, {{position, g, four}, none}, {{position, h, four}, none}, {{position, a, five}, none}, {{position, b, five}, none}, {{position, c, five}, none}, {{position, d, five}, none}, {{position, e, five}, none}, {{position, f, five}, none}, {{position, g, five}, none}, {{position, h, five}, none}, {{position, a, six}, none}, {{position, b, six}, none}, {{position, c, six}, none}, {{position, d, six}, none}, {{position, e, six}, none}, {{position, f, six}, none}, {{position, g, six}, none}, {{position, h, six}, none}, {{position, a, seven}, none}, {{position, b, seven}, none}, {{position, c, seven}, none}, {{position, d, seven}, none}, {{position, e, seven}, none}, {{position, f, seven}, none}, {{position, g, seven}, none}, {{position, h, seven}, none}, {{position, a, eight}, none}, {{position, b, eight}, none}, {{position, c, eight}, none}, {{position, d, eight}, none}, {{position, e, eight}, none}, {{position, f, eight}, none}, {{position, g, eight}, none}, {{position, h, eight}, none}] ), White_king_positions = board:get_positions(White_king_bitboard), White_queen_positions = board:get_positions(White_queen_bitboard), White_rook_positions = board:get_positions(White_rook_bitboard), White_bishop_positions = board:get_positions(White_bishop_bitboard), White_knight_positions = board:get_positions(White_knight_bitboard), White_pawns_positions = board:get_positions(White_pawns_bitboard), Black_king_positions = board:get_positions(Black_king_bitboard), Black_queen_positions = board:get_positions(Black_queen_bitboard), Black_rook_positions = board:get_positions(Black_rook_bitboard), Black_bishop_positions = board:get_positions(Black_bishop_bitboard), Black_knight_positions = board:get_positions(Black_knight_bitboard), Black_pawns_positions = board:get_positions(Black_pawns_bitboard), Board_map@2 = gleam@list:fold( White_king_positions, Board_map, fun(Board_map@1, Position) -> gleam@map:insert( Board_map@1, Position, {some, {piece, white, king}} ) end ), Board_map@4 = gleam@list:fold( White_queen_positions, Board_map@2, fun(Board_map@3, Position@1) -> gleam@map:insert( Board_map@3, Position@1, {some, {piece, white, queen}} ) end ), Board_map@6 = gleam@list:fold( White_rook_positions, Board_map@4, fun(Board_map@5, Position@2) -> gleam@map:insert( Board_map@5, Position@2, {some, {piece, white, rook}} ) end ), Board_map@8 = gleam@list:fold( White_bishop_positions, Board_map@6, fun(Board_map@7, Position@3) -> gleam@map:insert( Board_map@7, Position@3, {some, {piece, white, bishop}} ) end ), Board_map@10 = gleam@list:fold( White_knight_positions, Board_map@8, fun(Board_map@9, Position@4) -> gleam@map:insert( Board_map@9, Position@4, {some, {piece, white, knight}} ) end ), Board_map@12 = gleam@list:fold( White_pawns_positions, Board_map@10, fun(Board_map@11, Position@5) -> gleam@map:insert( Board_map@11, Position@5, {some, {piece, white, pawn}} ) end ), Board_map@14 = gleam@list:fold( Black_king_positions, Board_map@12, fun(Board_map@13, Position@6) -> gleam@map:insert( Board_map@13, Position@6, {some, {piece, black, king}} ) end ), Board_map@16 = gleam@list:fold( Black_queen_positions, Board_map@14, fun(Board_map@15, Position@7) -> gleam@map:insert( Board_map@15, Position@7, {some, {piece, black, queen}} ) end ), Board_map@18 = gleam@list:fold( Black_rook_positions, Board_map@16, fun(Board_map@17, Position@8) -> gleam@map:insert( Board_map@17, Position@8, {some, {piece, black, rook}} ) end ), Board_map@20 = gleam@list:fold( Black_bishop_positions, Board_map@18, fun(Board_map@19, Position@9) -> gleam@map:insert( Board_map@19, Position@9, {some, {piece, black, bishop}} ) end ), Board_map@22 = gleam@list:fold( Black_knight_positions, Board_map@20, fun(Board_map@21, Position@10) -> gleam@map:insert( Board_map@21, Position@10, {some, {piece, black, knight}} ) end ), Board_map@24 = gleam@list:fold( Black_pawns_positions, Board_map@22, fun(Board_map@23, Position@11) -> gleam@map:insert( Board_map@23, Position@11, {some, {piece, black, pawn}} ) end ), Board_map@24. -spec print_board(game()) -> nil. print_board(Game) -> Board_map = bitboard_repr_to_map_repr(erlang:element(2, Game)), gleam@io:print(<<"\n"/utf8>>), gleam@io:print(<<"\n"/utf8>>), gleam@io:print(<<" +---+---+---+---+---+---+---+---+"/utf8>>), gleam@list:each( [{position, a, eight}, {position, b, eight}, {position, c, eight}, {position, d, eight}, {position, e, eight}, {position, f, eight}, {position, g, eight}, {position, h, eight}, {position, a, seven}, {position, b, seven}, {position, c, seven}, {position, d, seven}, {position, e, seven}, {position, f, seven}, {position, g, seven}, {position, h, seven}, {position, a, six}, {position, b, six}, {position, c, six}, {position, d, six}, {position, e, six}, {position, f, six}, {position, g, six}, {position, h, six}, {position, a, five}, {position, b, five}, {position, c, five}, {position, d, five}, {position, e, five}, {position, f, five}, {position, g, five}, {position, h, five}, {position, a, four}, {position, b, four}, {position, c, four}, {position, d, four}, {position, e, four}, {position, f, four}, {position, g, four}, {position, h, four}, {position, a, three}, {position, b, three}, {position, c, three}, {position, d, three}, {position, e, three}, {position, f, three}, {position, g, three}, {position, h, three}, {position, a, two}, {position, b, two}, {position, c, two}, {position, d, two}, {position, e, two}, {position, f, two}, {position, g, two}, {position, h, two}, {position, a, one}, {position, b, one}, {position, c, one}, {position, d, one}, {position, e, one}, {position, f, one}, {position, g, one}, {position, h, one}], fun(Pos) -> Piece_to_print = gleam@result:unwrap( gleam@map:get(Board_map, Pos), none ), case erlang:element(2, Pos) of a -> gleam@io:print(<<"\n"/utf8>>), gleam@io:print( <<<<" "/utf8, (gleam@int:to_string( position:rank_to_int(erlang:element(3, Pos)) + 1 ))/binary>>/binary, " | "/utf8>> ), gleam@io:print(case Piece_to_print of {some, {piece, white, pawn}} -> <<"♙"/utf8>>; {some, {piece, white, knight}} -> <<"♘"/utf8>>; {some, {piece, white, bishop}} -> <<"♗"/utf8>>; {some, {piece, white, rook}} -> <<"♖"/utf8>>; {some, {piece, white, queen}} -> <<"♕"/utf8>>; {some, {piece, white, king}} -> <<"♔"/utf8>>; {some, {piece, black, pawn}} -> <<"♟"/utf8>>; {some, {piece, black, knight}} -> <<"♞"/utf8>>; {some, {piece, black, bishop}} -> <<"♝"/utf8>>; {some, {piece, black, rook}} -> <<"♜"/utf8>>; {some, {piece, black, queen}} -> <<"♛"/utf8>>; {some, {piece, black, king}} -> <<"♚"/utf8>>; none -> <<" "/utf8>> end), gleam@io:print(<<" | "/utf8>>); h -> gleam@io:print(case Piece_to_print of {some, {piece, white, pawn}} -> <<"♙"/utf8>>; {some, {piece, white, knight}} -> <<"♘"/utf8>>; {some, {piece, white, bishop}} -> <<"♗"/utf8>>; {some, {piece, white, rook}} -> <<"♖"/utf8>>; {some, {piece, white, queen}} -> <<"♕"/utf8>>; {some, {piece, white, king}} -> <<"♔"/utf8>>; {some, {piece, black, pawn}} -> <<"♟"/utf8>>; {some, {piece, black, knight}} -> <<"♞"/utf8>>; {some, {piece, black, bishop}} -> <<"♝"/utf8>>; {some, {piece, black, rook}} -> <<"♜"/utf8>>; {some, {piece, black, queen}} -> <<"♛"/utf8>>; {some, {piece, black, king}} -> <<"♚"/utf8>>; none -> <<" "/utf8>> end), gleam@io:print(<<" | "/utf8>>), gleam@io:print(<<"\n"/utf8>>), gleam@io:print( <<" +---+---+---+---+---+---+---+---+"/utf8>> ); _ -> gleam@io:print(case Piece_to_print of {some, {piece, white, pawn}} -> <<"♙"/utf8>>; {some, {piece, white, knight}} -> <<"♘"/utf8>>; {some, {piece, white, bishop}} -> <<"♗"/utf8>>; {some, {piece, white, rook}} -> <<"♖"/utf8>>; {some, {piece, white, queen}} -> <<"♕"/utf8>>; {some, {piece, white, king}} -> <<"♔"/utf8>>; {some, {piece, black, pawn}} -> <<"♟"/utf8>>; {some, {piece, black, knight}} -> <<"♞"/utf8>>; {some, {piece, black, bishop}} -> <<"♝"/utf8>>; {some, {piece, black, rook}} -> <<"♜"/utf8>>; {some, {piece, black, queen}} -> <<"♛"/utf8>>; {some, {piece, black, king}} -> <<"♚"/utf8>>; none -> <<" "/utf8>> end), gleam@io:print(<<" | "/utf8>>) end end ), gleam@io:print(<<"\n"/utf8>>), gleam@io:print(<<" a b c d e f g h\n"/utf8>>). -spec disable_status(game()) -> game(). disable_status(Game) -> erlang:setelement(5, Game, none). -spec apply_move_uci(game(), binary()) -> game(). apply_move_uci(Game, Move) -> case erlang:element(5, Game) of {some, {in_progress, _, _}} -> case gleam@string:length(Move) of 4 -> Move_chars = gleam@string:to_graphemes(Move), From_file = case gleam@list:first(Move_chars) of {ok, <<"a"/utf8>>} -> a; {ok, <<"b"/utf8>>} -> b; {ok, <<"c"/utf8>>} -> c; {ok, <<"d"/utf8>>} -> d; {ok, <<"e"/utf8>>} -> e; {ok, <<"f"/utf8>>} -> f; {ok, <<"g"/utf8>>} -> g; {ok, <<"h"/utf8>>} -> h; _ -> (erlang:error(#{gleam_error => panic, message => <<"panic expression evaluated"/utf8>>, module => <<"game"/utf8>>, function => <<"apply_move_uci"/utf8>>, line => 4230}))(<<"Invalid move"/utf8>>) end, _assert_subject = gleam@list:rest(Move_chars), {ok, Move_chars@1} = case _assert_subject of {ok, _} -> _assert_subject; _assert_fail -> erlang:error(#{gleam_error => let_assert, message => <<"Assertion pattern match failed"/utf8>>, value => _assert_fail, module => <<"game"/utf8>>, function => <<"apply_move_uci"/utf8>>, line => 4232}) end, From_rank = case gleam@list:first(Move_chars@1) of {ok, <<"1"/utf8>>} -> one; {ok, <<"2"/utf8>>} -> two; {ok, <<"3"/utf8>>} -> three; {ok, <<"4"/utf8>>} -> four; {ok, <<"5"/utf8>>} -> five; {ok, <<"6"/utf8>>} -> six; {ok, <<"7"/utf8>>} -> seven; {ok, <<"8"/utf8>>} -> eight; _ -> (erlang:error(#{gleam_error => panic, message => <<"panic expression evaluated"/utf8>>, module => <<"game"/utf8>>, function => <<"apply_move_uci"/utf8>>, line => 4242}))(<<"Invalid move"/utf8>>) end, _assert_subject@1 = gleam@list:rest(Move_chars@1), {ok, Move_chars@2} = case _assert_subject@1 of {ok, _} -> _assert_subject@1; _assert_fail@1 -> erlang:error(#{gleam_error => let_assert, message => <<"Assertion pattern match failed"/utf8>>, value => _assert_fail@1, module => <<"game"/utf8>>, function => <<"apply_move_uci"/utf8>>, line => 4244}) end, To_file = case gleam@list:first(Move_chars@2) of {ok, <<"a"/utf8>>} -> a; {ok, <<"b"/utf8>>} -> b; {ok, <<"c"/utf8>>} -> c; {ok, <<"d"/utf8>>} -> d; {ok, <<"e"/utf8>>} -> e; {ok, <<"f"/utf8>>} -> f; {ok, <<"g"/utf8>>} -> g; {ok, <<"h"/utf8>>} -> h; _ -> (erlang:error(#{gleam_error => panic, message => <<"panic expression evaluated"/utf8>>, module => <<"game"/utf8>>, function => <<"apply_move_uci"/utf8>>, line => 4254}))(<<"Invalid move"/utf8>>) end, _assert_subject@2 = gleam@list:rest(Move_chars@2), {ok, Move_chars@3} = case _assert_subject@2 of {ok, _} -> _assert_subject@2; _assert_fail@2 -> erlang:error(#{gleam_error => let_assert, message => <<"Assertion pattern match failed"/utf8>>, value => _assert_fail@2, module => <<"game"/utf8>>, function => <<"apply_move_uci"/utf8>>, line => 4256}) end, To_rank = case gleam@list:first(Move_chars@3) of {ok, <<"1"/utf8>>} -> one; {ok, <<"2"/utf8>>} -> two; {ok, <<"3"/utf8>>} -> three; {ok, <<"4"/utf8>>} -> four; {ok, <<"5"/utf8>>} -> five; {ok, <<"6"/utf8>>} -> six; {ok, <<"7"/utf8>>} -> seven; {ok, <<"8"/utf8>>} -> eight; _ -> (erlang:error(#{gleam_error => panic, message => <<"panic expression evaluated"/utf8>>, module => <<"game"/utf8>>, function => <<"apply_move_uci"/utf8>>, line => 4266}))(<<"Invalid move"/utf8>>) end, Promo = case gleam@list:length(Move_chars@3) of 5 -> _assert_subject@3 = gleam@list:rest(Move_chars@3), {ok, Move_chars@4} = case _assert_subject@3 of {ok, _} -> _assert_subject@3; _assert_fail@3 -> erlang:error(#{gleam_error => let_assert, message => <<"Assertion pattern match failed"/utf8>>, value => _assert_fail@3, module => <<"game"/utf8>>, function => <<"apply_move_uci"/utf8>>, line => 4271}) end, case gleam@list:first(Move_chars@4) of {ok, <<"q"/utf8>>} -> {some, queen}; {ok, <<"r"/utf8>>} -> {some, rook}; {ok, <<"b"/utf8>>} -> {some, bishop}; {ok, <<"n"/utf8>>} -> {some, knight}; _ -> (erlang:error(#{gleam_error => panic, message => <<"panic expression evaluated"/utf8>>, module => <<"game"/utf8>>, function => <<"apply_move_uci"/utf8>>, line => 4277}))( <<"Invalid move"/utf8>> ) end; _ -> none end, Legal_moves = begin _pipe = generate_pseudo_legal_move_list( Game, erlang:element(3, Game) ), gleam@list:filter( _pipe, fun(Move@1) -> is_move_legal(Game, Move@1) end ) end, _assert_subject@4 = gleam@list:find( Legal_moves, fun(Legal_move) -> case Legal_move of {normal, From, To, _, {some, Promotion}} -> case Promo of {some, Promo@1} -> ((((erlang:element(2, From) =:= From_file) andalso (erlang:element(3, From) =:= From_rank)) andalso (erlang:element(2, To) =:= To_file)) andalso (erlang:element(3, To) =:= To_rank)) andalso (Promo@1 =:= erlang:element( 3, Promotion )); none -> false end; {normal, From@1, To@1, _, none} -> ((((erlang:element(2, From@1) =:= From_file) andalso (erlang:element(3, From@1) =:= From_rank)) andalso (erlang:element(2, To@1) =:= To_file)) andalso (erlang:element(3, To@1) =:= To_rank)) andalso (Promo =:= none); {castle, From@2, To@2} -> (((erlang:element(2, From@2) =:= From_file) andalso (erlang:element(3, From@2) =:= From_rank)) andalso (erlang:element(2, To@2) =:= To_file)) andalso (erlang:element(3, To@2) =:= To_rank); {en_passant, From@3, To@3} -> (((erlang:element(2, From@3) =:= From_file) andalso (erlang:element(3, From@3) =:= From_rank)) andalso (erlang:element(2, To@3) =:= To_file)) andalso (erlang:element(3, To@3) =:= To_rank); _ -> (erlang:error(#{gleam_error => panic, message => <<"panic expression evaluated"/utf8>>, module => <<"game"/utf8>>, function => <<"apply_move_uci"/utf8>>, line => 4316}))( <<"Invalid move"/utf8>> ) end end ), {ok, Move@2} = case _assert_subject@4 of {ok, _} -> _assert_subject@4; _assert_fail@4 -> erlang:error(#{gleam_error => let_assert, message => <<"Assertion pattern match failed"/utf8>>, value => _assert_fail@4, module => <<"game"/utf8>>, function => <<"apply_move_uci"/utf8>>, line => 4290}) end, New_game_state = apply_pseudo_legal_move(Game, Move@2), New_game_state; 5 -> Move_chars = gleam@string:to_graphemes(Move), From_file = case gleam@list:first(Move_chars) of {ok, <<"a"/utf8>>} -> a; {ok, <<"b"/utf8>>} -> b; {ok, <<"c"/utf8>>} -> c; {ok, <<"d"/utf8>>} -> d; {ok, <<"e"/utf8>>} -> e; {ok, <<"f"/utf8>>} -> f; {ok, <<"g"/utf8>>} -> g; {ok, <<"h"/utf8>>} -> h; _ -> (erlang:error(#{gleam_error => panic, message => <<"panic expression evaluated"/utf8>>, module => <<"game"/utf8>>, function => <<"apply_move_uci"/utf8>>, line => 4230}))(<<"Invalid move"/utf8>>) end, _assert_subject = gleam@list:rest(Move_chars), {ok, Move_chars@1} = case _assert_subject of {ok, _} -> _assert_subject; _assert_fail -> erlang:error(#{gleam_error => let_assert, message => <<"Assertion pattern match failed"/utf8>>, value => _assert_fail, module => <<"game"/utf8>>, function => <<"apply_move_uci"/utf8>>, line => 4232}) end, From_rank = case gleam@list:first(Move_chars@1) of {ok, <<"1"/utf8>>} -> one; {ok, <<"2"/utf8>>} -> two; {ok, <<"3"/utf8>>} -> three; {ok, <<"4"/utf8>>} -> four; {ok, <<"5"/utf8>>} -> five; {ok, <<"6"/utf8>>} -> six; {ok, <<"7"/utf8>>} -> seven; {ok, <<"8"/utf8>>} -> eight; _ -> (erlang:error(#{gleam_error => panic, message => <<"panic expression evaluated"/utf8>>, module => <<"game"/utf8>>, function => <<"apply_move_uci"/utf8>>, line => 4242}))(<<"Invalid move"/utf8>>) end, _assert_subject@1 = gleam@list:rest(Move_chars@1), {ok, Move_chars@2} = case _assert_subject@1 of {ok, _} -> _assert_subject@1; _assert_fail@1 -> erlang:error(#{gleam_error => let_assert, message => <<"Assertion pattern match failed"/utf8>>, value => _assert_fail@1, module => <<"game"/utf8>>, function => <<"apply_move_uci"/utf8>>, line => 4244}) end, To_file = case gleam@list:first(Move_chars@2) of {ok, <<"a"/utf8>>} -> a; {ok, <<"b"/utf8>>} -> b; {ok, <<"c"/utf8>>} -> c; {ok, <<"d"/utf8>>} -> d; {ok, <<"e"/utf8>>} -> e; {ok, <<"f"/utf8>>} -> f; {ok, <<"g"/utf8>>} -> g; {ok, <<"h"/utf8>>} -> h; _ -> (erlang:error(#{gleam_error => panic, message => <<"panic expression evaluated"/utf8>>, module => <<"game"/utf8>>, function => <<"apply_move_uci"/utf8>>, line => 4254}))(<<"Invalid move"/utf8>>) end, _assert_subject@2 = gleam@list:rest(Move_chars@2), {ok, Move_chars@3} = case _assert_subject@2 of {ok, _} -> _assert_subject@2; _assert_fail@2 -> erlang:error(#{gleam_error => let_assert, message => <<"Assertion pattern match failed"/utf8>>, value => _assert_fail@2, module => <<"game"/utf8>>, function => <<"apply_move_uci"/utf8>>, line => 4256}) end, To_rank = case gleam@list:first(Move_chars@3) of {ok, <<"1"/utf8>>} -> one; {ok, <<"2"/utf8>>} -> two; {ok, <<"3"/utf8>>} -> three; {ok, <<"4"/utf8>>} -> four; {ok, <<"5"/utf8>>} -> five; {ok, <<"6"/utf8>>} -> six; {ok, <<"7"/utf8>>} -> seven; {ok, <<"8"/utf8>>} -> eight; _ -> (erlang:error(#{gleam_error => panic, message => <<"panic expression evaluated"/utf8>>, module => <<"game"/utf8>>, function => <<"apply_move_uci"/utf8>>, line => 4266}))(<<"Invalid move"/utf8>>) end, Promo = case gleam@list:length(Move_chars@3) of 5 -> _assert_subject@3 = gleam@list:rest(Move_chars@3), {ok, Move_chars@4} = case _assert_subject@3 of {ok, _} -> _assert_subject@3; _assert_fail@3 -> erlang:error(#{gleam_error => let_assert, message => <<"Assertion pattern match failed"/utf8>>, value => _assert_fail@3, module => <<"game"/utf8>>, function => <<"apply_move_uci"/utf8>>, line => 4271}) end, case gleam@list:first(Move_chars@4) of {ok, <<"q"/utf8>>} -> {some, queen}; {ok, <<"r"/utf8>>} -> {some, rook}; {ok, <<"b"/utf8>>} -> {some, bishop}; {ok, <<"n"/utf8>>} -> {some, knight}; _ -> (erlang:error(#{gleam_error => panic, message => <<"panic expression evaluated"/utf8>>, module => <<"game"/utf8>>, function => <<"apply_move_uci"/utf8>>, line => 4277}))( <<"Invalid move"/utf8>> ) end; _ -> none end, Legal_moves = begin _pipe = generate_pseudo_legal_move_list( Game, erlang:element(3, Game) ), gleam@list:filter( _pipe, fun(Move@1) -> is_move_legal(Game, Move@1) end ) end, _assert_subject@4 = gleam@list:find( Legal_moves, fun(Legal_move) -> case Legal_move of {normal, From, To, _, {some, Promotion}} -> case Promo of {some, Promo@1} -> ((((erlang:element(2, From) =:= From_file) andalso (erlang:element(3, From) =:= From_rank)) andalso (erlang:element(2, To) =:= To_file)) andalso (erlang:element(3, To) =:= To_rank)) andalso (Promo@1 =:= erlang:element( 3, Promotion )); none -> false end; {normal, From@1, To@1, _, none} -> ((((erlang:element(2, From@1) =:= From_file) andalso (erlang:element(3, From@1) =:= From_rank)) andalso (erlang:element(2, To@1) =:= To_file)) andalso (erlang:element(3, To@1) =:= To_rank)) andalso (Promo =:= none); {castle, From@2, To@2} -> (((erlang:element(2, From@2) =:= From_file) andalso (erlang:element(3, From@2) =:= From_rank)) andalso (erlang:element(2, To@2) =:= To_file)) andalso (erlang:element(3, To@2) =:= To_rank); {en_passant, From@3, To@3} -> (((erlang:element(2, From@3) =:= From_file) andalso (erlang:element(3, From@3) =:= From_rank)) andalso (erlang:element(2, To@3) =:= To_file)) andalso (erlang:element(3, To@3) =:= To_rank); _ -> (erlang:error(#{gleam_error => panic, message => <<"panic expression evaluated"/utf8>>, module => <<"game"/utf8>>, function => <<"apply_move_uci"/utf8>>, line => 4316}))( <<"Invalid move"/utf8>> ) end end ), {ok, Move@2} = case _assert_subject@4 of {ok, _} -> _assert_subject@4; _assert_fail@4 -> erlang:error(#{gleam_error => let_assert, message => <<"Assertion pattern match failed"/utf8>>, value => _assert_fail@4, module => <<"game"/utf8>>, function => <<"apply_move_uci"/utf8>>, line => 4290}) end, New_game_state = apply_pseudo_legal_move(Game, Move@2), New_game_state; _ -> (erlang:error(#{gleam_error => panic, message => <<"panic expression evaluated"/utf8>>, module => <<"game"/utf8>>, function => <<"apply_move_uci"/utf8>>, line => 4323}))(<<"Invalid move"/utf8>>) end; none -> case gleam@string:length(Move) of 4 -> Move_chars = gleam@string:to_graphemes(Move), From_file = case gleam@list:first(Move_chars) of {ok, <<"a"/utf8>>} -> a; {ok, <<"b"/utf8>>} -> b; {ok, <<"c"/utf8>>} -> c; {ok, <<"d"/utf8>>} -> d; {ok, <<"e"/utf8>>} -> e; {ok, <<"f"/utf8>>} -> f; {ok, <<"g"/utf8>>} -> g; {ok, <<"h"/utf8>>} -> h; _ -> (erlang:error(#{gleam_error => panic, message => <<"panic expression evaluated"/utf8>>, module => <<"game"/utf8>>, function => <<"apply_move_uci"/utf8>>, line => 4230}))(<<"Invalid move"/utf8>>) end, _assert_subject = gleam@list:rest(Move_chars), {ok, Move_chars@1} = case _assert_subject of {ok, _} -> _assert_subject; _assert_fail -> erlang:error(#{gleam_error => let_assert, message => <<"Assertion pattern match failed"/utf8>>, value => _assert_fail, module => <<"game"/utf8>>, function => <<"apply_move_uci"/utf8>>, line => 4232}) end, From_rank = case gleam@list:first(Move_chars@1) of {ok, <<"1"/utf8>>} -> one; {ok, <<"2"/utf8>>} -> two; {ok, <<"3"/utf8>>} -> three; {ok, <<"4"/utf8>>} -> four; {ok, <<"5"/utf8>>} -> five; {ok, <<"6"/utf8>>} -> six; {ok, <<"7"/utf8>>} -> seven; {ok, <<"8"/utf8>>} -> eight; _ -> (erlang:error(#{gleam_error => panic, message => <<"panic expression evaluated"/utf8>>, module => <<"game"/utf8>>, function => <<"apply_move_uci"/utf8>>, line => 4242}))(<<"Invalid move"/utf8>>) end, _assert_subject@1 = gleam@list:rest(Move_chars@1), {ok, Move_chars@2} = case _assert_subject@1 of {ok, _} -> _assert_subject@1; _assert_fail@1 -> erlang:error(#{gleam_error => let_assert, message => <<"Assertion pattern match failed"/utf8>>, value => _assert_fail@1, module => <<"game"/utf8>>, function => <<"apply_move_uci"/utf8>>, line => 4244}) end, To_file = case gleam@list:first(Move_chars@2) of {ok, <<"a"/utf8>>} -> a; {ok, <<"b"/utf8>>} -> b; {ok, <<"c"/utf8>>} -> c; {ok, <<"d"/utf8>>} -> d; {ok, <<"e"/utf8>>} -> e; {ok, <<"f"/utf8>>} -> f; {ok, <<"g"/utf8>>} -> g; {ok, <<"h"/utf8>>} -> h; _ -> (erlang:error(#{gleam_error => panic, message => <<"panic expression evaluated"/utf8>>, module => <<"game"/utf8>>, function => <<"apply_move_uci"/utf8>>, line => 4254}))(<<"Invalid move"/utf8>>) end, _assert_subject@2 = gleam@list:rest(Move_chars@2), {ok, Move_chars@3} = case _assert_subject@2 of {ok, _} -> _assert_subject@2; _assert_fail@2 -> erlang:error(#{gleam_error => let_assert, message => <<"Assertion pattern match failed"/utf8>>, value => _assert_fail@2, module => <<"game"/utf8>>, function => <<"apply_move_uci"/utf8>>, line => 4256}) end, To_rank = case gleam@list:first(Move_chars@3) of {ok, <<"1"/utf8>>} -> one; {ok, <<"2"/utf8>>} -> two; {ok, <<"3"/utf8>>} -> three; {ok, <<"4"/utf8>>} -> four; {ok, <<"5"/utf8>>} -> five; {ok, <<"6"/utf8>>} -> six; {ok, <<"7"/utf8>>} -> seven; {ok, <<"8"/utf8>>} -> eight; _ -> (erlang:error(#{gleam_error => panic, message => <<"panic expression evaluated"/utf8>>, module => <<"game"/utf8>>, function => <<"apply_move_uci"/utf8>>, line => 4266}))(<<"Invalid move"/utf8>>) end, Promo = case gleam@list:length(Move_chars@3) of 5 -> _assert_subject@3 = gleam@list:rest(Move_chars@3), {ok, Move_chars@4} = case _assert_subject@3 of {ok, _} -> _assert_subject@3; _assert_fail@3 -> erlang:error(#{gleam_error => let_assert, message => <<"Assertion pattern match failed"/utf8>>, value => _assert_fail@3, module => <<"game"/utf8>>, function => <<"apply_move_uci"/utf8>>, line => 4271}) end, case gleam@list:first(Move_chars@4) of {ok, <<"q"/utf8>>} -> {some, queen}; {ok, <<"r"/utf8>>} -> {some, rook}; {ok, <<"b"/utf8>>} -> {some, bishop}; {ok, <<"n"/utf8>>} -> {some, knight}; _ -> (erlang:error(#{gleam_error => panic, message => <<"panic expression evaluated"/utf8>>, module => <<"game"/utf8>>, function => <<"apply_move_uci"/utf8>>, line => 4277}))( <<"Invalid move"/utf8>> ) end; _ -> none end, Legal_moves = begin _pipe = generate_pseudo_legal_move_list( Game, erlang:element(3, Game) ), gleam@list:filter( _pipe, fun(Move@1) -> is_move_legal(Game, Move@1) end ) end, _assert_subject@4 = gleam@list:find( Legal_moves, fun(Legal_move) -> case Legal_move of {normal, From, To, _, {some, Promotion}} -> case Promo of {some, Promo@1} -> ((((erlang:element(2, From) =:= From_file) andalso (erlang:element(3, From) =:= From_rank)) andalso (erlang:element(2, To) =:= To_file)) andalso (erlang:element(3, To) =:= To_rank)) andalso (Promo@1 =:= erlang:element( 3, Promotion )); none -> false end; {normal, From@1, To@1, _, none} -> ((((erlang:element(2, From@1) =:= From_file) andalso (erlang:element(3, From@1) =:= From_rank)) andalso (erlang:element(2, To@1) =:= To_file)) andalso (erlang:element(3, To@1) =:= To_rank)) andalso (Promo =:= none); {castle, From@2, To@2} -> (((erlang:element(2, From@2) =:= From_file) andalso (erlang:element(3, From@2) =:= From_rank)) andalso (erlang:element(2, To@2) =:= To_file)) andalso (erlang:element(3, To@2) =:= To_rank); {en_passant, From@3, To@3} -> (((erlang:element(2, From@3) =:= From_file) andalso (erlang:element(3, From@3) =:= From_rank)) andalso (erlang:element(2, To@3) =:= To_file)) andalso (erlang:element(3, To@3) =:= To_rank); _ -> (erlang:error(#{gleam_error => panic, message => <<"panic expression evaluated"/utf8>>, module => <<"game"/utf8>>, function => <<"apply_move_uci"/utf8>>, line => 4316}))( <<"Invalid move"/utf8>> ) end end ), {ok, Move@2} = case _assert_subject@4 of {ok, _} -> _assert_subject@4; _assert_fail@4 -> erlang:error(#{gleam_error => let_assert, message => <<"Assertion pattern match failed"/utf8>>, value => _assert_fail@4, module => <<"game"/utf8>>, function => <<"apply_move_uci"/utf8>>, line => 4290}) end, New_game_state = apply_pseudo_legal_move(Game, Move@2), New_game_state; 5 -> Move_chars = gleam@string:to_graphemes(Move), From_file = case gleam@list:first(Move_chars) of {ok, <<"a"/utf8>>} -> a; {ok, <<"b"/utf8>>} -> b; {ok, <<"c"/utf8>>} -> c; {ok, <<"d"/utf8>>} -> d; {ok, <<"e"/utf8>>} -> e; {ok, <<"f"/utf8>>} -> f; {ok, <<"g"/utf8>>} -> g; {ok, <<"h"/utf8>>} -> h; _ -> (erlang:error(#{gleam_error => panic, message => <<"panic expression evaluated"/utf8>>, module => <<"game"/utf8>>, function => <<"apply_move_uci"/utf8>>, line => 4230}))(<<"Invalid move"/utf8>>) end, _assert_subject = gleam@list:rest(Move_chars), {ok, Move_chars@1} = case _assert_subject of {ok, _} -> _assert_subject; _assert_fail -> erlang:error(#{gleam_error => let_assert, message => <<"Assertion pattern match failed"/utf8>>, value => _assert_fail, module => <<"game"/utf8>>, function => <<"apply_move_uci"/utf8>>, line => 4232}) end, From_rank = case gleam@list:first(Move_chars@1) of {ok, <<"1"/utf8>>} -> one; {ok, <<"2"/utf8>>} -> two; {ok, <<"3"/utf8>>} -> three; {ok, <<"4"/utf8>>} -> four; {ok, <<"5"/utf8>>} -> five; {ok, <<"6"/utf8>>} -> six; {ok, <<"7"/utf8>>} -> seven; {ok, <<"8"/utf8>>} -> eight; _ -> (erlang:error(#{gleam_error => panic, message => <<"panic expression evaluated"/utf8>>, module => <<"game"/utf8>>, function => <<"apply_move_uci"/utf8>>, line => 4242}))(<<"Invalid move"/utf8>>) end, _assert_subject@1 = gleam@list:rest(Move_chars@1), {ok, Move_chars@2} = case _assert_subject@1 of {ok, _} -> _assert_subject@1; _assert_fail@1 -> erlang:error(#{gleam_error => let_assert, message => <<"Assertion pattern match failed"/utf8>>, value => _assert_fail@1, module => <<"game"/utf8>>, function => <<"apply_move_uci"/utf8>>, line => 4244}) end, To_file = case gleam@list:first(Move_chars@2) of {ok, <<"a"/utf8>>} -> a; {ok, <<"b"/utf8>>} -> b; {ok, <<"c"/utf8>>} -> c; {ok, <<"d"/utf8>>} -> d; {ok, <<"e"/utf8>>} -> e; {ok, <<"f"/utf8>>} -> f; {ok, <<"g"/utf8>>} -> g; {ok, <<"h"/utf8>>} -> h; _ -> (erlang:error(#{gleam_error => panic, message => <<"panic expression evaluated"/utf8>>, module => <<"game"/utf8>>, function => <<"apply_move_uci"/utf8>>, line => 4254}))(<<"Invalid move"/utf8>>) end, _assert_subject@2 = gleam@list:rest(Move_chars@2), {ok, Move_chars@3} = case _assert_subject@2 of {ok, _} -> _assert_subject@2; _assert_fail@2 -> erlang:error(#{gleam_error => let_assert, message => <<"Assertion pattern match failed"/utf8>>, value => _assert_fail@2, module => <<"game"/utf8>>, function => <<"apply_move_uci"/utf8>>, line => 4256}) end, To_rank = case gleam@list:first(Move_chars@3) of {ok, <<"1"/utf8>>} -> one; {ok, <<"2"/utf8>>} -> two; {ok, <<"3"/utf8>>} -> three; {ok, <<"4"/utf8>>} -> four; {ok, <<"5"/utf8>>} -> five; {ok, <<"6"/utf8>>} -> six; {ok, <<"7"/utf8>>} -> seven; {ok, <<"8"/utf8>>} -> eight; _ -> (erlang:error(#{gleam_error => panic, message => <<"panic expression evaluated"/utf8>>, module => <<"game"/utf8>>, function => <<"apply_move_uci"/utf8>>, line => 4266}))(<<"Invalid move"/utf8>>) end, Promo = case gleam@list:length(Move_chars@3) of 5 -> _assert_subject@3 = gleam@list:rest(Move_chars@3), {ok, Move_chars@4} = case _assert_subject@3 of {ok, _} -> _assert_subject@3; _assert_fail@3 -> erlang:error(#{gleam_error => let_assert, message => <<"Assertion pattern match failed"/utf8>>, value => _assert_fail@3, module => <<"game"/utf8>>, function => <<"apply_move_uci"/utf8>>, line => 4271}) end, case gleam@list:first(Move_chars@4) of {ok, <<"q"/utf8>>} -> {some, queen}; {ok, <<"r"/utf8>>} -> {some, rook}; {ok, <<"b"/utf8>>} -> {some, bishop}; {ok, <<"n"/utf8>>} -> {some, knight}; _ -> (erlang:error(#{gleam_error => panic, message => <<"panic expression evaluated"/utf8>>, module => <<"game"/utf8>>, function => <<"apply_move_uci"/utf8>>, line => 4277}))( <<"Invalid move"/utf8>> ) end; _ -> none end, Legal_moves = begin _pipe = generate_pseudo_legal_move_list( Game, erlang:element(3, Game) ), gleam@list:filter( _pipe, fun(Move@1) -> is_move_legal(Game, Move@1) end ) end, _assert_subject@4 = gleam@list:find( Legal_moves, fun(Legal_move) -> case Legal_move of {normal, From, To, _, {some, Promotion}} -> case Promo of {some, Promo@1} -> ((((erlang:element(2, From) =:= From_file) andalso (erlang:element(3, From) =:= From_rank)) andalso (erlang:element(2, To) =:= To_file)) andalso (erlang:element(3, To) =:= To_rank)) andalso (Promo@1 =:= erlang:element( 3, Promotion )); none -> false end; {normal, From@1, To@1, _, none} -> ((((erlang:element(2, From@1) =:= From_file) andalso (erlang:element(3, From@1) =:= From_rank)) andalso (erlang:element(2, To@1) =:= To_file)) andalso (erlang:element(3, To@1) =:= To_rank)) andalso (Promo =:= none); {castle, From@2, To@2} -> (((erlang:element(2, From@2) =:= From_file) andalso (erlang:element(3, From@2) =:= From_rank)) andalso (erlang:element(2, To@2) =:= To_file)) andalso (erlang:element(3, To@2) =:= To_rank); {en_passant, From@3, To@3} -> (((erlang:element(2, From@3) =:= From_file) andalso (erlang:element(3, From@3) =:= From_rank)) andalso (erlang:element(2, To@3) =:= To_file)) andalso (erlang:element(3, To@3) =:= To_rank); _ -> (erlang:error(#{gleam_error => panic, message => <<"panic expression evaluated"/utf8>>, module => <<"game"/utf8>>, function => <<"apply_move_uci"/utf8>>, line => 4316}))( <<"Invalid move"/utf8>> ) end end ), {ok, Move@2} = case _assert_subject@4 of {ok, _} -> _assert_subject@4; _assert_fail@4 -> erlang:error(#{gleam_error => let_assert, message => <<"Assertion pattern match failed"/utf8>>, value => _assert_fail@4, module => <<"game"/utf8>>, function => <<"apply_move_uci"/utf8>>, line => 4290}) end, New_game_state = apply_pseudo_legal_move(Game, Move@2), New_game_state; _ -> (erlang:error(#{gleam_error => panic, message => <<"panic expression evaluated"/utf8>>, module => <<"game"/utf8>>, function => <<"apply_move_uci"/utf8>>, line => 4323}))(<<"Invalid move"/utf8>>) end; {some, _} -> Game end. -spec undo_move(game()) -> game(). undo_move(Game) -> case erlang:element(5, Game) of {some, {in_progress, _, _}} -> case erlang:element(4, Game) of [] -> Game; [Move | Rest] -> case Move of {normal, From, To, Captured_piece, Promo_piece} -> Moving_piece = case board:get_piece_at_position( erlang:element(2, Game), To ) of none -> (erlang:error(#{gleam_error => panic, message => <<"panic expression evaluated"/utf8>>, module => <<"game"/utf8>>, function => <<"undo_move"/utf8>>, line => 4348}))( <<"Invalid move"/utf8>> ); {some, Piece} -> Piece end, Moving_piece@1 = case Promo_piece of none -> Moving_piece; {some, _} -> {piece, erlang:element(2, Moving_piece), pawn} end, New_turn = (case erlang:element(3, Game) of white -> black; black -> white end), New_game_state = case Captured_piece of none -> _assert_subject = board:remove_piece_at_position( erlang:element(2, Game), To ), {some, New_board} = 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 => <<"game"/utf8>>, function => <<"undo_move"/utf8>>, line => 4367} ) end, erlang:setelement(2, Game, New_board); {some, Piece@1} -> _assert_subject@1 = board:remove_piece_at_position( erlang:element(2, Game), To ), {some, New_board@1} = case _assert_subject@1 of {some, _} -> _assert_subject@1; _assert_fail@1 -> erlang:error( #{gleam_error => let_assert, message => <<"Assertion pattern match failed"/utf8>>, value => _assert_fail@1, module => <<"game"/utf8>>, function => <<"undo_move"/utf8>>, line => 4373} ) end, New_board@2 = board:set_piece_at_position( New_board@1, To, Piece@1 ), erlang:setelement(2, Game, New_board@2) end, New_board@3 = board:set_piece_at_position( erlang:element(2, New_game_state), From, Moving_piece@1 ), New_game_state@1 = erlang:setelement( 2, New_game_state, New_board@3 ), New_ply = erlang:element(6, Game) - 1, New_white_kingside_castle = case erlang:element( 7, Game ) of yes -> yes; {no, Ply} -> case Ply =:= erlang:element(6, Game) of true -> yes; false -> {no, Ply} end end, New_white_queenside_castle = case erlang:element( 8, Game ) of yes -> yes; {no, Ply@1} -> case Ply@1 =:= erlang:element(6, Game) of true -> yes; false -> {no, Ply@1} end end, New_black_kingside_castle = case erlang:element( 9, Game ) of yes -> yes; {no, Ply@2} -> case Ply@2 =:= erlang:element(6, Game) of true -> yes; false -> {no, Ply@2} end end, New_black_queenside_castle = case erlang:element( 10, Game ) of yes -> yes; {no, Ply@3} -> case Ply@3 =:= erlang:element(6, Game) of true -> yes; false -> {no, Ply@3} end end, New_history = Rest, New_en_passant = case Rest of [] -> none; [Move@1] -> case Move@1 of {normal, {position, _, two}, {position, File, four}, none, none} when erlang:element(3, Game) =:= white -> Moving_piece@2 = case board:get_piece_at_position( erlang:element( 2, New_game_state@1 ), {position, File, four} ) of {some, Piece@2} -> Piece@2; none -> (erlang:error( #{gleam_error => panic, message => <<"panic expression evaluated"/utf8>>, module => <<"game"/utf8>>, function => <<"undo_move"/utf8>>, line => 4457} ))(<<"Invalid move"/utf8>>) end, case Moving_piece@2 of {piece, _, pawn} -> {some, {position, File, three}}; _ -> none end; {normal, {position, _, seven}, {position, File@1, five}, none, none} when erlang:element(3, Game) =:= black -> Moving_piece@3 = case board:get_piece_at_position( erlang:element( 2, New_game_state@1 ), {position, File@1, five} ) of {some, Piece@3} -> Piece@3; none -> (erlang:error( #{gleam_error => panic, message => <<"panic expression evaluated"/utf8>>, module => <<"game"/utf8>>, function => <<"undo_move"/utf8>>, line => 4479} ))(<<"Invalid move"/utf8>>) end, case Moving_piece@3 of {piece, _, pawn} -> {some, {position, File@1, six}}; _ -> none end; _ -> none end; [Move@1 | _] -> case Move@1 of {normal, {position, _, two}, {position, File, four}, none, none} when erlang:element(3, Game) =:= white -> Moving_piece@2 = case board:get_piece_at_position( erlang:element( 2, New_game_state@1 ), {position, File, four} ) of {some, Piece@2} -> Piece@2; none -> (erlang:error( #{gleam_error => panic, message => <<"panic expression evaluated"/utf8>>, module => <<"game"/utf8>>, function => <<"undo_move"/utf8>>, line => 4457} ))(<<"Invalid move"/utf8>>) end, case Moving_piece@2 of {piece, _, pawn} -> {some, {position, File, three}}; _ -> none end; {normal, {position, _, seven}, {position, File@1, five}, none, none} when erlang:element(3, Game) =:= black -> Moving_piece@3 = case board:get_piece_at_position( erlang:element( 2, New_game_state@1 ), {position, File@1, five} ) of {some, Piece@3} -> Piece@3; none -> (erlang:error( #{gleam_error => panic, message => <<"panic expression evaluated"/utf8>>, module => <<"game"/utf8>>, function => <<"undo_move"/utf8>>, line => 4479} ))(<<"Invalid move"/utf8>>) end, case Moving_piece@3 of {piece, _, pawn} -> {some, {position, File@1, six}}; _ -> none end; _ -> none end end, New_status = case erlang:element(5, Game) of none -> none; {some, {in_progress, Fifty_move_rule, Threefold_repetition_rule}} -> New_fifty_move_rule = case Fifty_move_rule of 0 -> 0; _ -> Fifty_move_rule - 1 end, Threefold_position = {three_fold_position, erlang:element(3, Game), erlang:element(2, Game), erlang:element(11, Game), erlang:element(7, Game), erlang:element(8, Game), erlang:element(9, Game), erlang:element(10, Game)}, New_threefold_repetition_rule = case gleam@map:get( Threefold_repetition_rule, Threefold_position ) of {error, nil} -> Threefold_repetition_rule; {ok, 0} -> gleam@map:delete( Threefold_repetition_rule, Threefold_position ); {ok, 1} -> gleam@map:delete( Threefold_repetition_rule, Threefold_position ); {ok, Count} -> gleam@map:insert( Threefold_repetition_rule, Threefold_position, Count - 1 ) end, {some, {in_progress, New_fifty_move_rule, New_threefold_repetition_rule}}; {some, _} -> (erlang:error(#{gleam_error => panic, message => <<"panic expression evaluated"/utf8>>, module => <<"game"/utf8>>, function => <<"undo_move"/utf8>>, line => 4531}))( <<"trying to undo a move in a finished game is not possible"/utf8>> ) end, New_game_state@2 = erlang:setelement( 11, erlang:setelement( 10, erlang:setelement( 9, erlang:setelement( 8, erlang:setelement( 7, erlang:setelement( 5, erlang:setelement( 6, erlang:setelement( 4, erlang:setelement( 3, New_game_state@1, New_turn ), New_history ), New_ply ), New_status ), New_white_kingside_castle ), New_white_queenside_castle ), New_black_kingside_castle ), New_black_queenside_castle ), New_en_passant ), New_game_state@2; {castle, From@1, To@1} -> New_turn@1 = (case erlang:element(3, Game) of white -> black; black -> white end), New_game_state@3 = erlang:setelement( 2, Game, board:set_piece_at_position( erlang:element(2, Game), From@1, {piece, New_turn@1, king} ) ), Rook_castling_target_square = case To@1 of {position, g, one} -> {position, f, one}; {position, g, eight} -> {position, f, eight}; {position, c, one} -> {position, d, one}; {position, c, eight} -> {position, d, eight}; _ -> (erlang:error(#{gleam_error => panic, message => <<"panic expression evaluated"/utf8>>, module => <<"game"/utf8>>, function => <<"undo_move"/utf8>>, line => 4577}))( <<"Invalid castle move"/utf8>> ) end, New_board@4 = case board:remove_piece_at_position( erlang:element(2, New_game_state@3), Rook_castling_target_square ) of {some, Board} -> Board; none -> (erlang:error(#{gleam_error => panic, message => <<"panic expression evaluated"/utf8>>, module => <<"game"/utf8>>, function => <<"undo_move"/utf8>>, line => 4587}))( <<"Invalid move"/utf8>> ) end, New_game_state@4 = erlang:setelement( 2, New_game_state@3, New_board@4 ), _assert_subject@2 = board:remove_piece_at_position( erlang:element(2, New_game_state@4), To@1 ), {some, New_board@5} = case _assert_subject@2 of {some, _} -> _assert_subject@2; _assert_fail@2 -> erlang:error(#{gleam_error => let_assert, message => <<"Assertion pattern match failed"/utf8>>, value => _assert_fail@2, module => <<"game"/utf8>>, function => <<"undo_move"/utf8>>, line => 4591}) end, New_game_state@5 = erlang:setelement( 2, New_game_state@4, New_board@5 ), Rook_castling_origin_square = case To@1 of {position, g, one} -> {position, h, one}; {position, g, eight} -> {position, h, eight}; {position, c, one} -> {position, a, one}; {position, c, eight} -> {position, a, eight}; _ -> (erlang:error(#{gleam_error => panic, message => <<"panic expression evaluated"/utf8>>, module => <<"game"/utf8>>, function => <<"undo_move"/utf8>>, line => 4604}))( <<"Invalid castle move"/utf8>> ) end, New_game_state@6 = erlang:setelement( 2, New_game_state@5, board:set_piece_at_position( erlang:element(2, New_game_state@5), Rook_castling_origin_square, {piece, New_turn@1, rook} ) ), New_ply@1 = erlang:element(6, Game) - 1, New_white_kingside_castle@1 = case erlang:element( 7, Game ) of yes -> yes; {no, Ply@4} -> case Ply@4 =:= erlang:element(6, Game) of true -> yes; false -> {no, Ply@4} end end, New_white_queenside_castle@1 = case erlang:element( 8, Game ) of yes -> yes; {no, Ply@5} -> case Ply@5 =:= erlang:element(6, Game) of true -> yes; false -> {no, Ply@5} end end, New_black_kingside_castle@1 = case erlang:element( 9, Game ) of yes -> yes; {no, Ply@6} -> case Ply@6 =:= erlang:element(6, Game) of true -> yes; false -> {no, Ply@6} end end, New_black_queenside_castle@1 = case erlang:element( 10, Game ) of yes -> yes; {no, Ply@7} -> case Ply@7 =:= erlang:element(6, Game) of true -> yes; false -> {no, Ply@7} end end, New_history@1 = Rest, New_en_passant@1 = case Rest of [] -> none; [Move@2] -> case Move@2 of {normal, {position, _, two}, {position, File@2, four}, none, none} when erlang:element(3, Game) =:= white -> Moving_piece@4 = case board:get_piece_at_position( erlang:element( 2, New_game_state@6 ), {position, File@2, four} ) of {some, Piece@4} -> Piece@4; none -> (erlang:error( #{gleam_error => panic, message => <<"panic expression evaluated"/utf8>>, module => <<"game"/utf8>>, function => <<"undo_move"/utf8>>, line => 4682} ))(<<"Invalid move"/utf8>>) end, case Moving_piece@4 of {piece, _, pawn} -> {some, {position, File@2, three}}; _ -> none end; {normal, {position, _, seven}, {position, File@3, five}, none, none} when erlang:element(3, Game) =:= black -> Moving_piece@5 = case board:get_piece_at_position( erlang:element( 2, New_game_state@6 ), {position, File@3, five} ) of {some, Piece@5} -> Piece@5; none -> (erlang:error( #{gleam_error => panic, message => <<"panic expression evaluated"/utf8>>, module => <<"game"/utf8>>, function => <<"undo_move"/utf8>>, line => 4704} ))(<<"Invalid move"/utf8>>) end, case Moving_piece@5 of {piece, _, pawn} -> {some, {position, File@3, six}}; _ -> none end; _ -> none end; [Move@2 | _] -> case Move@2 of {normal, {position, _, two}, {position, File@2, four}, none, none} when erlang:element(3, Game) =:= white -> Moving_piece@4 = case board:get_piece_at_position( erlang:element( 2, New_game_state@6 ), {position, File@2, four} ) of {some, Piece@4} -> Piece@4; none -> (erlang:error( #{gleam_error => panic, message => <<"panic expression evaluated"/utf8>>, module => <<"game"/utf8>>, function => <<"undo_move"/utf8>>, line => 4682} ))(<<"Invalid move"/utf8>>) end, case Moving_piece@4 of {piece, _, pawn} -> {some, {position, File@2, three}}; _ -> none end; {normal, {position, _, seven}, {position, File@3, five}, none, none} when erlang:element(3, Game) =:= black -> Moving_piece@5 = case board:get_piece_at_position( erlang:element( 2, New_game_state@6 ), {position, File@3, five} ) of {some, Piece@5} -> Piece@5; none -> (erlang:error( #{gleam_error => panic, message => <<"panic expression evaluated"/utf8>>, module => <<"game"/utf8>>, function => <<"undo_move"/utf8>>, line => 4704} ))(<<"Invalid move"/utf8>>) end, case Moving_piece@5 of {piece, _, pawn} -> {some, {position, File@3, six}}; _ -> none end; _ -> none end end, New_status@1 = case erlang:element(5, Game) of none -> none; {some, {in_progress, Fifty_move_rule@1, Threefold_repetition_rule@1}} -> case Fifty_move_rule@1 of 0 -> {some, {in_progress, 0, Threefold_repetition_rule@1}}; _ -> {some, {in_progress, Fifty_move_rule@1 - 1, Threefold_repetition_rule@1}} end; {some, _} -> (erlang:error(#{gleam_error => panic, message => <<"panic expression evaluated"/utf8>>, module => <<"game"/utf8>>, function => <<"undo_move"/utf8>>, line => 4730}))( <<"Trying to undo a move in a finished game"/utf8>> ) end, New_game_state@7 = erlang:setelement( 11, erlang:setelement( 10, erlang:setelement( 9, erlang:setelement( 8, erlang:setelement( 7, erlang:setelement( 5, erlang:setelement( 6, erlang:setelement( 4, erlang:setelement( 3, New_game_state@6, New_turn@1 ), New_history@1 ), New_ply@1 ), New_status@1 ), New_white_kingside_castle@1 ), New_white_queenside_castle@1 ), New_black_kingside_castle@1 ), New_black_queenside_castle@1 ), New_en_passant@1 ), New_game_state@7; {en_passant, From@2, To@2} -> _assert_subject@3 = board:get_piece_at_position( erlang:element(2, Game), To@2 ), {some, Moving_piece@6} = case _assert_subject@3 of {some, _} -> _assert_subject@3; _assert_fail@3 -> erlang:error(#{gleam_error => let_assert, message => <<"Assertion pattern match failed"/utf8>>, value => _assert_fail@3, module => <<"game"/utf8>>, function => <<"undo_move"/utf8>>, line => 4751}) end, _assert_subject@4 = board:remove_piece_at_position( erlang:element(2, Game), To@2 ), {some, New_board@6} = case _assert_subject@4 of {some, _} -> _assert_subject@4; _assert_fail@4 -> erlang:error(#{gleam_error => let_assert, message => <<"Assertion pattern match failed"/utf8>>, value => _assert_fail@4, module => <<"game"/utf8>>, function => <<"undo_move"/utf8>>, line => 4754}) end, New_game_state@8 = erlang:setelement( 2, Game, New_board@6 ), New_game_state@9 = erlang:setelement( 2, New_game_state@8, board:set_piece_at_position( erlang:element(2, New_game_state@8), From@2, Moving_piece@6 ) ), New_game_state@10 = case erlang:element(3, Game) of black -> erlang:setelement( 2, New_game_state@9, board:set_piece_at_position( erlang:element(2, New_game_state@9), {position, erlang:element(2, To@2), four}, {piece, white, pawn} ) ); white -> erlang:setelement( 2, New_game_state@9, board:set_piece_at_position( erlang:element(2, New_game_state@9), {position, erlang:element(2, To@2), five}, {piece, black, pawn} ) ) end, New_ply@2 = erlang:element(6, Game) - 1, New_white_kingside_castle@2 = case erlang:element( 7, Game ) of yes -> yes; {no, Ply@8} -> case Ply@8 =:= erlang:element(6, Game) of true -> yes; false -> {no, Ply@8} end end, New_white_queenside_castle@2 = case erlang:element( 8, Game ) of yes -> yes; {no, Ply@9} -> case Ply@9 =:= erlang:element(6, Game) of true -> yes; false -> {no, Ply@9} end end, New_black_kingside_castle@2 = case erlang:element( 9, Game ) of yes -> yes; {no, Ply@10} -> case Ply@10 =:= erlang:element(6, Game) of true -> yes; false -> {no, Ply@10} end end, New_black_queenside_castle@2 = case erlang:element( 10, Game ) of yes -> yes; {no, Ply@11} -> case Ply@11 =:= erlang:element(6, Game) of true -> yes; false -> {no, Ply@11} end end, New_turn@2 = (case erlang:element(3, Game) of white -> black; black -> white end), New_history@2 = Rest, New_en_passant@2 = To@2, New_status@2 = case erlang:element(5, Game) of none -> none; {some, {in_progress, Fifty_move_rule@2, Threefold_repetition_rule@2}} -> case Fifty_move_rule@2 of 0 -> {some, {in_progress, 0, Threefold_repetition_rule@2}}; _ -> {some, {in_progress, Fifty_move_rule@2 - 1, Threefold_repetition_rule@2}} end; {some, _} -> (erlang:error(#{gleam_error => panic, message => <<"panic expression evaluated"/utf8>>, module => <<"game"/utf8>>, function => <<"undo_move"/utf8>>, line => 4859}))( <<"Trying to undo a move in a finished game"/utf8>> ) end, New_game_state@11 = erlang:setelement( 11, erlang:setelement( 10, erlang:setelement( 9, erlang:setelement( 8, erlang:setelement( 7, erlang:setelement( 5, erlang:setelement( 6, erlang:setelement( 4, erlang:setelement( 3, New_game_state@10, New_turn@2 ), New_history@2 ), New_ply@2 ), New_status@2 ), New_white_kingside_castle@2 ), New_white_queenside_castle@2 ), New_black_kingside_castle@2 ), New_black_queenside_castle@2 ), {some, New_en_passant@2} ), New_game_state@11 end end; none -> case erlang:element(4, Game) of [] -> Game; [Move | Rest] -> case Move of {normal, From, To, Captured_piece, Promo_piece} -> Moving_piece = case board:get_piece_at_position( erlang:element(2, Game), To ) of none -> (erlang:error(#{gleam_error => panic, message => <<"panic expression evaluated"/utf8>>, module => <<"game"/utf8>>, function => <<"undo_move"/utf8>>, line => 4348}))( <<"Invalid move"/utf8>> ); {some, Piece} -> Piece end, Moving_piece@1 = case Promo_piece of none -> Moving_piece; {some, _} -> {piece, erlang:element(2, Moving_piece), pawn} end, New_turn = (case erlang:element(3, Game) of white -> black; black -> white end), New_game_state = case Captured_piece of none -> _assert_subject = board:remove_piece_at_position( erlang:element(2, Game), To ), {some, New_board} = 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 => <<"game"/utf8>>, function => <<"undo_move"/utf8>>, line => 4367} ) end, erlang:setelement(2, Game, New_board); {some, Piece@1} -> _assert_subject@1 = board:remove_piece_at_position( erlang:element(2, Game), To ), {some, New_board@1} = case _assert_subject@1 of {some, _} -> _assert_subject@1; _assert_fail@1 -> erlang:error( #{gleam_error => let_assert, message => <<"Assertion pattern match failed"/utf8>>, value => _assert_fail@1, module => <<"game"/utf8>>, function => <<"undo_move"/utf8>>, line => 4373} ) end, New_board@2 = board:set_piece_at_position( New_board@1, To, Piece@1 ), erlang:setelement(2, Game, New_board@2) end, New_board@3 = board:set_piece_at_position( erlang:element(2, New_game_state), From, Moving_piece@1 ), New_game_state@1 = erlang:setelement( 2, New_game_state, New_board@3 ), New_ply = erlang:element(6, Game) - 1, New_white_kingside_castle = case erlang:element( 7, Game ) of yes -> yes; {no, Ply} -> case Ply =:= erlang:element(6, Game) of true -> yes; false -> {no, Ply} end end, New_white_queenside_castle = case erlang:element( 8, Game ) of yes -> yes; {no, Ply@1} -> case Ply@1 =:= erlang:element(6, Game) of true -> yes; false -> {no, Ply@1} end end, New_black_kingside_castle = case erlang:element( 9, Game ) of yes -> yes; {no, Ply@2} -> case Ply@2 =:= erlang:element(6, Game) of true -> yes; false -> {no, Ply@2} end end, New_black_queenside_castle = case erlang:element( 10, Game ) of yes -> yes; {no, Ply@3} -> case Ply@3 =:= erlang:element(6, Game) of true -> yes; false -> {no, Ply@3} end end, New_history = Rest, New_en_passant = case Rest of [] -> none; [Move@1] -> case Move@1 of {normal, {position, _, two}, {position, File, four}, none, none} when erlang:element(3, Game) =:= white -> Moving_piece@2 = case board:get_piece_at_position( erlang:element( 2, New_game_state@1 ), {position, File, four} ) of {some, Piece@2} -> Piece@2; none -> (erlang:error( #{gleam_error => panic, message => <<"panic expression evaluated"/utf8>>, module => <<"game"/utf8>>, function => <<"undo_move"/utf8>>, line => 4457} ))(<<"Invalid move"/utf8>>) end, case Moving_piece@2 of {piece, _, pawn} -> {some, {position, File, three}}; _ -> none end; {normal, {position, _, seven}, {position, File@1, five}, none, none} when erlang:element(3, Game) =:= black -> Moving_piece@3 = case board:get_piece_at_position( erlang:element( 2, New_game_state@1 ), {position, File@1, five} ) of {some, Piece@3} -> Piece@3; none -> (erlang:error( #{gleam_error => panic, message => <<"panic expression evaluated"/utf8>>, module => <<"game"/utf8>>, function => <<"undo_move"/utf8>>, line => 4479} ))(<<"Invalid move"/utf8>>) end, case Moving_piece@3 of {piece, _, pawn} -> {some, {position, File@1, six}}; _ -> none end; _ -> none end; [Move@1 | _] -> case Move@1 of {normal, {position, _, two}, {position, File, four}, none, none} when erlang:element(3, Game) =:= white -> Moving_piece@2 = case board:get_piece_at_position( erlang:element( 2, New_game_state@1 ), {position, File, four} ) of {some, Piece@2} -> Piece@2; none -> (erlang:error( #{gleam_error => panic, message => <<"panic expression evaluated"/utf8>>, module => <<"game"/utf8>>, function => <<"undo_move"/utf8>>, line => 4457} ))(<<"Invalid move"/utf8>>) end, case Moving_piece@2 of {piece, _, pawn} -> {some, {position, File, three}}; _ -> none end; {normal, {position, _, seven}, {position, File@1, five}, none, none} when erlang:element(3, Game) =:= black -> Moving_piece@3 = case board:get_piece_at_position( erlang:element( 2, New_game_state@1 ), {position, File@1, five} ) of {some, Piece@3} -> Piece@3; none -> (erlang:error( #{gleam_error => panic, message => <<"panic expression evaluated"/utf8>>, module => <<"game"/utf8>>, function => <<"undo_move"/utf8>>, line => 4479} ))(<<"Invalid move"/utf8>>) end, case Moving_piece@3 of {piece, _, pawn} -> {some, {position, File@1, six}}; _ -> none end; _ -> none end end, New_status = case erlang:element(5, Game) of none -> none; {some, {in_progress, Fifty_move_rule, Threefold_repetition_rule}} -> New_fifty_move_rule = case Fifty_move_rule of 0 -> 0; _ -> Fifty_move_rule - 1 end, Threefold_position = {three_fold_position, erlang:element(3, Game), erlang:element(2, Game), erlang:element(11, Game), erlang:element(7, Game), erlang:element(8, Game), erlang:element(9, Game), erlang:element(10, Game)}, New_threefold_repetition_rule = case gleam@map:get( Threefold_repetition_rule, Threefold_position ) of {error, nil} -> Threefold_repetition_rule; {ok, 0} -> gleam@map:delete( Threefold_repetition_rule, Threefold_position ); {ok, 1} -> gleam@map:delete( Threefold_repetition_rule, Threefold_position ); {ok, Count} -> gleam@map:insert( Threefold_repetition_rule, Threefold_position, Count - 1 ) end, {some, {in_progress, New_fifty_move_rule, New_threefold_repetition_rule}}; {some, _} -> (erlang:error(#{gleam_error => panic, message => <<"panic expression evaluated"/utf8>>, module => <<"game"/utf8>>, function => <<"undo_move"/utf8>>, line => 4531}))( <<"trying to undo a move in a finished game is not possible"/utf8>> ) end, New_game_state@2 = erlang:setelement( 11, erlang:setelement( 10, erlang:setelement( 9, erlang:setelement( 8, erlang:setelement( 7, erlang:setelement( 5, erlang:setelement( 6, erlang:setelement( 4, erlang:setelement( 3, New_game_state@1, New_turn ), New_history ), New_ply ), New_status ), New_white_kingside_castle ), New_white_queenside_castle ), New_black_kingside_castle ), New_black_queenside_castle ), New_en_passant ), New_game_state@2; {castle, From@1, To@1} -> New_turn@1 = (case erlang:element(3, Game) of white -> black; black -> white end), New_game_state@3 = erlang:setelement( 2, Game, board:set_piece_at_position( erlang:element(2, Game), From@1, {piece, New_turn@1, king} ) ), Rook_castling_target_square = case To@1 of {position, g, one} -> {position, f, one}; {position, g, eight} -> {position, f, eight}; {position, c, one} -> {position, d, one}; {position, c, eight} -> {position, d, eight}; _ -> (erlang:error(#{gleam_error => panic, message => <<"panic expression evaluated"/utf8>>, module => <<"game"/utf8>>, function => <<"undo_move"/utf8>>, line => 4577}))( <<"Invalid castle move"/utf8>> ) end, New_board@4 = case board:remove_piece_at_position( erlang:element(2, New_game_state@3), Rook_castling_target_square ) of {some, Board} -> Board; none -> (erlang:error(#{gleam_error => panic, message => <<"panic expression evaluated"/utf8>>, module => <<"game"/utf8>>, function => <<"undo_move"/utf8>>, line => 4587}))( <<"Invalid move"/utf8>> ) end, New_game_state@4 = erlang:setelement( 2, New_game_state@3, New_board@4 ), _assert_subject@2 = board:remove_piece_at_position( erlang:element(2, New_game_state@4), To@1 ), {some, New_board@5} = case _assert_subject@2 of {some, _} -> _assert_subject@2; _assert_fail@2 -> erlang:error(#{gleam_error => let_assert, message => <<"Assertion pattern match failed"/utf8>>, value => _assert_fail@2, module => <<"game"/utf8>>, function => <<"undo_move"/utf8>>, line => 4591}) end, New_game_state@5 = erlang:setelement( 2, New_game_state@4, New_board@5 ), Rook_castling_origin_square = case To@1 of {position, g, one} -> {position, h, one}; {position, g, eight} -> {position, h, eight}; {position, c, one} -> {position, a, one}; {position, c, eight} -> {position, a, eight}; _ -> (erlang:error(#{gleam_error => panic, message => <<"panic expression evaluated"/utf8>>, module => <<"game"/utf8>>, function => <<"undo_move"/utf8>>, line => 4604}))( <<"Invalid castle move"/utf8>> ) end, New_game_state@6 = erlang:setelement( 2, New_game_state@5, board:set_piece_at_position( erlang:element(2, New_game_state@5), Rook_castling_origin_square, {piece, New_turn@1, rook} ) ), New_ply@1 = erlang:element(6, Game) - 1, New_white_kingside_castle@1 = case erlang:element( 7, Game ) of yes -> yes; {no, Ply@4} -> case Ply@4 =:= erlang:element(6, Game) of true -> yes; false -> {no, Ply@4} end end, New_white_queenside_castle@1 = case erlang:element( 8, Game ) of yes -> yes; {no, Ply@5} -> case Ply@5 =:= erlang:element(6, Game) of true -> yes; false -> {no, Ply@5} end end, New_black_kingside_castle@1 = case erlang:element( 9, Game ) of yes -> yes; {no, Ply@6} -> case Ply@6 =:= erlang:element(6, Game) of true -> yes; false -> {no, Ply@6} end end, New_black_queenside_castle@1 = case erlang:element( 10, Game ) of yes -> yes; {no, Ply@7} -> case Ply@7 =:= erlang:element(6, Game) of true -> yes; false -> {no, Ply@7} end end, New_history@1 = Rest, New_en_passant@1 = case Rest of [] -> none; [Move@2] -> case Move@2 of {normal, {position, _, two}, {position, File@2, four}, none, none} when erlang:element(3, Game) =:= white -> Moving_piece@4 = case board:get_piece_at_position( erlang:element( 2, New_game_state@6 ), {position, File@2, four} ) of {some, Piece@4} -> Piece@4; none -> (erlang:error( #{gleam_error => panic, message => <<"panic expression evaluated"/utf8>>, module => <<"game"/utf8>>, function => <<"undo_move"/utf8>>, line => 4682} ))(<<"Invalid move"/utf8>>) end, case Moving_piece@4 of {piece, _, pawn} -> {some, {position, File@2, three}}; _ -> none end; {normal, {position, _, seven}, {position, File@3, five}, none, none} when erlang:element(3, Game) =:= black -> Moving_piece@5 = case board:get_piece_at_position( erlang:element( 2, New_game_state@6 ), {position, File@3, five} ) of {some, Piece@5} -> Piece@5; none -> (erlang:error( #{gleam_error => panic, message => <<"panic expression evaluated"/utf8>>, module => <<"game"/utf8>>, function => <<"undo_move"/utf8>>, line => 4704} ))(<<"Invalid move"/utf8>>) end, case Moving_piece@5 of {piece, _, pawn} -> {some, {position, File@3, six}}; _ -> none end; _ -> none end; [Move@2 | _] -> case Move@2 of {normal, {position, _, two}, {position, File@2, four}, none, none} when erlang:element(3, Game) =:= white -> Moving_piece@4 = case board:get_piece_at_position( erlang:element( 2, New_game_state@6 ), {position, File@2, four} ) of {some, Piece@4} -> Piece@4; none -> (erlang:error( #{gleam_error => panic, message => <<"panic expression evaluated"/utf8>>, module => <<"game"/utf8>>, function => <<"undo_move"/utf8>>, line => 4682} ))(<<"Invalid move"/utf8>>) end, case Moving_piece@4 of {piece, _, pawn} -> {some, {position, File@2, three}}; _ -> none end; {normal, {position, _, seven}, {position, File@3, five}, none, none} when erlang:element(3, Game) =:= black -> Moving_piece@5 = case board:get_piece_at_position( erlang:element( 2, New_game_state@6 ), {position, File@3, five} ) of {some, Piece@5} -> Piece@5; none -> (erlang:error( #{gleam_error => panic, message => <<"panic expression evaluated"/utf8>>, module => <<"game"/utf8>>, function => <<"undo_move"/utf8>>, line => 4704} ))(<<"Invalid move"/utf8>>) end, case Moving_piece@5 of {piece, _, pawn} -> {some, {position, File@3, six}}; _ -> none end; _ -> none end end, New_status@1 = case erlang:element(5, Game) of none -> none; {some, {in_progress, Fifty_move_rule@1, Threefold_repetition_rule@1}} -> case Fifty_move_rule@1 of 0 -> {some, {in_progress, 0, Threefold_repetition_rule@1}}; _ -> {some, {in_progress, Fifty_move_rule@1 - 1, Threefold_repetition_rule@1}} end; {some, _} -> (erlang:error(#{gleam_error => panic, message => <<"panic expression evaluated"/utf8>>, module => <<"game"/utf8>>, function => <<"undo_move"/utf8>>, line => 4730}))( <<"Trying to undo a move in a finished game"/utf8>> ) end, New_game_state@7 = erlang:setelement( 11, erlang:setelement( 10, erlang:setelement( 9, erlang:setelement( 8, erlang:setelement( 7, erlang:setelement( 5, erlang:setelement( 6, erlang:setelement( 4, erlang:setelement( 3, New_game_state@6, New_turn@1 ), New_history@1 ), New_ply@1 ), New_status@1 ), New_white_kingside_castle@1 ), New_white_queenside_castle@1 ), New_black_kingside_castle@1 ), New_black_queenside_castle@1 ), New_en_passant@1 ), New_game_state@7; {en_passant, From@2, To@2} -> _assert_subject@3 = board:get_piece_at_position( erlang:element(2, Game), To@2 ), {some, Moving_piece@6} = case _assert_subject@3 of {some, _} -> _assert_subject@3; _assert_fail@3 -> erlang:error(#{gleam_error => let_assert, message => <<"Assertion pattern match failed"/utf8>>, value => _assert_fail@3, module => <<"game"/utf8>>, function => <<"undo_move"/utf8>>, line => 4751}) end, _assert_subject@4 = board:remove_piece_at_position( erlang:element(2, Game), To@2 ), {some, New_board@6} = case _assert_subject@4 of {some, _} -> _assert_subject@4; _assert_fail@4 -> erlang:error(#{gleam_error => let_assert, message => <<"Assertion pattern match failed"/utf8>>, value => _assert_fail@4, module => <<"game"/utf8>>, function => <<"undo_move"/utf8>>, line => 4754}) end, New_game_state@8 = erlang:setelement( 2, Game, New_board@6 ), New_game_state@9 = erlang:setelement( 2, New_game_state@8, board:set_piece_at_position( erlang:element(2, New_game_state@8), From@2, Moving_piece@6 ) ), New_game_state@10 = case erlang:element(3, Game) of black -> erlang:setelement( 2, New_game_state@9, board:set_piece_at_position( erlang:element(2, New_game_state@9), {position, erlang:element(2, To@2), four}, {piece, white, pawn} ) ); white -> erlang:setelement( 2, New_game_state@9, board:set_piece_at_position( erlang:element(2, New_game_state@9), {position, erlang:element(2, To@2), five}, {piece, black, pawn} ) ) end, New_ply@2 = erlang:element(6, Game) - 1, New_white_kingside_castle@2 = case erlang:element( 7, Game ) of yes -> yes; {no, Ply@8} -> case Ply@8 =:= erlang:element(6, Game) of true -> yes; false -> {no, Ply@8} end end, New_white_queenside_castle@2 = case erlang:element( 8, Game ) of yes -> yes; {no, Ply@9} -> case Ply@9 =:= erlang:element(6, Game) of true -> yes; false -> {no, Ply@9} end end, New_black_kingside_castle@2 = case erlang:element( 9, Game ) of yes -> yes; {no, Ply@10} -> case Ply@10 =:= erlang:element(6, Game) of true -> yes; false -> {no, Ply@10} end end, New_black_queenside_castle@2 = case erlang:element( 10, Game ) of yes -> yes; {no, Ply@11} -> case Ply@11 =:= erlang:element(6, Game) of true -> yes; false -> {no, Ply@11} end end, New_turn@2 = (case erlang:element(3, Game) of white -> black; black -> white end), New_history@2 = Rest, New_en_passant@2 = To@2, New_status@2 = case erlang:element(5, Game) of none -> none; {some, {in_progress, Fifty_move_rule@2, Threefold_repetition_rule@2}} -> case Fifty_move_rule@2 of 0 -> {some, {in_progress, 0, Threefold_repetition_rule@2}}; _ -> {some, {in_progress, Fifty_move_rule@2 - 1, Threefold_repetition_rule@2}} end; {some, _} -> (erlang:error(#{gleam_error => panic, message => <<"panic expression evaluated"/utf8>>, module => <<"game"/utf8>>, function => <<"undo_move"/utf8>>, line => 4859}))( <<"Trying to undo a move in a finished game"/utf8>> ) end, New_game_state@11 = erlang:setelement( 11, erlang:setelement( 10, erlang:setelement( 9, erlang:setelement( 8, erlang:setelement( 7, erlang:setelement( 5, erlang:setelement( 6, erlang:setelement( 4, erlang:setelement( 3, New_game_state@10, New_turn@2 ), New_history@2 ), New_ply@2 ), New_status@2 ), New_white_kingside_castle@2 ), New_white_queenside_castle@2 ), New_black_kingside_castle@2 ), New_black_queenside_castle@2 ), {some, New_en_passant@2} ), New_game_state@11 end end; {some, _} -> Game end. -spec all_legal_moves(game()) -> list(move:move()). all_legal_moves(Game) -> case erlang:element(5, Game) of {some, {in_progress, _, _}} -> Legal_moves = begin _pipe = generate_pseudo_legal_move_list( Game, erlang:element(3, Game) ), gleam@list:filter( _pipe, fun(Move) -> is_move_legal(Game, Move) end ) end, Legal_moves; none -> Legal_moves = begin _pipe = generate_pseudo_legal_move_list( Game, erlang:element(3, Game) ), gleam@list:filter( _pipe, fun(Move) -> is_move_legal(Game, Move) end ) end, Legal_moves; {some, _} -> [] end. -spec has_moves(game()) -> boolean(). has_moves(Game) -> Move_list = all_legal_moves(Game), not gleam@list:is_empty(Move_list). -spec apply_move(game(), move:move()) -> game(). apply_move(Game, Move) -> case erlang:element(5, Game) of {some, {in_progress, _, _}} -> Legal_moves = begin _pipe = generate_pseudo_legal_move_list( Game, erlang:element(3, Game) ), gleam@list:filter( _pipe, fun(Move@1) -> is_move_legal(Game, Move@1) end ) end, New_game_state@1 = case gleam@list:contains(Legal_moves, Move) of true -> New_game_state = apply_pseudo_legal_move(Game, Move), New_game_state; false -> Game end, New_game_state@2 = case [is_king_in_check( New_game_state@1, erlang:element(3, New_game_state@1) ), not has_moves(New_game_state@1)] of [true, true] -> Winner = case erlang:element(3, New_game_state@1) of white -> black; black -> white end, erlang:setelement( 5, New_game_state@1, {some, {win, Winner, <<"Checkmate"/utf8>>}} ); [true, false] -> New_game_state@1; [false, false] -> New_game_state@1; [false, true] -> gleam@io:println(<<"nothing"/utf8>>), erlang:setelement( 5, New_game_state@1, {some, {draw, stalemate}} ) end, New_game_state@2; none -> Legal_moves = begin _pipe = generate_pseudo_legal_move_list( Game, erlang:element(3, Game) ), gleam@list:filter( _pipe, fun(Move@1) -> is_move_legal(Game, Move@1) end ) end, New_game_state@1 = case gleam@list:contains(Legal_moves, Move) of true -> New_game_state = apply_pseudo_legal_move(Game, Move), New_game_state; false -> Game end, New_game_state@2 = case [is_king_in_check( New_game_state@1, erlang:element(3, New_game_state@1) ), not has_moves(New_game_state@1)] of [true, true] -> Winner = case erlang:element(3, New_game_state@1) of white -> black; black -> white end, erlang:setelement( 5, New_game_state@1, {some, {win, Winner, <<"Checkmate"/utf8>>}} ); [true, false] -> New_game_state@1; [false, false] -> New_game_state@1; [false, true] -> gleam@io:println(<<"nothing"/utf8>>), erlang:setelement( 5, New_game_state@1, {some, {draw, stalemate}} ) end, New_game_state@2; {some, _} -> Game end. -spec apply_move_san_string(game(), binary()) -> {ok, game()} | {error, binary()}. apply_move_san_string(Game, Move) -> Move_san = move_san:from_string(Move), case Move_san of {ok, Move_san@1} -> case Move_san@1 of {normal, _, To, Moving_piece, _, Promotion, _} -> Promotion@2 = case Promotion of {some, Promotion@1} -> {some, {piece, erlang:element(3, Game), Promotion@1}}; none -> none end, Move@5 = begin Potential_moves = gleam@list:filter( all_legal_moves(Game), fun(Move@1) -> case Move@1 of {normal, _, To_legal, _, Promo_legal} when (To_legal =:= To) andalso (Promo_legal =:= Promotion@2) -> true; _ -> false end end ), case Potential_moves of [] -> {error, <<"No potential moves found"/utf8>>}; [Move@2] -> case Move@2 of {normal, _, _, _, _} -> {ok, Move@2}; _ -> (erlang:error(#{gleam_error => panic, message => <<"panic expression evaluated"/utf8>>, module => <<"game"/utf8>>, function => <<"apply_move_san_string"/utf8>>, line => 4084}))( <<"This panic should be unreachable"/utf8>> ) end; Move_list -> Maybe_move = gleam@list:filter( Move_list, fun(Move@3) -> case Move@3 of {normal, From, _, _, _} -> _assert_subject = board:get_piece_at_position( erlang:element(2, Game), From ), {some, Piece} = 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 => <<"game"/utf8>>, function => <<"apply_move_san_string"/utf8>>, line => 4099} ) end, erlang:element(3, Piece) =:= Moving_piece; _ -> (erlang:error( #{gleam_error => panic, message => <<"panic expression evaluated"/utf8>>, module => <<"game"/utf8>>, function => <<"apply_move_san_string"/utf8>>, line => 4103} ))( <<"This panic should be unreachable"/utf8>> ) end end ), case Maybe_move of [] -> {error, <<"Move not found"/utf8>>}; [Move@4] -> {ok, Move@4}; _ -> (erlang:error(#{gleam_error => panic, message => <<"panic expression evaluated"/utf8>>, module => <<"game"/utf8>>, function => <<"apply_move_san_string"/utf8>>, line => 4110}))( <<"This panic should be unreachable"/utf8>> ) end end end, case Move@5 of {ok, Move@6} -> New_game_state = apply_move(Game, Move@6), {ok, New_game_state}; {error, Error} -> {error, Error} end; {castle, Side, _} -> Move@7 = case Side of king_side -> case erlang:element(3, Game) of white -> {castle, {position, e, one}, {position, g, one}}; black -> {castle, {position, e, eight}, {position, g, eight}} end; queen_side -> case erlang:element(3, Game) of white -> {castle, {position, e, one}, {position, c, one}}; black -> {castle, {position, e, eight}, {position, c, eight}} end end, {ok, apply_move(Game, Move@7)}; {en_passant, From@1, To@1, _} -> Ep_moves = gleam@list:filter( all_legal_moves(Game), fun(Move@8) -> case Move@8 of {en_passant, _, To_legal@1} when To_legal@1 =:= To@1 -> true; _ -> false end end ), case Ep_moves of [] -> {error, <<"Illegal move"/utf8>>}; [Move@9] -> {ok, apply_move(Game, Move@9)}; [Move_1, Move_2] -> case From@1 of {some, {position_san, {some, File}, _}} when File =:= erlang:element( 2, erlang:element(2, Move_1) ) -> {ok, apply_move(Game, Move_1)}; {some, {position_san, {some, File@1}, _}} when File@1 =:= erlang:element( 2, erlang:element(2, Move_2) ) -> {ok, apply_move(Game, Move_2)}; _ -> {error, <<"Illegal move"/utf8>>} end, {ok, apply_move(Game, Move_1)}; _ -> {error, <<"Illegal move"/utf8>>} end; _ -> (erlang:error(#{gleam_error => panic, message => <<"panic expression evaluated"/utf8>>, module => <<"game"/utf8>>, function => <<"apply_move_san_string"/utf8>>, line => 4208}))( <<"This panic should be unreachable"/utf8>> ) end; {error, _} -> {error, <<"Invalid move"/utf8>>} end. -spec load_pgn(binary()) -> {ok, game()} | {error, binary()}. load_pgn(Pgn) -> Game = new_game(), Pgn@1 = gleam@string:trim(Pgn), Pgn@2 = pgn:remove_tags(Pgn@1), List_of_movetext = pgn:split_movetext(Pgn@2), gleam@list:fold( List_of_movetext, {ok, Game}, fun(Game@1, Movetext) -> Game@7 = case gleam@string:split(Movetext, <<" "/utf8>>) of [White_ply, Black_ply] -> {ok, Game@2} = case Game@1 of {ok, _} -> Game@1; _assert_fail -> erlang:error(#{gleam_error => let_assert, message => <<"Assertion pattern match failed"/utf8>>, value => _assert_fail, module => <<"game"/utf8>>, function => <<"load_pgn"/utf8>>, line => 444}) end, Game@3 = apply_move_san_string(Game@2, White_ply), case Game@3 of {ok, Game@4} -> apply_move_san_string(Game@4, Black_ply); {error, Message} -> {error, Message} end; [White_ply@1] -> {ok, Game@5} = case Game@1 of {ok, _} -> Game@1; _assert_fail@1 -> erlang:error(#{gleam_error => let_assert, message => <<"Assertion pattern match failed"/utf8>>, value => _assert_fail@1, module => <<"game"/utf8>>, function => <<"load_pgn"/utf8>>, line => 454}) end, Game@6 = apply_move_san_string(Game@5, White_ply@1), Game@6; [] -> {error, <<"Invalid PGN"/utf8>>}; _ -> {error, <<"Invalid PGN"/utf8>>} end, Game@7 end ). -spec print_board_from_fen(binary()) -> nil. print_board_from_fen(Fen) -> Parsed_fen = fen:from_string(Fen), Board_map = bitboard_repr_to_map_repr(erlang:element(2, Parsed_fen)), gleam@io:print(<<"\n"/utf8>>), gleam@io:print(<<" +---+---+---+---+---+---+---+---+"/utf8>>), gleam@list:each( [{position, a, eight}, {position, b, eight}, {position, c, eight}, {position, d, eight}, {position, e, eight}, {position, f, eight}, {position, g, eight}, {position, h, eight}, {position, a, seven}, {position, b, seven}, {position, c, seven}, {position, d, seven}, {position, e, seven}, {position, f, seven}, {position, g, seven}, {position, h, seven}, {position, a, six}, {position, b, six}, {position, c, six}, {position, d, six}, {position, e, six}, {position, f, six}, {position, g, six}, {position, h, six}, {position, a, five}, {position, b, five}, {position, c, five}, {position, d, five}, {position, e, five}, {position, f, five}, {position, g, five}, {position, h, five}, {position, a, four}, {position, b, four}, {position, c, four}, {position, d, four}, {position, e, four}, {position, f, four}, {position, g, four}, {position, h, four}, {position, a, three}, {position, b, three}, {position, c, three}, {position, d, three}, {position, e, three}, {position, f, three}, {position, g, three}, {position, h, three}, {position, a, two}, {position, b, two}, {position, c, two}, {position, d, two}, {position, e, two}, {position, f, two}, {position, g, two}, {position, h, two}, {position, a, one}, {position, b, one}, {position, c, one}, {position, d, one}, {position, e, one}, {position, f, one}, {position, g, one}, {position, h, one}], fun(Pos) -> Piece_to_print = gleam@result:unwrap( gleam@map:get(Board_map, Pos), none ), case erlang:element(2, Pos) of a -> gleam@io:print(<<"\n"/utf8>>), gleam@io:print( <<<<" "/utf8, (gleam@int:to_string( position:rank_to_int(erlang:element(3, Pos)) + 1 ))/binary>>/binary, " | "/utf8>> ), gleam@io:print(case Piece_to_print of {some, {piece, white, pawn}} -> <<"♙"/utf8>>; {some, {piece, white, knight}} -> <<"♘"/utf8>>; {some, {piece, white, bishop}} -> <<"♗"/utf8>>; {some, {piece, white, rook}} -> <<"♖"/utf8>>; {some, {piece, white, queen}} -> <<"♕"/utf8>>; {some, {piece, white, king}} -> <<"♔"/utf8>>; {some, {piece, black, pawn}} -> <<"♟"/utf8>>; {some, {piece, black, knight}} -> <<"♞"/utf8>>; {some, {piece, black, bishop}} -> <<"♝"/utf8>>; {some, {piece, black, rook}} -> <<"♜"/utf8>>; {some, {piece, black, queen}} -> <<"♛"/utf8>>; {some, {piece, black, king}} -> <<"♚"/utf8>>; none -> <<" "/utf8>> end), gleam@io:print(<<" | "/utf8>>); h -> gleam@io:print(case Piece_to_print of {some, {piece, white, pawn}} -> <<"♙"/utf8>>; {some, {piece, white, knight}} -> <<"♘"/utf8>>; {some, {piece, white, bishop}} -> <<"♗"/utf8>>; {some, {piece, white, rook}} -> <<"♖"/utf8>>; {some, {piece, white, queen}} -> <<"♕"/utf8>>; {some, {piece, white, king}} -> <<"♔"/utf8>>; {some, {piece, black, pawn}} -> <<"♟"/utf8>>; {some, {piece, black, knight}} -> <<"♞"/utf8>>; {some, {piece, black, bishop}} -> <<"♝"/utf8>>; {some, {piece, black, rook}} -> <<"♜"/utf8>>; {some, {piece, black, queen}} -> <<"♛"/utf8>>; {some, {piece, black, king}} -> <<"♚"/utf8>>; none -> <<" "/utf8>> end), gleam@io:print(<<" | "/utf8>>), gleam@io:print(<<"\n"/utf8>>), gleam@io:print( <<" +---+---+---+---+---+---+---+---+"/utf8>> ); _ -> gleam@io:print(case Piece_to_print of {some, {piece, white, pawn}} -> <<"♙"/utf8>>; {some, {piece, white, knight}} -> <<"♘"/utf8>>; {some, {piece, white, bishop}} -> <<"♗"/utf8>>; {some, {piece, white, rook}} -> <<"♖"/utf8>>; {some, {piece, white, queen}} -> <<"♕"/utf8>>; {some, {piece, white, king}} -> <<"♔"/utf8>>; {some, {piece, black, pawn}} -> <<"♟"/utf8>>; {some, {piece, black, knight}} -> <<"♞"/utf8>>; {some, {piece, black, bishop}} -> <<"♝"/utf8>>; {some, {piece, black, rook}} -> <<"♜"/utf8>>; {some, {piece, black, queen}} -> <<"♛"/utf8>>; {some, {piece, black, king}} -> <<"♚"/utf8>>; none -> <<" "/utf8>> end), gleam@io:print(<<" | "/utf8>>) end end ), gleam@io:print(<<"\n"/utf8>>), gleam@io:print(<<" a b c d e f g h\n"/utf8>>).