Current section

Files

Jump to
gchess src game.erl
Raw

src/game.erl

-module(game).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch]).
-export([to_fen/1, new_game_without_status/0, new_game/0, from_fen_string/1, apply_move_raw/2, disable_status/1, undo_move/1, print_board/1, print_board_from_fen/1, all_legal_moves/1, apply_move/2, apply_move_san_string/2, load_pgn/1, apply_move_uci/2]).
-export_type([game/0]).
-type game() :: {game,
board:board_bb(),
color:color(),
list(move:move_with_capture()),
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 = 2#0000000000000000000000000000000000000000000000000000000000001000,
White_queen_bitboard = 2#0000000000000000000000000000000000000000000000000000000000010000,
White_rook_bitboard = 2#0000000000000000000000000000000000000000000000000000000010000001,
White_bishop_bitboard = 2#0000000000000000000000000000000000000000000000000000000000100100,
White_knight_bitboard = 2#0000000000000000000000000000000000000000000000000000000001000010,
White_pawns_bitboard = 2#0000000000000000000000000000000000000000000000001111111100000000,
Black_king_bitboard = 2#0000100000000000000000000000000000000000000000000000000000000000,
Black_queen_bitboard = 2#0001000000000000000000000000000000000000000000000000000000000000,
Black_rook_bitboard = 2#1000000100000000000000000000000000000000000000000000000000000000,
Black_bishop_bitboard = 2#0010010000000000000000000000000000000000000000000000000000000000,
Black_knight_bitboard = 2#0100001000000000000000000000000000000000000000000000000000000000,
Black_pawns_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 = 2#0000000000000000000000000000000000000000000000000000000000010000,
White_queen_bitboard = 2#0000000000000000000000000000000000000000000000000000000000001000,
White_rook_bitboard = 2#0000000000000000000000000000000000000000000000000000000010000001,
White_bishop_bitboard = 2#0000000000000000000000000000000000000000000000000000000000100100,
White_knight_bitboard = 2#0000000000000000000000000000000000000000000000000000000001000010,
White_pawns_bitboard = 2#0000000000000000000000000000000000000000000000001111111100000000,
Black_king_bitboard = 2#0001000000000000000000000000000000000000000000000000000000000000,
Black_queen_bitboard = 2#0000100000000000000000000000000000000000000000000000000000000000,
Black_rook_bitboard = 2#1000000100000000000000000000000000000000000000000000000000000000,
Black_bishop_bitboard = 2#0010010000000000000000000000000000000000000000000000000000000000,
Black_knight_bitboard = 2#0100001000000000000000000000000000000000000000000000000000000000,
Black_pawns_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@dict:new()},
Ply = 0,
{game, Board, Turn, History, {some, Status}, Ply, yes, yes, yes, yes, none}.
-spec from_fen_string(binary()) -> {ok, game()} | {error, any()}.
from_fen_string(Fen_string) ->
Fen = fen:from_string(Fen_string),
Status = {in_progress, erlang:element(6, Fen), gleam@dict: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,
{ok,
{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 look_up_knight_target_bb(position:position()) -> integer().
look_up_knight_target_bb(Origin_square) ->
case Origin_square of
{position, a, one} ->
2#0000000000000000000000000000000000000000000000100000010000000000;
{position, a, two} ->
2#0000000000000000000000000000000000000010000001000000000000000100;
{position, a, three} ->
2#0000000000000000000000000000001000000100000000000000010000000010;
{position, a, four} ->
2#0000000000000000000000100000010000000000000001000000001000000000;
{position, a, five} ->
2#0000000000000010000001000000000000000100000000100000000000000000;
{position, a, six} ->
2#0000001000000100000000000000010000000010000000000000000000000000;
{position, a, seven} ->
2#0000010000000000000001000000001000000000000000000000000000000000;
{position, a, eight} ->
2#0000000000000100000000100000000000000000000000000000000000000000;
{position, b, one} ->
2#0000000000000000000000000000000000000000000001010000100000000000;
{position, b, two} ->
2#0000000000000000000000000000000000000101000010000000000000001000;
{position, b, three} ->
2#0000000000000000000000000000010100001000000000000000100000000101;
{position, b, four} ->
2#0000000000000000000001010000100000000000000010000000010100000000;
{position, b, five} ->
2#0000000000000101000010000000000000001000000001010000000000000000;
{position, b, six} ->
2#0000010100001000000000000000100000000101000000000000000000000000;
{position, b, seven} ->
2#0000100000000000000010000000010100000000000000000000000000000000;
{position, b, eight} ->
2#0000000000001000000001010000000000000000000000000000000000000000;
{position, c, one} ->
2#0000000000000000000000000000000000000000000010100001000100000000;
{position, c, two} ->
2#0000000000000000000000000000000000001010000100010000000000010001;
{position, c, three} ->
2#0000000000000000000000000000101000010001000000000001000100001010;
{position, c, four} ->
2#0000000000000000000010100001000100000000000100010000101000000000;
{position, c, five} ->
2#0000000000001010000100010000000000010001000010100000000000000000;
{position, c, six} ->
2#0000101000010001000000000001000100001010000000000000000000000000;
{position, c, seven} ->
2#0001000100000000000100010000101000000000000000000000000000000000;
{position, c, eight} ->
2#0000000000010001000010100000000000000000000000000000000000000000;
{position, d, one} ->
2#0000000000000000000000000000000000000000000101000010001000000000;
{position, d, two} ->
2#0000000000000000000000000000000000010100001000100000000000100010;
{position, d, three} ->
2#0000000000000000000000000001010000100010000000000010001000010100;
{position, d, four} ->
2#0000000000000000000101000010001000000000001000100001010000000000;
{position, d, five} ->
2#0000000000010100001000100000000000100010000101000000000000000000;
{position, d, six} ->
2#0001010000100010000000000010001000010100000000000000000000000000;
{position, d, seven} ->
2#0010001000000000001000100001010000000000000000000000000000000000;
{position, d, eight} ->
2#0000000000100010000101000000000000000000000000000000000000000000;
{position, e, one} ->
2#0000000000000000000000000000000000000000001010000100010000000000;
{position, e, two} ->
2#0000000000000000000000000000000000101000010001000000000001000100;
{position, e, three} ->
2#0000000000000000000000000010100001000100000000000100010000101000;
{position, e, four} ->
2#0000000000000000001010000100010000000000010001000010100000000000;
{position, e, five} ->
2#0000000000101000010001000000000001000100001010000000000000000000;
{position, e, six} ->
2#0010100001000100000000000100010000101000000000000000000000000000;
{position, e, seven} ->
2#0100010000000000010001000010100000000000000000000000000000000000;
{position, e, eight} ->
2#0000000001000100001010000000000000000000000000000000000000000000;
{position, f, one} ->
2#0000000000000000000000000000000000000000010100001000100000000000;
{position, f, two} ->
2#0000000000000000000000000000000001010000100010000000000010001000;
{position, f, three} ->
2#0000000000000000000000000101000010001000000000001000100001010000;
{position, f, four} ->
2#0000000000000000010100001000100000000000100010000101000000000000;
{position, f, five} ->
2#0000000001010000100010000000000010001000010100000000000000000000;
{position, f, six} ->
2#0101000010001000000000001000100001010000000000000000000000000000;
{position, f, seven} ->
2#1000100000000000100010000101000000000000000000000000000000000000;
{position, f, eight} ->
2#0000000010001000010100000000000000000000000000000000000000000000;
{position, g, one} ->
2#0000000000000000000000000000000000000000101000000001000000000000;
{position, g, two} ->
2#0000000000000000000000000000000010100000000100000000000000010000;
{position, g, three} ->
2#0000000000000000000000001010000000010000000000000001000010100000;
{position, g, four} ->
2#0000000000000000101000000001000000000000000100001010000000000000;
{position, g, five} ->
2#0000000010100000000100000000000000010000101000000000000000000000;
{position, g, six} ->
2#1010000000010000000000000001000010100000000000000000000000000000;
{position, g, seven} ->
2#0001000000000000000100001010000000000000000000000000000000000000;
{position, g, eight} ->
2#0000000000010000101000000000000000000000000000000000000000000000;
{position, h, one} ->
2#0000000000000000000000000000000000000000010000000010000000000000;
{position, h, two} ->
2#0000000000000000000000000000000001000000001000000000000000100000;
{position, h, three} ->
2#0000000000000000000000000100000000100000000000000010000001000000;
{position, h, four} ->
2#0000000000000000010000000010000000000000001000000100000000000000;
{position, h, five} ->
2#0000000001000000001000000000000000100000010000000000000000000000;
{position, h, six} ->
2#0100000000100000000000000010000001000000000000000000000000000000;
{position, h, seven} ->
2#0010000000000000001000000100000000000000000000000000000000000000;
{position, h, eight} ->
2#0000000000100000010000000000000000000000000000000000000000000000
end.
-spec look_up_east_ray_bb(position:position()) -> integer().
look_up_east_ray_bb(Origin_square) ->
case Origin_square of
{position, a, one} ->
2#0000000000000000000000000000000000000000000000000000000011111110;
{position, a, two} ->
2#0000000000000000000000000000000000000000000000001111111000000000;
{position, a, three} ->
2#0000000000000000000000000000000000000000111111100000000000000000;
{position, a, four} ->
2#0000000000000000000000000000000011111110000000000000000000000000;
{position, a, five} ->
2#0000000000000000000000001111111000000000000000000000000000000000;
{position, a, six} ->
2#0000000000000000111111100000000000000000000000000000000000000000;
{position, a, seven} ->
2#0000000011111110000000000000000000000000000000000000000000000000;
{position, a, eight} ->
2#1111111000000000000000000000000000000000000000000000000000000000;
{position, b, one} ->
2#0000000000000000000000000000000000000000000000000000000011111100;
{position, b, two} ->
2#0000000000000000000000000000000000000000000000001111110000000000;
{position, b, three} ->
2#0000000000000000000000000000000000000000111111000000000000000000;
{position, b, four} ->
2#0000000000000000000000000000000011111100000000000000000000000000;
{position, b, five} ->
2#0000000000000000000000001111110000000000000000000000000000000000;
{position, b, six} ->
2#0000000000000000111111000000000000000000000000000000000000000000;
{position, b, seven} ->
2#0000000011111100000000000000000000000000000000000000000000000000;
{position, b, eight} ->
2#1111110000000000000000000000000000000000000000000000000000000000;
{position, c, one} ->
2#0000000000000000000000000000000000000000000000000000000011111000;
{position, c, two} ->
2#0000000000000000000000000000000000000000000000001111100000000000;
{position, c, three} ->
2#0000000000000000000000000000000000000000111110000000000000000000;
{position, c, four} ->
2#0000000000000000000000000000000011111000000000000000000000000000;
{position, c, five} ->
2#0000000000000000000000001111100000000000000000000000000000000000;
{position, c, six} ->
2#0000000000000000111110000000000000000000000000000000000000000000;
{position, c, seven} ->
2#0000000011111000000000000000000000000000000000000000000000000000;
{position, c, eight} ->
2#1111100000000000000000000000000000000000000000000000000000000000;
{position, d, one} ->
2#0000000000000000000000000000000000000000000000000000000011110000;
{position, d, two} ->
2#0000000000000000000000000000000000000000000000001111000000000000;
{position, d, three} ->
2#0000000000000000000000000000000000000000111100000000000000000000;
{position, d, four} ->
2#0000000000000000000000000000000011110000000000000000000000000000;
{position, d, five} ->
2#0000000000000000000000001111000000000000000000000000000000000000;
{position, d, six} ->
2#0000000000000000111100000000000000000000000000000000000000000000;
{position, d, seven} ->
2#0000000011110000000000000000000000000000000000000000000000000000;
{position, d, eight} ->
2#1111000000000000000000000000000000000000000000000000000000000000;
{position, e, one} ->
2#0000000000000000000000000000000000000000000000000000000011100000;
{position, e, two} ->
2#0000000000000000000000000000000000000000000000001110000000000000;
{position, e, three} ->
2#0000000000000000000000000000000000000000111000000000000000000000;
{position, e, four} ->
2#0000000000000000000000000000000011100000000000000000000000000000;
{position, e, five} ->
2#0000000000000000000000001110000000000000000000000000000000000000;
{position, e, six} ->
2#0000000000000000111000000000000000000000000000000000000000000000;
{position, e, seven} ->
2#0000000011100000000000000000000000000000000000000000000000000000;
{position, e, eight} ->
2#1110000000000000000000000000000000000000000000000000000000000000;
{position, f, one} ->
2#0000000000000000000000000000000000000000000000000000000011000000;
{position, f, two} ->
2#0000000000000000000000000000000000000000000000001100000000000000;
{position, f, three} ->
2#0000000000000000000000000000000000000000110000000000000000000000;
{position, f, four} ->
2#0000000000000000000000000000000011000000000000000000000000000000;
{position, f, five} ->
2#0000000000000000000000001100000000000000000000000000000000000000;
{position, f, six} ->
2#0000000000000000110000000000000000000000000000000000000000000000;
{position, f, seven} ->
2#0000000011000000000000000000000000000000000000000000000000000000;
{position, f, eight} ->
2#1100000000000000000000000000000000000000000000000000000000000000;
{position, g, one} ->
2#0000000000000000000000000000000000000000000000000000000010000000;
{position, g, two} ->
2#0000000000000000000000000000000000000000000000001000000000000000;
{position, g, three} ->
2#0000000000000000000000000000000000000000100000000000000000000000;
{position, g, four} ->
2#0000000000000000000000000000000010000000000000000000000000000000;
{position, g, five} ->
2#0000000000000000000000001000000000000000000000000000000000000000;
{position, g, six} ->
2#0000000000000000100000000000000000000000000000000000000000000000;
{position, g, seven} ->
2#0000000010000000000000000000000000000000000000000000000000000000;
{position, g, eight} ->
2#1000000000000000000000000000000000000000000000000000000000000000;
{position, h, one} ->
2#0000000000000000000000000000000000000000000000000000000000000000;
{position, h, two} ->
2#0000000000000000000000000000000000000000000000000000000000000000;
{position, h, three} ->
2#0000000000000000000000000000000000000000000000000000000000000000;
{position, h, four} ->
2#0000000000000000000000000000000000000000000000000000000000000000;
{position, h, five} ->
2#0000000000000000000000000000000000000000000000000000000000000000;
{position, h, six} ->
2#0000000000000000000000000000000000000000000000000000000000000000;
{position, h, seven} ->
2#0000000000000000000000000000000000000000000000000000000000000000;
{position, h, eight} ->
2#0000000000000000000000000000000000000000000000000000000000000000
end.
-spec look_up_north_ray_bb(position:position()) -> integer().
look_up_north_ray_bb(Origin_square) ->
case Origin_square of
{position, a, eight} ->
2#0000000000000000000000000000000000000000000000000000000000000000;
{position, a, seven} ->
2#0000000100000000000000000000000000000000000000000000000000000000;
{position, a, six} ->
2#0000000100000001000000000000000000000000000000000000000000000000;
{position, a, five} ->
2#0000000100000001000000010000000000000000000000000000000000000000;
{position, a, four} ->
2#0000000100000001000000010000000100000000000000000000000000000000;
{position, a, three} ->
2#0000000100000001000000010000000100000001000000000000000000000000;
{position, a, two} ->
2#0000000100000001000000010000000100000001000000010000000000000000;
{position, a, one} ->
2#0000000100000001000000010000000100000001000000010000000100000000;
{position, b, eight} ->
2#0000000000000000000000000000000000000000000000000000000000000000;
{position, b, seven} ->
2#0000001000000000000000000000000000000000000000000000000000000000;
{position, b, six} ->
2#0000001000000010000000000000000000000000000000000000000000000000;
{position, b, five} ->
2#0000001000000010000000100000000000000000000000000000000000000000;
{position, b, four} ->
2#0000001000000010000000100000001000000000000000000000000000000000;
{position, b, three} ->
2#0000001000000010000000100000001000000010000000000000000000000000;
{position, b, two} ->
2#0000001000000010000000100000001000000010000000100000000000000000;
{position, b, one} ->
2#0000001000000010000000100000001000000010000000100000001000000000;
{position, c, eight} ->
2#0000000000000000000000000000000000000000000000000000000000000000;
{position, c, seven} ->
2#0000010000000000000000000000000000000000000000000000000000000000;
{position, c, six} ->
2#0000010000000100000000000000000000000000000000000000000000000000;
{position, c, five} ->
2#0000010000000100000001000000000000000000000000000000000000000000;
{position, c, four} ->
2#0000010000000100000001000000010000000000000000000000000000000000;
{position, c, three} ->
2#0000010000000100000001000000010000000100000000000000000000000000;
{position, c, two} ->
2#0000010000000100000001000000010000000100000001000000000000000000;
{position, c, one} ->
2#0000010000000100000001000000010000000100000001000000010000000000;
{position, d, eight} ->
2#0000000000000000000000000000000000000000000000000000000000000000;
{position, d, seven} ->
2#0000100000000000000000000000000000000000000000000000000000000000;
{position, d, six} ->
2#0000100000001000000000000000000000000000000000000000000000000000;
{position, d, five} ->
2#0000100000001000000010000000000000000000000000000000000000000000;
{position, d, four} ->
2#0000100000001000000010000000100000000000000000000000000000000000;
{position, d, three} ->
2#0000100000001000000010000000100000001000000000000000000000000000;
{position, d, two} ->
2#0000100000001000000010000000100000001000000010000000000000000000;
{position, d, one} ->
2#0000100000001000000010000000100000001000000010000000100000000000;
{position, e, eight} ->
2#0000000000000000000000000000000000000000000000000000000000000000;
{position, e, seven} ->
2#0001000000000000000000000000000000000000000000000000000000000000;
{position, e, six} ->
2#0001000000010000000000000000000000000000000000000000000000000000;
{position, e, five} ->
2#0001000000010000000100000000000000000000000000000000000000000000;
{position, e, four} ->
2#0001000000010000000100000001000000000000000000000000000000000000;
{position, e, three} ->
2#0001000000010000000100000001000000010000000000000000000000000000;
{position, e, two} ->
2#0001000000010000000100000001000000010000000100000000000000000000;
{position, e, one} ->
2#0001000000010000000100000001000000010000000100000001000000000000;
{position, f, eight} ->
2#0000000000000000000000000000000000000000000000000000000000000000;
{position, f, seven} ->
2#0010000000000000000000000000000000000000000000000000000000000000;
{position, f, six} ->
2#0010000000100000000000000000000000000000000000000000000000000000;
{position, f, five} ->
2#0010000000100000001000000000000000000000000000000000000000000000;
{position, f, four} ->
2#0010000000100000001000000010000000000000000000000000000000000000;
{position, f, three} ->
2#0010000000100000001000000010000000100000000000000000000000000000;
{position, f, two} ->
2#0010000000100000001000000010000000100000001000000000000000000000;
{position, f, one} ->
2#0010000000100000001000000010000000100000001000000010000000000000;
{position, g, eight} ->
2#0000000000000000000000000000000000000000000000000000000000000000;
{position, g, seven} ->
2#0100000000000000000000000000000000000000000000000000000000000000;
{position, g, six} ->
2#0100000001000000000000000000000000000000000000000000000000000000;
{position, g, five} ->
2#0100000001000000010000000000000000000000000000000000000000000000;
{position, g, four} ->
2#0100000001000000010000000100000000000000000000000000000000000000;
{position, g, three} ->
2#0100000001000000010000000100000001000000000000000000000000000000;
{position, g, two} ->
2#0100000001000000010000000100000001000000010000000000000000000000;
{position, g, one} ->
2#0100000001000000010000000100000001000000010000000100000000000000;
{position, h, eight} ->
2#0000000000000000000000000000000000000000000000000000000000000000;
{position, h, seven} ->
2#1000000000000000000000000000000000000000000000000000000000000000;
{position, h, six} ->
2#1000000010000000000000000000000000000000000000000000000000000000;
{position, h, five} ->
2#1000000010000000100000000000000000000000000000000000000000000000;
{position, h, four} ->
2#1000000010000000100000001000000000000000000000000000000000000000;
{position, h, three} ->
2#1000000010000000100000001000000010000000000000000000000000000000;
{position, h, two} ->
2#1000000010000000100000001000000010000000100000000000000000000000;
{position, h, one} ->
2#1000000010000000100000001000000010000000100000001000000000000000
end.
-spec look_up_west_ray_bb(position:position()) -> integer().
look_up_west_ray_bb(Origin_square) ->
case Origin_square of
{position, h, eight} ->
2#0111111100000000000000000000000000000000000000000000000000000000;
{position, h, seven} ->
2#0000000001111111000000000000000000000000000000000000000000000000;
{position, h, six} ->
2#0000000000000000011111110000000000000000000000000000000000000000;
{position, h, five} ->
2#0000000000000000000000000111111100000000000000000000000000000000;
{position, h, four} ->
2#0000000000000000000000000000000001111111000000000000000000000000;
{position, h, three} ->
2#0000000000000000000000000000000000000000011111110000000000000000;
{position, h, two} ->
2#0000000000000000000000000000000000000000000000000111111100000000;
{position, h, one} ->
2#0000000000000000000000000000000000000000000000000000000001111111;
{position, g, eight} ->
2#0011111100000000000000000000000000000000000000000000000000000000;
{position, g, seven} ->
2#0000000000111111000000000000000000000000000000000000000000000000;
{position, g, six} ->
2#0000000000000000001111110000000000000000000000000000000000000000;
{position, g, five} ->
2#0000000000000000000000000011111100000000000000000000000000000000;
{position, g, four} ->
2#0000000000000000000000000000000000111111000000000000000000000000;
{position, g, three} ->
2#0000000000000000000000000000000000000000001111110000000000000000;
{position, g, two} ->
2#0000000000000000000000000000000000000000000000000011111100000000;
{position, g, one} ->
2#0000000000000000000000000000000000000000000000000000000000111111;
{position, f, eight} ->
2#0001111100000000000000000000000000000000000000000000000000000000;
{position, f, seven} ->
2#0000000000011111000000000000000000000000000000000000000000000000;
{position, f, six} ->
2#0000000000000000000111110000000000000000000000000000000000000000;
{position, f, five} ->
2#0000000000000000000000000001111100000000000000000000000000000000;
{position, f, four} ->
2#0000000000000000000000000000000000011111000000000000000000000000;
{position, f, three} ->
2#0000000000000000000000000000000000000000000111110000000000000000;
{position, f, two} ->
2#0000000000000000000000000000000000000000000000000001111100000000;
{position, f, one} ->
2#0000000000000000000000000000000000000000000000000000000000011111;
{position, e, eight} ->
2#0000111100000000000000000000000000000000000000000000000000000000;
{position, e, seven} ->
2#0000000000001111000000000000000000000000000000000000000000000000;
{position, e, six} ->
2#0000000000000000000011110000000000000000000000000000000000000000;
{position, e, five} ->
2#0000000000000000000000000000111100000000000000000000000000000000;
{position, e, four} ->
2#0000000000000000000000000000000000001111000000000000000000000000;
{position, e, three} ->
2#0000000000000000000000000000000000000000000011110000000000000000;
{position, e, two} ->
2#0000000000000000000000000000000000000000000000000000111100000000;
{position, e, one} ->
2#0000000000000000000000000000000000000000000000000000000000001111;
{position, d, eight} ->
2#0000011100000000000000000000000000000000000000000000000000000000;
{position, d, seven} ->
2#0000000000000111000000000000000000000000000000000000000000000000;
{position, d, six} ->
2#0000000000000000000001110000000000000000000000000000000000000000;
{position, d, five} ->
2#0000000000000000000000000000011100000000000000000000000000000000;
{position, d, four} ->
2#0000000000000000000000000000000000000111000000000000000000000000;
{position, d, three} ->
2#0000000000000000000000000000000000000000000001110000000000000000;
{position, d, two} ->
2#0000000000000000000000000000000000000000000000000000011100000000;
{position, d, one} ->
2#0000000000000000000000000000000000000000000000000000000000000111;
{position, c, eight} ->
2#0000001100000000000000000000000000000000000000000000000000000000;
{position, c, seven} ->
2#0000000000000011000000000000000000000000000000000000000000000000;
{position, c, six} ->
2#0000000000000000000000110000000000000000000000000000000000000000;
{position, c, five} ->
2#0000000000000000000000000000001100000000000000000000000000000000;
{position, c, four} ->
2#0000000000000000000000000000000000000011000000000000000000000000;
{position, c, three} ->
2#0000000000000000000000000000000000000000000000110000000000000000;
{position, c, two} ->
2#0000000000000000000000000000000000000000000000000000001100000000;
{position, c, one} ->
2#0000000000000000000000000000000000000000000000000000000000000011;
{position, b, eight} ->
2#0000000100000000000000000000000000000000000000000000000000000000;
{position, b, seven} ->
2#0000000000000001000000000000000000000000000000000000000000000000;
{position, b, six} ->
2#0000000000000000000000010000000000000000000000000000000000000000;
{position, b, five} ->
2#0000000000000000000000000000000100000000000000000000000000000000;
{position, b, four} ->
2#0000000000000000000000000000000000000001000000000000000000000000;
{position, b, three} ->
2#0000000000000000000000000000000000000000000000010000000000000000;
{position, b, two} ->
2#0000000000000000000000000000000000000000000000000000000100000000;
{position, b, one} ->
2#0000000000000000000000000000000000000000000000000000000000000001;
{position, a, eight} ->
2#0000000000000000000000000000000000000000000000000000000000000000;
{position, a, seven} ->
2#0000000000000000000000000000000000000000000000000000000000000000;
{position, a, six} ->
2#0000000000000000000000000000000000000000000000000000000000000000;
{position, a, five} ->
2#0000000000000000000000000000000000000000000000000000000000000000;
{position, a, four} ->
2#0000000000000000000000000000000000000000000000000000000000000000;
{position, a, three} ->
2#0000000000000000000000000000000000000000000000000000000000000000;
{position, a, two} ->
2#0000000000000000000000000000000000000000000000000000000000000000;
{position, a, one} ->
2#0000000000000000000000000000000000000000000000000000000000000000
end.
-spec look_up_south_ray_bb(position:position()) -> integer().
look_up_south_ray_bb(Origin_square) ->
case Origin_square of
{position, a, eight} ->
2#0000000000000001000000010000000100000001000000010000000100000001;
{position, a, seven} ->
2#0000000000000000000000010000000100000001000000010000000100000001;
{position, a, six} ->
2#0000000000000000000000000000000100000001000000010000000100000001;
{position, a, five} ->
2#0000000000000000000000000000000000000001000000010000000100000001;
{position, a, four} ->
2#0000000000000000000000000000000000000000000000010000000100000001;
{position, a, three} ->
2#0000000000000000000000000000000000000000000000000000000100000001;
{position, a, two} ->
2#0000000000000000000000000000000000000000000000000000000000000001;
{position, a, one} ->
2#0000000000000000000000000000000000000000000000000000000000000000;
{position, b, eight} ->
2#0000000000000010000000100000001000000010000000100000001000000010;
{position, b, seven} ->
2#0000000000000000000000100000001000000010000000100000001000000010;
{position, b, six} ->
2#0000000000000000000000000000001000000010000000100000001000000010;
{position, b, five} ->
2#0000000000000000000000000000000000000010000000100000001000000010;
{position, b, four} ->
2#0000000000000000000000000000000000000000000000100000001000000010;
{position, b, three} ->
2#0000000000000000000000000000000000000000000000000000001000000010;
{position, b, two} ->
2#0000000000000000000000000000000000000000000000000000000000000010;
{position, b, one} ->
2#0000000000000000000000000000000000000000000000000000000000000000;
{position, c, eight} ->
2#0000000000000100000001000000010000000100000001000000010000000100;
{position, c, seven} ->
2#0000000000000000000001000000010000000100000001000000010000000100;
{position, c, six} ->
2#0000000000000000000000000000010000000100000001000000010000000100;
{position, c, five} ->
2#0000000000000000000000000000000000000100000001000000010000000100;
{position, c, four} ->
2#0000000000000000000000000000000000000000000001000000010000000100;
{position, c, three} ->
2#0000000000000000000000000000000000000000000000000000010000000100;
{position, c, two} ->
2#0000000000000000000000000000000000000000000000000000000000000100;
{position, c, one} ->
2#0000000000000000000000000000000000000000000000000000000000000000;
{position, d, eight} ->
2#0000000000001000000010000000100000001000000010000000100000001000;
{position, d, seven} ->
2#0000000000000000000010000000100000001000000010000000100000001000;
{position, d, six} ->
2#0000000000000000000000000000100000001000000010000000100000001000;
{position, d, five} ->
2#0000000000000000000000000000000000001000000010000000100000001000;
{position, d, four} ->
2#0000000000000000000000000000000000000000000010000000100000001000;
{position, d, three} ->
2#0000000000000000000000000000000000000000000000000000100000001000;
{position, d, two} ->
2#0000000000000000000000000000000000000000000000000000000000001000;
{position, d, one} ->
2#0000000000000000000000000000000000000000000000000000000000000000;
{position, e, eight} ->
2#0000000000010000000100000001000000010000000100000001000000010000;
{position, e, seven} ->
2#0000000000000000000100000001000000010000000100000001000000010000;
{position, e, six} ->
2#0000000000000000000000000001000000010000000100000001000000010000;
{position, e, five} ->
2#0000000000000000000000000000000000010000000100000001000000010000;
{position, e, four} ->
2#0000000000000000000000000000000000000000000100000001000000010000;
{position, e, three} ->
2#0000000000000000000000000000000000000000000000000001000000010000;
{position, e, two} ->
2#0000000000000000000000000000000000000000000000000000000000010000;
{position, e, one} ->
2#0000000000000000000000000000000000000000000000000000000000000000;
{position, f, eight} ->
2#0000000000100000001000000010000000100000001000000010000000100000;
{position, f, seven} ->
2#0000000000000000001000000010000000100000001000000010000000100000;
{position, f, six} ->
2#0000000000000000000000000010000000100000001000000010000000100000;
{position, f, five} ->
2#0000000000000000000000000000000000100000001000000010000000100000;
{position, f, four} ->
2#0000000000000000000000000000000000000000001000000010000000100000;
{position, f, three} ->
2#0000000000000000000000000000000000000000000000000010000000100000;
{position, f, two} ->
2#0000000000000000000000000000000000000000000000000000000000100000;
{position, f, one} ->
2#0000000000000000000000000000000000000000000000000000000000000000;
{position, g, eight} ->
2#0000000001000000010000000100000001000000010000000100000001000000;
{position, g, seven} ->
2#0000000000000000010000000100000001000000010000000100000001000000;
{position, g, six} ->
2#0000000000000000000000000100000001000000010000000100000001000000;
{position, g, five} ->
2#0000000000000000000000000000000001000000010000000100000001000000;
{position, g, four} ->
2#0000000000000000000000000000000000000000010000000100000001000000;
{position, g, three} ->
2#0000000000000000000000000000000000000000000000000100000001000000;
{position, g, two} ->
2#0000000000000000000000000000000000000000000000000000000001000000;
{position, g, one} ->
2#0000000000000000000000000000000000000000000000000000000000000000;
{position, h, eight} ->
2#0000000010000000100000001000000010000000100000001000000010000000;
{position, h, seven} ->
2#0000000000000000100000001000000010000000100000001000000010000000;
{position, h, six} ->
2#0000000000000000000000001000000010000000100000001000000010000000;
{position, h, five} ->
2#0000000000000000000000000000000010000000100000001000000010000000;
{position, h, four} ->
2#0000000000000000000000000000000000000000100000001000000010000000;
{position, h, three} ->
2#0000000000000000000000000000000000000000000000001000000010000000;
{position, h, two} ->
2#0000000000000000000000000000000000000000000000000000000010000000;
{position, h, one} ->
2#0000000000000000000000000000000000000000000000000000000000000000
end.
-spec look_up_south_west_ray_bb(position:position()) -> integer().
look_up_south_west_ray_bb(Origin_square) ->
case Origin_square of
{position, a, eight} ->
2#0000000000000000000000000000000000000000000000000000000000000000;
{position, a, seven} ->
2#0000000000000000000000000000000000000000000000000000000000000000;
{position, a, six} ->
2#0000000000000000000000000000000000000000000000000000000000000000;
{position, a, five} ->
2#0000000000000000000000000000000000000000000000000000000000000000;
{position, a, four} ->
2#0000000000000000000000000000000000000000000000000000000000000000;
{position, a, three} ->
2#0000000000000000000000000000000000000000000000000000000000000000;
{position, a, two} ->
2#0000000000000000000000000000000000000000000000000000000000000000;
{position, a, one} ->
2#0000000000000000000000000000000000000000000000000000000000000000;
{position, b, eight} ->
2#0000000000000001000000000000000000000000000000000000000000000000;
{position, b, seven} ->
2#0000000000000000000000010000000000000000000000000000000000000000;
{position, b, six} ->
2#0000000000000000000000000000000100000000000000000000000000000000;
{position, b, five} ->
2#0000000000000000000000000000000000000001000000000000000000000000;
{position, b, four} ->
2#0000000000000000000000000000000000000000000000010000000000000000;
{position, b, three} ->
2#0000000000000000000000000000000000000000000000000000000100000000;
{position, b, two} ->
2#0000000000000000000000000000000000000000000000000000000000000001;
{position, b, one} ->
2#0000000000000000000000000000000000000000000000000000000000000000;
{position, c, eight} ->
2#0000000000000010000000010000000000000000000000000000000000000000;
{position, c, seven} ->
2#0000000000000000000000100000000100000000000000000000000000000000;
{position, c, six} ->
2#0000000000000000000000000000001000000001000000000000000000000000;
{position, c, five} ->
2#0000000000000000000000000000000000000010000000010000000000000000;
{position, c, four} ->
2#0000000000000000000000000000000000000000000000100000000100000000;
{position, c, three} ->
2#0000000000000000000000000000000000000000000000000000001000000001;
{position, c, two} ->
2#0000000000000000000000000000000000000000000000000000000000000010;
{position, c, one} ->
2#0000000000000000000000000000000000000000000000000000000000000000;
{position, d, eight} ->
2#0000000000000100000000100000000100000000000000000000000000000000;
{position, d, seven} ->
2#0000000000000000000001000000001000000001000000000000000000000000;
{position, d, six} ->
2#0000000000000000000000000000010000000010000000010000000000000000;
{position, d, five} ->
2#0000000000000000000000000000000000000100000000100000000100000000;
{position, d, four} ->
2#0000000000000000000000000000000000000000000001000000001000000001;
{position, d, three} ->
2#0000000000000000000000000000000000000000000000000000010000000010;
{position, d, two} ->
2#0000000000000000000000000000000000000000000000000000000000000100;
{position, d, one} ->
2#0000000000000000000000000000000000000000000000000000000000000000;
{position, e, eight} ->
2#0000000000001000000001000000001000000001000000000000000000000000;
{position, e, seven} ->
2#0000000000000000000010000000010000000010000000010000000000000000;
{position, e, six} ->
2#0000000000000000000000000000100000000100000000100000000100000000;
{position, e, five} ->
2#0000000000000000000000000000000000001000000001000000001000000001;
{position, e, four} ->
2#0000000000000000000000000000000000000000000010000000010000000010;
{position, e, three} ->
2#0000000000000000000000000000000000000000000000000000100000000100;
{position, e, two} ->
2#0000000000000000000000000000000000000000000000000000000000001000;
{position, e, one} ->
2#0000000000000000000000000000000000000000000000000000000000000000;
{position, f, eight} ->
2#0000000000010000000010000000010000000010000000010000000000000000;
{position, f, seven} ->
2#0000000000000000000100000000100000000100000000100000000100000000;
{position, f, six} ->
2#0000000000000000000000000001000000001000000001000000001000000001;
{position, f, five} ->
2#0000000000000000000000000000000000010000000010000000010000000010;
{position, f, four} ->
2#0000000000000000000000000000000000000000000100000000100000000100;
{position, f, three} ->
2#0000000000000000000000000000000000000000000000000001000000001000;
{position, f, two} ->
2#0000000000000000000000000000000000000000000000000000000000010000;
{position, f, one} ->
2#0000000000000000000000000000000000000000000000000000000000000000;
{position, g, eight} ->
2#0000000000100000000100000000100000000100000000100000000100000000;
{position, g, seven} ->
2#0000000000000000001000000001000000001000000001000000001000000001;
{position, g, six} ->
2#0000000000000000000000000010000000010000000010000000010000000010;
{position, g, five} ->
2#0000000000000000000000000000000000100000000100000000100000000100;
{position, g, four} ->
2#0000000000000000000000000000000000000000001000000001000000001000;
{position, g, three} ->
2#0000000000000000000000000000000000000000000000000010000000010000;
{position, g, two} ->
2#0000000000000000000000000000000000000000000000000000000000100000;
{position, g, one} ->
2#0000000000000000000000000000000000000000000000000000000000000000;
{position, h, eight} ->
2#0000000001000000001000000001000000001000000001000000001000000001;
{position, h, seven} ->
2#0000000000000000010000000010000000010000000010000000010000000010;
{position, h, six} ->
2#0000000000000000000000000100000000100000000100000000100000000100;
{position, h, five} ->
2#0000000000000000000000000000000001000000001000000001000000001000;
{position, h, four} ->
2#0000000000000000000000000000000000000000010000000010000000010000;
{position, h, three} ->
2#0000000000000000000000000000000000000000000000000100000000100000;
{position, h, two} ->
2#0000000000000000000000000000000000000000000000000000000001000000;
{position, h, one} ->
2#0000000000000000000000000000000000000000000000000000000000000000
end.
-spec look_up_south_east_ray_bb(position:position()) -> integer().
look_up_south_east_ray_bb(Origin_square) ->
case Origin_square of
{position, a, eight} ->
2#0000000000000010000001000000100000010000001000000100000010000000;
{position, a, seven} ->
2#0000000000000000000000100000010000001000000100000010000001000000;
{position, a, six} ->
2#0000000000000000000000000000001000000100000010000001000000100000;
{position, a, five} ->
2#0000000000000000000000000000000000000010000001000000100000010000;
{position, a, four} ->
2#0000000000000000000000000000000000000000000000100000010000001000;
{position, a, three} ->
2#0000000000000000000000000000000000000000000000000000001000000100;
{position, a, two} ->
2#0000000000000000000000000000000000000000000000000000000000000010;
{position, a, one} ->
2#0000000000000000000000000000000000000000000000000000000000000000;
{position, b, eight} ->
2#0000000000000100000010000001000000100000010000001000000000000000;
{position, b, seven} ->
2#0000000000000000000001000000100000010000001000000100000010000000;
{position, b, six} ->
2#0000000000000000000000000000010000001000000100000010000001000000;
{position, b, five} ->
2#0000000000000000000000000000000000000100000010000001000000100000;
{position, b, four} ->
2#0000000000000000000000000000000000000000000001000000100000010000;
{position, b, three} ->
2#0000000000000000000000000000000000000000000000000000010000001000;
{position, b, two} ->
2#0000000000000000000000000000000000000000000000000000000000000100;
{position, b, one} ->
2#0000000000000000000000000000000000000000000000000000000000000000;
{position, c, eight} ->
2#0000000000001000000100000010000001000000100000000000000000000000;
{position, c, seven} ->
2#0000000000000000000010000001000000100000010000001000000000000000;
{position, c, six} ->
2#0000000000000000000000000000100000010000001000000100000010000000;
{position, c, five} ->
2#0000000000000000000000000000000000001000000100000010000001000000;
{position, c, four} ->
2#0000000000000000000000000000000000000000000010000001000000100000;
{position, c, three} ->
2#0000000000000000000000000000000000000000000000000000100000010000;
{position, c, two} ->
2#0000000000000000000000000000000000000000000000000000000000001000;
{position, c, one} ->
2#0000000000000000000000000000000000000000000000000000000000000000;
{position, d, eight} ->
2#0000000000010000001000000100000010000000000000000000000000000000;
{position, d, seven} ->
2#0000000000000000000100000010000001000000100000000000000000000000;
{position, d, six} ->
2#0000000000000000000000000001000000100000010000001000000000000000;
{position, d, five} ->
2#0000000000000000000000000000000000010000001000000100000010000000;
{position, d, four} ->
2#0000000000000000000000000000000000000000000100000010000001000000;
{position, d, three} ->
2#0000000000000000000000000000000000000000000000000001000000100000;
{position, d, two} ->
2#0000000000000000000000000000000000000000000000000000000000010000;
{position, d, one} ->
2#0000000000000000000000000000000000000000000000000000000000000000;
{position, e, eight} ->
2#0000000000100000010000001000000000000000000000000000000000000000;
{position, e, seven} ->
2#0000000000000000001000000100000010000000000000000000000000000000;
{position, e, six} ->
2#0000000000000000000000000010000001000000100000000000000000000000;
{position, e, five} ->
2#0000000000000000000000000000000000100000010000001000000000000000;
{position, e, four} ->
2#0000000000000000000000000000000000000000001000000100000010000000;
{position, e, three} ->
2#0000000000000000000000000000000000000000000000000010000001000000;
{position, e, two} ->
2#0000000000000000000000000000000000000000000000000000000000100000;
{position, e, one} ->
2#0000000000000000000000000000000000000000000000000000000000000000;
{position, f, eight} ->
2#0000000001000000100000000000000000000000000000000000000000000000;
{position, f, seven} ->
2#0000000000000000010000001000000000000000000000000000000000000000;
{position, f, six} ->
2#0000000000000000000000000100000010000000000000000000000000000000;
{position, f, five} ->
2#0000000000000000000000000000000001000000100000000000000000000000;
{position, f, four} ->
2#0000000000000000000000000000000000000000010000001000000000000000;
{position, f, three} ->
2#0000000000000000000000000000000000000000000000000100000010000000;
{position, f, two} ->
2#0000000000000000000000000000000000000000000000000000000001000000;
{position, f, one} ->
2#0000000000000000000000000000000000000000000000000000000000000000;
{position, g, eight} ->
2#0000000010000000000000000000000000000000000000000000000000000000;
{position, g, seven} ->
2#0000000000000000100000000000000000000000000000000000000000000000;
{position, g, six} ->
2#0000000000000000000000001000000000000000000000000000000000000000;
{position, g, five} ->
2#0000000000000000000000000000000010000000000000000000000000000000;
{position, g, four} ->
2#0000000000000000000000000000000000000000100000000000000000000000;
{position, g, three} ->
2#0000000000000000000000000000000000000000000000001000000000000000;
{position, g, two} ->
2#0000000000000000000000000000000000000000000000000000000010000000;
{position, g, one} ->
2#0000000000000000000000000000000000000000000000000000000000000000;
{position, h, eight} ->
2#0000000000000000000000000000000000000000000000000000000000000000;
{position, h, seven} ->
2#0000000000000000000000000000000000000000000000000000000000000000;
{position, h, six} ->
2#0000000000000000000000000000000000000000000000000000000000000000;
{position, h, five} ->
2#0000000000000000000000000000000000000000000000000000000000000000;
{position, h, four} ->
2#0000000000000000000000000000000000000000000000000000000000000000;
{position, h, three} ->
2#0000000000000000000000000000000000000000000000000000000000000000;
{position, h, two} ->
2#0000000000000000000000000000000000000000000000000000000000000000;
{position, h, one} ->
2#0000000000000000000000000000000000000000000000000000000000000000
end.
-spec look_up_north_east_ray_bb(position:position()) -> integer().
look_up_north_east_ray_bb(Origin_square) ->
case Origin_square of
{position, a, one} ->
2#1000000001000000001000000001000000001000000001000000001000000000;
{position, a, two} ->
2#0100000000100000000100000000100000000100000000100000000000000000;
{position, a, three} ->
2#0010000000010000000010000000010000000010000000000000000000000000;
{position, a, four} ->
2#0001000000001000000001000000001000000000000000000000000000000000;
{position, a, five} ->
2#0000100000000100000000100000000000000000000000000000000000000000;
{position, a, six} ->
2#0000010000000010000000000000000000000000000000000000000000000000;
{position, a, seven} ->
2#0000001000000000000000000000000000000000000000000000000000000000;
{position, a, eight} ->
2#0000000000000000000000000000000000000000000000000000000000000000;
{position, b, one} ->
2#0000000010000000010000000010000000010000000010000000010000000000;
{position, b, two} ->
2#1000000001000000001000000001000000001000000001000000000000000000;
{position, b, three} ->
2#0100000000100000000100000000100000000100000000000000000000000000;
{position, b, four} ->
2#0010000000010000000010000000010000000000000000000000000000000000;
{position, b, five} ->
2#0001000000001000000001000000000000000000000000000000000000000000;
{position, b, six} ->
2#0000100000000100000000000000000000000000000000000000000000000000;
{position, b, seven} ->
2#0000010000000000000000000000000000000000000000000000000000000000;
{position, b, eight} ->
2#0000000000000000000000000000000000000000000000000000000000000000;
{position, c, one} ->
2#0000000000000000100000000100000000100000000100000000100000000000;
{position, c, two} ->
2#0000000010000000010000000010000000010000000010000000000000000000;
{position, c, three} ->
2#1000000001000000001000000001000000001000000000000000000000000000;
{position, c, four} ->
2#0100000000100000000100000000100000000000000000000000000000000000;
{position, c, five} ->
2#0010000000010000000010000000000000000000000000000000000000000000;
{position, c, six} ->
2#0001000000001000000000000000000000000000000000000000000000000000;
{position, c, seven} ->
2#0000100000000000000000000000000000000000000000000000000000000000;
{position, c, eight} ->
2#0000000000000000000000000000000000000000000000000000000000000000;
{position, d, one} ->
2#0000000000000000000000001000000001000000001000000001000000000000;
{position, d, two} ->
2#0000000000000000100000000100000000100000000100000000000000000000;
{position, d, three} ->
2#0000000010000000010000000010000000010000000000000000000000000000;
{position, d, four} ->
2#1000000001000000001000000001000000000000000000000000000000000000;
{position, d, five} ->
2#0100000000100000000100000000000000000000000000000000000000000000;
{position, d, six} ->
2#0010000000010000000000000000000000000000000000000000000000000000;
{position, d, seven} ->
2#0001000000000000000000000000000000000000000000000000000000000000;
{position, d, eight} ->
2#0000000000000000000000000000000000000000000000000000000000000000;
{position, e, one} ->
2#0000000000000000000000000000000010000000010000000010000000000000;
{position, e, two} ->
2#0000000000000000000000001000000001000000001000000000000000000000;
{position, e, three} ->
2#0000000000000000100000000100000000100000000000000000000000000000;
{position, e, four} ->
2#0000000010000000010000000010000000000000000000000000000000000000;
{position, e, five} ->
2#1000000001000000001000000000000000000000000000000000000000000000;
{position, e, six} ->
2#0100000000100000000000000000000000000000000000000000000000000000;
{position, e, seven} ->
2#0010000000000000000000000000000000000000000000000000000000000000;
{position, e, eight} ->
2#0000000000000000000000000000000000000000000000000000000000000000;
{position, f, one} ->
2#0000000000000000000000000000000000000000100000000100000000000000;
{position, f, two} ->
2#0000000000000000000000000000000010000000010000000000000000000000;
{position, f, three} ->
2#0000000000000000000000001000000001000000000000000000000000000000;
{position, f, four} ->
2#0000000000000000100000000100000000000000000000000000000000000000;
{position, f, five} ->
2#0000000010000000010000000000000000000000000000000000000000000000;
{position, f, six} ->
2#1000000001000000000000000000000000000000000000000000000000000000;
{position, f, seven} ->
2#0100000000000000000000000000000000000000000000000000000000000000;
{position, f, eight} ->
2#0000000000000000000000000000000000000000000000000000000000000000;
{position, g, one} ->
2#0000000000000000000000000000000000000000000000001000000000000000;
{position, g, two} ->
2#0000000000000000000000000000000000000000100000000000000000000000;
{position, g, three} ->
2#0000000000000000000000000000000010000000000000000000000000000000;
{position, g, four} ->
2#0000000000000000000000001000000000000000000000000000000000000000;
{position, g, five} ->
2#0000000000000000100000000000000000000000000000000000000000000000;
{position, g, six} ->
2#0000000010000000000000000000000000000000000000000000000000000000;
{position, g, seven} ->
2#1000000000000000000000000000000000000000000000000000000000000000;
{position, g, eight} ->
2#0000000000000000000000000000000000000000000000000000000000000000;
{position, h, one} ->
2#0000000000000000000000000000000000000000000000000000000010000000;
{position, h, two} ->
2#0000000000000000000000000000000000000000000000000000000000000000;
{position, h, three} ->
2#0000000000000000000000000000000000000000000000000000000000000000;
{position, h, four} ->
2#0000000000000000000000000000000000000000000000000000000000000000;
{position, h, five} ->
2#0000000000000000000000000000000000000000000000000000000000000000;
{position, h, six} ->
2#0000000000000000000000000000000000000000000000000000000000000000;
{position, h, seven} ->
2#0000000000000000000000000000000000000000000000000000000000000000;
{position, h, eight} ->
2#0000000000000000000000000000000000000000000000000000000000000000
end.
-spec look_up_north_west_ray_bb(position:position()) -> integer().
look_up_north_west_ray_bb(Origin_square) ->
case Origin_square of
{position, a, one} ->
2#0000000000000000000000000000000000000000000000000000000000000000;
{position, a, two} ->
2#0000000000000000000000000000000000000000000000000000000000000000;
{position, a, three} ->
2#0000000000000000000000000000000000000000000000000000000000000000;
{position, a, four} ->
2#0000000000000000000000000000000000000000000000000000000000000000;
{position, a, five} ->
2#0000000000000000000000000000000000000000000000000000000000000000;
{position, a, six} ->
2#0000000000000000000000000000000000000000000000000000000000000000;
{position, a, seven} ->
2#0000000000000000000000000000000000000000000000000000000000000000;
{position, a, eight} ->
2#0000000000000000000000000000000000000000000000000000000000000000;
{position, b, one} ->
2#0000000000000000000000000000000000000000000000000000000100000000;
{position, b, two} ->
2#0000000000000000000000000000000000000000000000010000000000000000;
{position, b, three} ->
2#0000000000000000000000000000000000000001000000000000000000000000;
{position, b, four} ->
2#0000000000000000000000000000000100000000000000000000000000000000;
{position, b, five} ->
2#0000000000000000000000010000000000000000000000000000000000000000;
{position, b, six} ->
2#0000000000000001000000000000000000000000000000000000000000000000;
{position, b, seven} ->
2#0000000100000000000000000000000000000000000000000000000000000000;
{position, b, eight} ->
2#0000000000000000000000000000000000000000000000000000000000000000;
{position, c, one} ->
2#0000000000000000000000000000000000000000000000010000001000000000;
{position, c, two} ->
2#0000000000000000000000000000000000000001000000100000000000000000;
{position, c, three} ->
2#0000000000000000000000000000000100000010000000000000000000000000;
{position, c, four} ->
2#0000000000000000000000010000001000000000000000000000000000000000;
{position, c, five} ->
2#0000000000000001000000100000000000000000000000000000000000000000;
{position, c, six} ->
2#0000000100000010000000000000000000000000000000000000000000000000;
{position, c, seven} ->
2#0000001000000000000000000000000000000000000000000000000000000000;
{position, c, eight} ->
2#0000000000000000000000000000000000000000000000000000000000000000;
{position, d, one} ->
2#0000000000000000000000000000000000000001000000100000010000000000;
{position, d, two} ->
2#0000000000000000000000000000000100000010000001000000000000000000;
{position, d, three} ->
2#0000000000000000000000010000001000000100000000000000000000000000;
{position, d, four} ->
2#0000000000000001000000100000010000000000000000000000000000000000;
{position, d, five} ->
2#0000000100000010000001000000000000000000000000000000000000000000;
{position, d, six} ->
2#0000001000000100000000000000000000000000000000000000000000000000;
{position, d, seven} ->
2#0000010000000000000000000000000000000000000000000000000000000000;
{position, d, eight} ->
2#0000000000000000000000000000000000000000000000000000000000000000;
{position, e, one} ->
2#0000000000000000000000000000000100000010000001000000100000000000;
{position, e, two} ->
2#0000000000000000000000010000001000000100000010000000000000000000;
{position, e, three} ->
2#0000000000000001000000100000010000001000000000000000000000000000;
{position, e, four} ->
2#0000000100000010000001000000100000000000000000000000000000000000;
{position, e, five} ->
2#0000001000000100000010000000000000000000000000000000000000000000;
{position, e, six} ->
2#0000010000001000000000000000000000000000000000000000000000000000;
{position, e, seven} ->
2#0000100000000000000000000000000000000000000000000000000000000000;
{position, e, eight} ->
2#0000000000000000000000000000000000000000000000000000000000000000;
{position, f, one} ->
2#0000000000000000000000010000001000000100000010000001000000000000;
{position, f, two} ->
2#0000000000000001000000100000010000001000000100000000000000000000;
{position, f, three} ->
2#0000000100000010000001000000100000010000000000000000000000000000;
{position, f, four} ->
2#0000001000000100000010000001000000000000000000000000000000000000;
{position, f, five} ->
2#0000010000001000000100000000000000000000000000000000000000000000;
{position, f, six} ->
2#0000100000010000000000000000000000000000000000000000000000000000;
{position, f, seven} ->
2#0001000000000000000000000000000000000000000000000000000000000000;
{position, f, eight} ->
2#0000000000000000000000000000000000000000000000000000000000000000;
{position, g, one} ->
2#0000000000000001000000100000010000001000000100000010000000000000;
{position, g, two} ->
2#0000000100000010000001000000100000010000001000000000000000000000;
{position, g, three} ->
2#0000001000000100000010000001000000100000000000000000000000000000;
{position, g, four} ->
2#0000010000001000000100000010000000000000000000000000000000000000;
{position, g, five} ->
2#0000100000010000001000000000000000000000000000000000000000000000;
{position, g, six} ->
2#0001000000100000000000000000000000000000000000000000000000000000;
{position, g, seven} ->
2#0010000000000000000000000000000000000000000000000000000000000000;
{position, g, eight} ->
2#0000000000000000000000000000000000000000000000000000000000000000;
{position, h, one} ->
2#0000000100000010000001000000100000010000001000000100000000000000;
{position, h, two} ->
2#0000001000000100000010000001000000100000010000000000000000000000;
{position, h, three} ->
2#0000010000001000000100000010000001000000000000000000000000000000;
{position, h, four} ->
2#0000100000010000001000000100000000000000000000000000000000000000;
{position, h, five} ->
2#0001000000100000010000000000000000000000000000000000000000000000;
{position, h, six} ->
2#0010000001000000000000000000000000000000000000000000000000000000;
{position, h, seven} ->
2#0100000000000000000000000000000000000000000000000000000000000000;
{position, h, eight} ->
2#0000000000000000000000000000000000000000000000000000000000000000
end.
-spec occupied_squares(board:board_bb()) -> integer().
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,
0,
fun(Collector, Next) -> bitboard:'or'(Collector, Next) end
).
-spec occupied_squares_white(board:board_bb()) -> integer().
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,
0,
fun(Collector, Next) -> bitboard:'or'(Collector, Next) end
).
-spec occupied_squares_black(board:board_bb()) -> integer().
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,
0,
fun(Collector, Next) -> bitboard:'or'(Collector, Next) end
).
-spec pawn_squares(color:color(), board:board_bb()) -> integer().
pawn_squares(Color, Board) ->
case Color of
white ->
erlang:element(13, Board);
black ->
erlang:element(7, Board)
end.
-spec generate_queen_pseudo_legal_move_list(color:color(), game()) -> {ok,
list(move:move())} |
{error, binary()}.
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,
gleam@result:'try'(
board:get_positions(Queen_bitboard),
fun(Queen_origin_squares) ->
gleam@list:fold(
Queen_origin_squares,
{ok, []},
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
{error, _} ->
0;
{ok, Position} ->
look_up_south_ray_bb(Position)
end,
First_blocker_east_mask_bb = case First_blocker_east of
{error, _} ->
0;
{ok, Position@1} ->
look_up_east_ray_bb(Position@1)
end,
First_blocker_north_mask_bb = case First_blocker_north of
{error, _} ->
0;
{ok, Position@2} ->
look_up_north_ray_bb(Position@2)
end,
First_blocker_west_mask_bb = case First_blocker_west of
{error, _} ->
0;
{ok, 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],
{ok, []},
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,
gleam@result:'try'(
board:get_positions(Rook_simple_moves),
fun(Rook_simple_moves_positions) ->
Simple_moves = gleam@list:map(
Rook_simple_moves_positions,
fun(Dest) ->
{normal,
Queen_origin_square,
Dest,
none}
end
),
gleam@result:'try'(
board:get_positions(Captures),
fun(Captures_positions) ->
Captures@1 = gleam@list:map(
Captures_positions,
fun(Dest@1) ->
{normal,
Queen_origin_square,
Dest@1,
none}
end
),
gleam@result:'try'(
Collector@1,
fun(Collector@2) ->
Simple_moves@1 = gleam@list:append(
Collector@2,
Simple_moves
),
All_moves = gleam@list:append(
Simple_moves@1,
Captures@1
),
{ok, All_moves}
end
)
end
)
end
)
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
{error, _} ->
0;
{ok, Position@4} ->
look_up_south_west_ray_bb(Position@4)
end,
First_blocker_south_east_mask_bb = case First_blocker_south_east of
{error, _} ->
0;
{ok, Position@5} ->
look_up_south_east_ray_bb(Position@5)
end,
First_blocker_north_east_mask_bb = case First_blocker_north_east of
{error, _} ->
0;
{ok, Position@6} ->
look_up_north_east_ray_bb(Position@6)
end,
First_blocker_north_west_mask_bb = case First_blocker_north_west of
{error, _} ->
0;
{ok, 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],
{ok, []},
fun(Collector@3, 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,
gleam@result:'try'(
board:get_positions(Rook_simple_moves@1),
fun(Rook_simple_moves_positions@1) ->
Simple_moves@2 = gleam@list:map(
Rook_simple_moves_positions@1,
fun(Dest@2) ->
{normal,
Queen_origin_square,
Dest@2,
none}
end
),
gleam@result:'try'(
board:get_positions(Captures@2),
fun(Captures_positions@1) ->
Captures@3 = gleam@list:map(
Captures_positions@1,
fun(Dest@3) ->
{normal,
Queen_origin_square,
Dest@3,
none}
end
),
gleam@result:'try'(
Collector@3,
fun(Collector@4) ->
Simple_moves@3 = gleam@list:append(
Collector@4,
Simple_moves@2
),
All_moves@1 = gleam@list:append(
Simple_moves@3,
Captures@3
),
{ok, All_moves@1}
end
)
end
)
end
)
end
),
gleam@result:'try'(
Rook_moves,
fun(Rook_moves@1) ->
gleam@result:'try'(
Bishop_moves,
fun(Bishop_moves@1) ->
gleam@result:'try'(
Collector,
fun(Collector@5) ->
All_moves@2 = gleam@list:append(
gleam@list:append(
Collector@5,
Rook_moves@1
),
Bishop_moves@1
),
{ok, All_moves@2}
end
)
end
)
end
)
end
)
end
).
-spec generate_rook_pseudo_legal_move_list(color:color(), game()) -> {ok,
list(move:move())} |
{error, binary()}.
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,
gleam@result:'try'(
board:get_positions(Rook_bitboard),
fun(Rook_origin_squares) ->
gleam@list:fold(
Rook_origin_squares,
{ok, []},
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
{error, _} ->
0;
{ok, Position} ->
look_up_south_ray_bb(Position)
end,
First_blocker_east_mask_bb = case First_blocker_east of
{error, _} ->
0;
{ok, Position@1} ->
look_up_east_ray_bb(Position@1)
end,
First_blocker_north_mask_bb = case First_blocker_north of
{error, _} ->
0;
{ok, Position@2} ->
look_up_north_ray_bb(Position@2)
end,
First_blocker_west_mask_bb = case First_blocker_west of
{error, _} ->
0;
{ok, 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],
{ok, []},
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,
gleam@result:'try'(
board:get_positions(Rook_simple_moves),
fun(Rook_simple_moves_positions) ->
Simple_moves = gleam@list:map(
Rook_simple_moves_positions,
fun(Dest) ->
{normal,
Rook_origin_square,
Dest,
none}
end
),
gleam@result:'try'(
board:get_positions(Rook_captures),
fun(Rook_captures_positions) ->
Captures = gleam@list:map(
Rook_captures_positions,
fun(Dest@1) ->
{normal,
Rook_origin_square,
Dest@1,
none}
end
),
gleam@result:'try'(
Collector@1,
fun(Collector@2) ->
Simple_moves@1 = gleam@list:append(
Collector@2,
Simple_moves
),
All_moves = gleam@list:append(
Simple_moves@1,
Captures
),
{ok, All_moves}
end
)
end
)
end
)
end
),
gleam@result:'try'(
Rook_moves,
fun(Rook_moves@1) ->
gleam@result:'try'(
Collector,
fun(Collector@3) ->
{ok,
gleam@list:append(
Collector@3,
Rook_moves@1
)}
end
)
end
)
end
)
end
).
-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
0 ->
none;
_ when Position_white_king =/= 0 ->
{some, {piece, white, king}};
_ when Position_white_queen =/= 0 ->
{some, {piece, white, queen}};
_ when Position_white_rook =/= 0 ->
{some, {piece, white, rook}};
_ when Position_white_bishop =/= 0 ->
{some, {piece, white, bishop}};
_ when Position_white_knight =/= 0 ->
{some, {piece, white, knight}};
_ when Position_white_pawn =/= 0 ->
{some, {piece, white, pawn}};
_ when Position_black_king =/= 0 ->
{some, {piece, black, king}};
_ when Position_black_queen =/= 0 ->
{some, {piece, black, queen}};
_ when Position_black_rook =/= 0 ->
{some, {piece, black, rook}};
_ when Position_black_bishop =/= 0 ->
{some, {piece, black, bishop}};
_ when Position_black_knight =/= 0 ->
{some, {piece, black, knight}};
_ when Position_black_pawn =/= 0 ->
{some, {piece, black, pawn}};
_ ->
erlang:error(#{gleam_error => panic,
message => <<"panic expression evaluated"/utf8>>,
module => <<"game"/utf8>>,
function => <<"piece_at_position"/utf8>>,
line => 2583})
end.
-spec apply_move_raw(game(), move:move()) -> {ok, game()} | {error, binary()}.
apply_move_raw(Game, Move) ->
case Move of
{normal, From, To, Promo_piece} ->
gleam@result:'try'(
case board:get_piece_at_position(erlang:element(2, Game), From) of
{some, Piece} ->
{ok, Piece};
none ->
{error, <<"No piece at from position"/utf8>>}
end,
fun(Moving_piece) ->
Captured_piece = piece_at_position(Game, To),
gleam@result:'try'(
board:remove_piece_at_position(
erlang:element(2, Game),
From
),
fun(New_board) ->
New_game_state = erlang:setelement(
2,
Game,
New_board
),
gleam@result:'try'(case Captured_piece of
none ->
{ok, New_game_state};
{some, _} ->
gleam@result:'try'(
board:remove_piece_at_position(
erlang:element(
2,
New_game_state
),
To
),
fun(New_board@1) ->
{ok,
erlang:setelement(
2,
New_game_state,
New_board@1
)}
end
)
end, fun(New_game_state@1) ->
New_game_state@2 = case Promo_piece of
none ->
erlang:setelement(
2,
New_game_state@1,
board:set_piece_at_position(
erlang:element(
2,
New_game_state@1
),
To,
Moving_piece
)
);
{some, Promo_piece@1} ->
erlang:setelement(
2,
New_game_state@1,
board:set_piece_at_position(
erlang:element(
2,
New_game_state@1
),
To,
Promo_piece@1
)
)
end,
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),
Move_with_capture = {move_with_capture,
Move,
Captured_piece},
New_history = [Move_with_capture |
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_game_state@3 = erlang:setelement(
11,
erlang:setelement(
10,
erlang:setelement(
9,
erlang:setelement(
8,
erlang:setelement(
7,
erlang:setelement(
6,
erlang:setelement(
4,
erlang:setelement(
3,
New_game_state@2,
New_turn
),
New_history
),
New_ply
),
New_white_king_castle
),
New_white_queen_castle
),
New_black_king_castle
),
New_black_queen_castle
),
New_en_passant
),
{ok, New_game_state@3}
end)
end
)
end
);
{castle, From@1, To@1} ->
gleam@result:'try'(
board:remove_piece_at_position(erlang:element(2, Game), From@1),
fun(New_board@2) ->
New_game_state@4 = erlang:setelement(2, Game, New_board@2),
New_game_state@5 = erlang:setelement(
2,
New_game_state@4,
board:set_piece_at_position(
erlang:element(2, New_game_state@4),
To@1,
{piece, erlang:element(3, New_game_state@4), king}
)
),
gleam@result:'try'(case To@1 of
{position, g, one} ->
{ok, {position, f, one}};
{position, g, eight} ->
{ok, {position, f, eight}};
{position, c, one} ->
{ok, {position, d, one}};
{position, c, eight} ->
{ok, {position, d, eight}};
_ ->
{error, <<"Invalid castle move"/utf8>>}
end, fun(Rook_castling_target_square) ->
New_turn@1 = (case erlang:element(3, Game) of
white ->
black;
black ->
white
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_target_square,
{piece, erlang:element(3, Game), rook}
)
),
gleam@result:'try'(case To@1 of
{position, g, one} ->
{ok, {position, h, one}};
{position, g, eight} ->
{ok, {position, h, eight}};
{position, c, one} ->
{ok, {position, a, one}};
{position, c, eight} ->
{ok, {position, a, eight}};
_ ->
{error, <<"Invalid castle move"/utf8>>}
end, fun(Rook_castling_origin_square) ->
gleam@result:'try'(
board:remove_piece_at_position(
erlang:element(2, New_game_state@6),
Rook_castling_origin_square
),
fun(New_board@3) ->
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,
gleam@result:'try'(
case erlang:element(3, Game) of
white ->
{ok,
{{no, New_ply@1},
{no, New_ply@1},
erlang:element(
9,
Game
),
erlang:element(
10,
Game
)}};
black ->
{ok,
{erlang:element(
7,
Game
),
erlang:element(
8,
Game
),
{no, New_ply@1},
{no, New_ply@1}}}
end,
fun(_use0) ->
{New_white_king_castle@1,
New_white_queen_castle@1,
New_black_king_castle@1,
New_black_queen_castle@1} = _use0,
Move_with_capture@1 = {move_with_capture,
Move,
none},
New_history@1 = [Move_with_capture@1 |
erlang:element(4, Game)],
New_en_passant@1 = none,
New_game_state@8 = erlang:setelement(
10,
erlang:setelement(
9,
erlang:setelement(
8,
erlang:setelement(
7,
erlang:setelement(
11,
erlang:setelement(
6,
erlang:setelement(
4,
erlang:setelement(
3,
New_game_state@7,
New_turn@1
),
New_history@1
),
New_ply@1
),
New_en_passant@1
),
New_white_king_castle@1
),
New_white_queen_castle@1
),
New_black_king_castle@1
),
New_black_queen_castle@1
),
{ok, New_game_state@8}
end
)
end
)
end)
end)
end
);
{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}
)
),
gleam@result:'try'(
board:remove_piece_at_position(
erlang:element(2, New_game_state@9),
From@2
),
fun(New_board@4) ->
New_game_state@10 = erlang:setelement(
2,
New_game_state@9,
New_board@4
),
gleam@result:'try'(case To@2 of
{position, a, three} ->
{ok, {position, a, four}};
{position, a, six} ->
{ok, {position, a, five}};
{position, b, three} ->
{ok, {position, b, four}};
{position, b, six} ->
{ok, {position, b, five}};
{position, c, three} ->
{ok, {position, c, four}};
{position, c, six} ->
{ok, {position, c, five}};
{position, d, three} ->
{ok, {position, d, four}};
{position, d, six} ->
{ok, {position, d, five}};
{position, e, three} ->
{ok, {position, e, four}};
{position, e, six} ->
{ok, {position, e, five}};
{position, f, three} ->
{ok, {position, f, four}};
{position, f, six} ->
{ok, {position, f, five}};
{position, g, three} ->
{ok, {position, g, four}};
{position, g, six} ->
{ok, {position, g, five}};
{position, h, three} ->
{ok, {position, h, four}};
{position, h, six} ->
{ok, {position, h, five}};
_ ->
{error, <<"Invalid en passant move"/utf8>>}
end, fun(Captured_pawn_square) ->
gleam@result:'try'(
case board:remove_piece_at_position(
erlang:element(2, New_game_state@10),
Captured_pawn_square
) of
{ok, New_board@5} ->
{ok, New_board@5};
{error, _} ->
{error,
<<"Invalid en passant move"/utf8>>}
end,
fun(New_board@6) ->
New_ply@2 = erlang:element(
6,
New_game_state@10
)
+ 1,
New_turn@2 = (case erlang:element(3, Game) of
white ->
black;
black ->
white
end),
New_game_state@11 = erlang:setelement(
2,
New_game_state@10,
New_board@6
),
Move_with_capture@2 = {move_with_capture,
Move,
{some, {piece, New_turn@2, pawn}}},
New_history@2 = [Move_with_capture@2 |
erlang:element(4, Game)],
New_en_passant@2 = none,
New_game_state@12 = erlang:setelement(
11,
erlang:setelement(
6,
erlang:setelement(
3,
erlang:setelement(
4,
New_game_state@11,
New_history@2
),
New_turn@2
),
New_ply@2
),
New_en_passant@2
),
{ok, New_game_state@12}
end
)
end)
end
)
end.
-spec generate_bishop_pseudo_legal_move_list(color:color(), game()) -> {ok,
list(move:move())} |
{error, binary()}.
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,
gleam@result:'try'(
board:get_positions(Bishop_bitboard),
fun(Bishop_origin_squares) ->
gleam@list:fold(
Bishop_origin_squares,
{ok, []},
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
{error, _} ->
0;
{ok, Position} ->
look_up_south_west_ray_bb(Position)
end,
First_blocker_south_east_mask_bb = case First_blocker_south_east of
{error, _} ->
0;
{ok, Position@1} ->
look_up_south_east_ray_bb(Position@1)
end,
First_blocker_north_east_mask_bb = case First_blocker_north_east of
{error, _} ->
0;
{ok, Position@2} ->
look_up_north_east_ray_bb(Position@2)
end,
First_blocker_north_west_mask_bb = case First_blocker_north_west of
{error, _} ->
0;
{ok, 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],
{ok, []},
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,
gleam@result:'try'(
board:get_positions(Rook_simple_moves),
fun(Rook_simple_moves_positions) ->
gleam@result:'try'(
board:get_positions(Captures),
fun(Captures_positions) ->
Simple_moves = gleam@list:map(
Rook_simple_moves_positions,
fun(Dest) ->
{normal,
Bishop_origin_square,
Dest,
none}
end
),
Captures@1 = gleam@list:map(
Captures_positions,
fun(Dest@1) ->
{normal,
Bishop_origin_square,
Dest@1,
none}
end
),
gleam@result:'try'(
Collector@1,
fun(Collector@2) ->
Simple_moves@1 = gleam@list:append(
Collector@2,
Simple_moves
),
All_moves = gleam@list:append(
Simple_moves@1,
Captures@1
),
{ok, All_moves}
end
)
end
)
end
)
end
),
gleam@result:'try'(
Bishop_moves,
fun(Bishop_moves@1) ->
gleam@result:'try'(
Collector,
fun(Collector@3) ->
{ok,
gleam@list:append(
Collector@3,
Bishop_moves@1
)}
end
)
end
)
end
)
end
).
-spec generate_pawn_non_capture_move_bitboard(color:color(), game()) -> integer().
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,
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,
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 bitboard_repr_to_map_repr(board:board_bb()) -> {ok,
gleam@dict:dict(position:position(), gleam@option:option(piece:piece()))} |
{error, binary()}.
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 = maps: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}]
),
gleam@result:'try'(
board:get_positions(White_king_bitboard),
fun(White_king_positions) ->
gleam@result:'try'(
board:get_positions(White_queen_bitboard),
fun(White_queen_positions) ->
gleam@result:'try'(
board:get_positions(White_rook_bitboard),
fun(White_rook_positions) ->
gleam@result:'try'(
board:get_positions(White_bishop_bitboard),
fun(White_bishop_positions) ->
gleam@result:'try'(
board:get_positions(
White_knight_bitboard
),
fun(White_knight_positions) ->
gleam@result:'try'(
board:get_positions(
White_pawns_bitboard
),
fun(White_pawns_positions) ->
gleam@result:'try'(
board:get_positions(
Black_king_bitboard
),
fun(
Black_king_positions
) ->
gleam@result:'try'(
board:get_positions(
Black_queen_bitboard
),
fun(
Black_queen_positions
) ->
gleam@result:'try'(
board:get_positions(
Black_rook_bitboard
),
fun(
Black_rook_positions
) ->
gleam@result:'try'(
board:get_positions(
Black_bishop_bitboard
),
fun(
Black_bishop_positions
) ->
gleam@result:'try'(
board:get_positions(
Black_knight_bitboard
),
fun(
Black_knight_positions
) ->
gleam@result:'try'(
board:get_positions(
Black_pawns_bitboard
),
fun(
Black_pawns_positions
) ->
Board_map@2 = gleam@list:fold(
White_king_positions,
Board_map,
fun(
Board_map@1,
Position
) ->
gleam@dict: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@dict: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@dict: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@dict: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@dict: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@dict: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@dict: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@dict: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@dict: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@dict: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@dict: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@dict:insert(
Board_map@23,
Position@11,
{some,
{piece,
black,
pawn}}
)
end
),
{ok,
Board_map@24}
end
)
end
)
end
)
end
)
end
)
end
)
end
)
end
)
end
)
end
)
end
)
end
).
-spec disable_status(game()) -> game().
disable_status(Game) ->
erlang:setelement(5, Game, none).
-spec undo_move(game()) -> {ok, game()} | {error, binary()}.
undo_move(Game) ->
case erlang:element(5, Game) of
{some, {in_progress, _, _}} ->
case erlang:element(4, Game) of
[] ->
{ok, Game};
[Move | Rest] ->
case Move of
{move_with_capture,
{normal, From, To, Promo_piece},
Captured_piece} ->
Moving_piece = case board:get_piece_at_position(
erlang:element(2, Game),
To
) of
none ->
erlang:error(#{gleam_error => panic,
message => <<"Undoing Normal Move: Could not get piece at position"/utf8>>,
module => <<"game"/utf8>>,
function => <<"undo_move"/utf8>>,
line => 4409});
{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),
gleam@result:'try'(case Captured_piece of
none ->
gleam@result:'try'(
board:remove_piece_at_position(
erlang:element(2, Game),
To
),
fun(New_board) ->
{ok,
erlang:setelement(
2,
Game,
New_board
)}
end
);
{some, Piece@1} ->
gleam@result:'try'(
board:remove_piece_at_position(
erlang:element(2, Game),
To
),
fun(New_board@1) ->
New_board@2 = board:set_piece_at_position(
New_board@1,
To,
Piece@1
),
{ok,
erlang:setelement(
2,
Game,
New_board@2
)}
end
)
end, fun(New_game_state) ->
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
{move_with_capture,
{normal,
{position, _, two},
{position, File, four},
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 => <<"Undoing Normal Move: Could not get piece at position"/utf8>>,
module => <<"game"/utf8>>,
function => <<"undo_move"/utf8>>,
line => 4527}
)
end,
case Moving_piece@2 of
{piece, _, pawn} ->
{some,
{position,
File,
three}};
_ ->
none
end;
{move_with_capture,
{normal,
{position, _, seven},
{position, File@1, five},
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 => <<"Undoing Normal Move:Could not get piece at position"/utf8>>,
module => <<"game"/utf8>>,
function => <<"undo_move"/utf8>>,
line => 4552}
)
end,
case Moving_piece@3 of
{piece, _, pawn} ->
{some,
{position,
File@1,
six}};
_ ->
none
end;
_ ->
none
end;
[Move@1 | _] ->
case Move@1 of
{move_with_capture,
{normal,
{position, _, two},
{position, File, four},
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 => <<"Undoing Normal Move: Could not get piece at position"/utf8>>,
module => <<"game"/utf8>>,
function => <<"undo_move"/utf8>>,
line => 4527}
)
end,
case Moving_piece@2 of
{piece, _, pawn} ->
{some,
{position,
File,
three}};
_ ->
none
end;
{move_with_capture,
{normal,
{position, _, seven},
{position, File@1, five},
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 => <<"Undoing Normal Move:Could not get piece at position"/utf8>>,
module => <<"game"/utf8>>,
function => <<"undo_move"/utf8>>,
line => 4552}
)
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@dict:get(
Threefold_repetition_rule,
Threefold_position
) of
{error, nil} ->
Threefold_repetition_rule;
{ok, 0} ->
gleam@dict:delete(
Threefold_repetition_rule,
Threefold_position
);
{ok, 1} ->
gleam@dict:delete(
Threefold_repetition_rule,
Threefold_position
);
{ok, Count} ->
gleam@dict: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 => <<"Undoing Normal Move: trying to undo a move in a finished game is not possible"/utf8>>,
module => <<"game"/utf8>>,
function => <<"undo_move"/utf8>>,
line => 4604})
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
),
{ok, New_game_state@2}
end);
{move_with_capture, {castle, From@1, To@1}, _} ->
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 => <<"Undoing Castle Move: Invalid castle move"/utf8>>,
module => <<"game"/utf8>>,
function => <<"undo_move"/utf8>>,
line => 4636})
end,
gleam@result:'try'(
case board:remove_piece_at_position(
erlang:element(2, Game),
Rook_castling_target_square
) of
{ok, Board} ->
{ok, Board};
{error, _} ->
{error,
<<"Undoing Castle Move: Could not remove piece at position"/utf8>>}
end,
fun(New_board@4) ->
New_game_state@3 = erlang:setelement(
2,
Game,
New_board@4
),
gleam@result:'try'(
board:remove_piece_at_position(
erlang:element(2, New_game_state@3),
To@1
),
fun(New_board@5) ->
New_game_state@4 = erlang:setelement(
2,
New_game_state@3,
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 => <<"Undoing Castle Move: Invalid castle move"/utf8>>,
module => <<"game"/utf8>>,
function => <<"undo_move"/utf8>>,
line => 4668}
)
end,
New_turn@1 = (case erlang:element(
3,
New_game_state@4
) of
white ->
black;
black ->
white
end),
New_game_state@5 = erlang:setelement(
2,
New_game_state@4,
board:set_piece_at_position(
erlang:element(
2,
New_game_state@4
),
From@1,
{piece, New_turn@1, king}
)
),
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
{move_with_capture,
{normal,
{position,
_,
two},
{position,
File@2,
four},
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 => <<"Undoing Castle Move: could not get piece at position 1"/utf8>>,
module => <<"game"/utf8>>,
function => <<"undo_move"/utf8>>,
line => 4767}
)
end,
case Moving_piece@4 of
{piece, _, pawn} ->
{some,
{position,
File@2,
three}};
_ ->
none
end;
{move_with_capture,
{normal,
{position,
_,
seven},
{position,
File@3,
five},
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 => <<"Undoing Castle Move: could not get piece at position 2"/utf8>>,
module => <<"game"/utf8>>,
function => <<"undo_move"/utf8>>,
line => 4792}
)
end,
case Moving_piece@5 of
{piece, _, pawn} ->
{some,
{position,
File@3,
six}};
_ ->
none
end;
_ ->
none
end;
[Move@2 | _] ->
case Move@2 of
{move_with_capture,
{normal,
{position,
_,
two},
{position,
File@2,
four},
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 => <<"Undoing Castle Move: could not get piece at position 1"/utf8>>,
module => <<"game"/utf8>>,
function => <<"undo_move"/utf8>>,
line => 4767}
)
end,
case Moving_piece@4 of
{piece, _, pawn} ->
{some,
{position,
File@2,
three}};
_ ->
none
end;
{move_with_capture,
{normal,
{position,
_,
seven},
{position,
File@3,
five},
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 => <<"Undoing Castle Move: could not get piece at position 2"/utf8>>,
module => <<"game"/utf8>>,
function => <<"undo_move"/utf8>>,
line => 4792}
)
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 => <<"Undoing Castle Move: Trying to undo a move in a finished game"/utf8>>,
module => <<"game"/utf8>>,
function => <<"undo_move"/utf8>>,
line => 4820}
)
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
),
{ok, New_game_state@7}
end
)
end
);
{move_with_capture, {en_passant, From@2, To@2}, _} ->
gleam@result:'try'(
board:remove_piece_at_position(
erlang:element(2, Game),
To@2
),
fun(New_board@6) ->
New_game_state@8 = erlang:setelement(
2,
Game,
New_board@6
),
New_game_state@9 = case erlang:element(
3,
Game
) of
black ->
erlang:setelement(
2,
New_game_state@8,
board:set_piece_at_position(
erlang:element(
2,
New_game_state@8
),
From@2,
{piece, white, pawn}
)
);
white ->
erlang:setelement(
2,
New_game_state@8,
board:set_piece_at_position(
erlang:element(
2,
New_game_state@8
),
From@2,
{piece, black, pawn}
)
)
end,
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),
five},
{piece, black, 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),
four},
{piece, white, 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 => <<"Undoing En Passant Move: Trying to undo a move in a finished game"/utf8>>,
module => <<"game"/utf8>>,
function => <<"undo_move"/utf8>>,
line => 4962})
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}
),
{ok, New_game_state@11}
end
)
end
end;
none ->
case erlang:element(4, Game) of
[] ->
{ok, Game};
[Move | Rest] ->
case Move of
{move_with_capture,
{normal, From, To, Promo_piece},
Captured_piece} ->
Moving_piece = case board:get_piece_at_position(
erlang:element(2, Game),
To
) of
none ->
erlang:error(#{gleam_error => panic,
message => <<"Undoing Normal Move: Could not get piece at position"/utf8>>,
module => <<"game"/utf8>>,
function => <<"undo_move"/utf8>>,
line => 4409});
{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),
gleam@result:'try'(case Captured_piece of
none ->
gleam@result:'try'(
board:remove_piece_at_position(
erlang:element(2, Game),
To
),
fun(New_board) ->
{ok,
erlang:setelement(
2,
Game,
New_board
)}
end
);
{some, Piece@1} ->
gleam@result:'try'(
board:remove_piece_at_position(
erlang:element(2, Game),
To
),
fun(New_board@1) ->
New_board@2 = board:set_piece_at_position(
New_board@1,
To,
Piece@1
),
{ok,
erlang:setelement(
2,
Game,
New_board@2
)}
end
)
end, fun(New_game_state) ->
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
{move_with_capture,
{normal,
{position, _, two},
{position, File, four},
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 => <<"Undoing Normal Move: Could not get piece at position"/utf8>>,
module => <<"game"/utf8>>,
function => <<"undo_move"/utf8>>,
line => 4527}
)
end,
case Moving_piece@2 of
{piece, _, pawn} ->
{some,
{position,
File,
three}};
_ ->
none
end;
{move_with_capture,
{normal,
{position, _, seven},
{position, File@1, five},
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 => <<"Undoing Normal Move:Could not get piece at position"/utf8>>,
module => <<"game"/utf8>>,
function => <<"undo_move"/utf8>>,
line => 4552}
)
end,
case Moving_piece@3 of
{piece, _, pawn} ->
{some,
{position,
File@1,
six}};
_ ->
none
end;
_ ->
none
end;
[Move@1 | _] ->
case Move@1 of
{move_with_capture,
{normal,
{position, _, two},
{position, File, four},
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 => <<"Undoing Normal Move: Could not get piece at position"/utf8>>,
module => <<"game"/utf8>>,
function => <<"undo_move"/utf8>>,
line => 4527}
)
end,
case Moving_piece@2 of
{piece, _, pawn} ->
{some,
{position,
File,
three}};
_ ->
none
end;
{move_with_capture,
{normal,
{position, _, seven},
{position, File@1, five},
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 => <<"Undoing Normal Move:Could not get piece at position"/utf8>>,
module => <<"game"/utf8>>,
function => <<"undo_move"/utf8>>,
line => 4552}
)
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@dict:get(
Threefold_repetition_rule,
Threefold_position
) of
{error, nil} ->
Threefold_repetition_rule;
{ok, 0} ->
gleam@dict:delete(
Threefold_repetition_rule,
Threefold_position
);
{ok, 1} ->
gleam@dict:delete(
Threefold_repetition_rule,
Threefold_position
);
{ok, Count} ->
gleam@dict: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 => <<"Undoing Normal Move: trying to undo a move in a finished game is not possible"/utf8>>,
module => <<"game"/utf8>>,
function => <<"undo_move"/utf8>>,
line => 4604})
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
),
{ok, New_game_state@2}
end);
{move_with_capture, {castle, From@1, To@1}, _} ->
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 => <<"Undoing Castle Move: Invalid castle move"/utf8>>,
module => <<"game"/utf8>>,
function => <<"undo_move"/utf8>>,
line => 4636})
end,
gleam@result:'try'(
case board:remove_piece_at_position(
erlang:element(2, Game),
Rook_castling_target_square
) of
{ok, Board} ->
{ok, Board};
{error, _} ->
{error,
<<"Undoing Castle Move: Could not remove piece at position"/utf8>>}
end,
fun(New_board@4) ->
New_game_state@3 = erlang:setelement(
2,
Game,
New_board@4
),
gleam@result:'try'(
board:remove_piece_at_position(
erlang:element(2, New_game_state@3),
To@1
),
fun(New_board@5) ->
New_game_state@4 = erlang:setelement(
2,
New_game_state@3,
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 => <<"Undoing Castle Move: Invalid castle move"/utf8>>,
module => <<"game"/utf8>>,
function => <<"undo_move"/utf8>>,
line => 4668}
)
end,
New_turn@1 = (case erlang:element(
3,
New_game_state@4
) of
white ->
black;
black ->
white
end),
New_game_state@5 = erlang:setelement(
2,
New_game_state@4,
board:set_piece_at_position(
erlang:element(
2,
New_game_state@4
),
From@1,
{piece, New_turn@1, king}
)
),
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
{move_with_capture,
{normal,
{position,
_,
two},
{position,
File@2,
four},
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 => <<"Undoing Castle Move: could not get piece at position 1"/utf8>>,
module => <<"game"/utf8>>,
function => <<"undo_move"/utf8>>,
line => 4767}
)
end,
case Moving_piece@4 of
{piece, _, pawn} ->
{some,
{position,
File@2,
three}};
_ ->
none
end;
{move_with_capture,
{normal,
{position,
_,
seven},
{position,
File@3,
five},
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 => <<"Undoing Castle Move: could not get piece at position 2"/utf8>>,
module => <<"game"/utf8>>,
function => <<"undo_move"/utf8>>,
line => 4792}
)
end,
case Moving_piece@5 of
{piece, _, pawn} ->
{some,
{position,
File@3,
six}};
_ ->
none
end;
_ ->
none
end;
[Move@2 | _] ->
case Move@2 of
{move_with_capture,
{normal,
{position,
_,
two},
{position,
File@2,
four},
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 => <<"Undoing Castle Move: could not get piece at position 1"/utf8>>,
module => <<"game"/utf8>>,
function => <<"undo_move"/utf8>>,
line => 4767}
)
end,
case Moving_piece@4 of
{piece, _, pawn} ->
{some,
{position,
File@2,
three}};
_ ->
none
end;
{move_with_capture,
{normal,
{position,
_,
seven},
{position,
File@3,
five},
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 => <<"Undoing Castle Move: could not get piece at position 2"/utf8>>,
module => <<"game"/utf8>>,
function => <<"undo_move"/utf8>>,
line => 4792}
)
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 => <<"Undoing Castle Move: Trying to undo a move in a finished game"/utf8>>,
module => <<"game"/utf8>>,
function => <<"undo_move"/utf8>>,
line => 4820}
)
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
),
{ok, New_game_state@7}
end
)
end
);
{move_with_capture, {en_passant, From@2, To@2}, _} ->
gleam@result:'try'(
board:remove_piece_at_position(
erlang:element(2, Game),
To@2
),
fun(New_board@6) ->
New_game_state@8 = erlang:setelement(
2,
Game,
New_board@6
),
New_game_state@9 = case erlang:element(
3,
Game
) of
black ->
erlang:setelement(
2,
New_game_state@8,
board:set_piece_at_position(
erlang:element(
2,
New_game_state@8
),
From@2,
{piece, white, pawn}
)
);
white ->
erlang:setelement(
2,
New_game_state@8,
board:set_piece_at_position(
erlang:element(
2,
New_game_state@8
),
From@2,
{piece, black, pawn}
)
)
end,
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),
five},
{piece, black, 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),
four},
{piece, white, 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 => <<"Undoing En Passant Move: Trying to undo a move in a finished game"/utf8>>,
module => <<"game"/utf8>>,
function => <<"undo_move"/utf8>>,
line => 4962})
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}
),
{ok, New_game_state@11}
end
)
end
end;
{some, _} ->
{ok, Game}
end.
-spec print_board(game()) -> {ok, binary()} | {error, binary()}.
print_board(Game) ->
gleam@result:'try'(
bitboard_repr_to_map_repr(erlang:element(2, Game)),
fun(Board_map) ->
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@dict: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>>),
{ok, <<"Successfully Printed Board"/utf8>>}
end
).
-spec print_board_from_fen(binary()) -> {ok, binary()} | {error, binary()}.
print_board_from_fen(Fen) ->
Parsed_fen = fen:from_string(Fen),
gleam@result:'try'(
bitboard_repr_to_map_repr(erlang:element(2, Parsed_fen)),
fun(Board_map) ->
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@dict: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>>),
{ok, <<"Successfully printed board"/utf8>>}
end
).
-spec generate_en_passant_pseudo_legal_move_list(color:color(), game()) -> {ok,
list(move:move())} |
{error, binary()}.
generate_en_passant_pseudo_legal_move_list(Color, Game) ->
case erlang:element(11, Game) of
none ->
{ok, []};
{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
),
2#1111111011111110111111101111111011111110111111101111111011111110
),
East_west_attacker_bb = bitboard:'and'(
bitboard:'and'(
bitboard:shift_right(Ep_bitboard, 9),
Pawn_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
),
2#0111111101111111011111110111111101111111011111110111111101111111
),
East_west_attacker_bb@1 = bitboard:'and'(
bitboard:'and'(
bitboard:shift_left(Ep_bitboard, 9),
Pawn_bitboard
),
2#1111111011111110111111101111111011111110111111101111111011111110
),
bitboard:'or'(
West_east_attacker_bb@1,
East_west_attacker_bb@1
)
end,
gleam@result:'try'(
board:get_positions(Ep_attacker_bitboard),
fun(Ep_attacker_positions) ->
Ep_moves = gleam@list:map(
Ep_attacker_positions,
fun(Position) -> {en_passant, Position, Ep_position} end
),
{ok, Ep_moves}
end
)
end.
-spec generate_king_pseudo_legal_move_list(color:color(), game()) -> {ok,
list(move:move())} |
{error, binary()}.
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,
gleam@result:'try'(
board:get_positions(King_bitboard),
fun(King_origin_squares) ->
gleam@list:fold(
King_origin_squares,
{ok, []},
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),
2#1111111011111110111111101111111011111110111111101111111011111110
),
bitboard:'and'(
bitboard:shift_left(King_bitboard@1, 7),
2#0111111101111111011111110111111101111111011111110111111101111111
)
),
South_west_south_east_target_squares = bitboard:'or'(
bitboard:'and'(
bitboard:shift_right(King_bitboard@1, 9),
2#0111111101111111011111110111111101111111011111110111111101111111
),
bitboard:'and'(
bitboard:shift_right(King_bitboard@1, 7),
2#1111111011111110111111101111111011111110111111101111111011111110
)
),
West_east_target_squares = bitboard:'or'(
bitboard:'and'(
bitboard:shift_left(King_bitboard@1, 1),
2#1111111011111110111111101111111011111110111111101111111011111110
),
bitboard:'and'(
bitboard:shift_right(King_bitboard@1, 1),
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,
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,
gleam@result:'try'(
board:get_positions(Simple_moves),
fun(Simple_moves_positions) ->
Simple_moves@1 = gleam@list:map(
Simple_moves_positions,
fun(Dest) -> {normal, Origin, Dest, none} end
),
gleam@result:'try'(
board:get_positions(Captures),
fun(Captures_positions) ->
Captures@1 = gleam@list:map(
Captures_positions,
fun(Dest@1) ->
{normal, Origin, Dest@1, none}
end
),
All_moves = gleam@list:append(
Simple_moves@1,
Captures@1
),
gleam@result:'try'(
Collector,
fun(Collector@2) ->
{ok,
gleam@list:append(
Collector@2,
All_moves
)}
end
)
end
)
end
)
end
)
end
).
-spec generate_knight_pseudo_legal_move_list(color:color(), game()) -> {ok,
list(move:move())} |
{error, binary()}.
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,
gleam@result:'try'(
board:get_positions(Knight_bitboard),
fun(Knight_origin_squares) ->
gleam@list:fold(
Knight_origin_squares,
{ok, []},
fun(Collector, Origin) ->
Knight_bitboard@1 = board:from_position(Origin),
North_target_squares = bitboard:'or'(
bitboard:'and'(
bitboard:shift_left(Knight_bitboard@1, 17),
2#1111111011111110111111101111111011111110111111101111111011111110
),
bitboard:'and'(
bitboard:shift_left(Knight_bitboard@1, 15),
2#0111111101111111011111110111111101111111011111110111111101111111
)
),
South_target_squares = bitboard:'or'(
bitboard:'and'(
bitboard:shift_right(Knight_bitboard@1, 17),
2#0111111101111111011111110111111101111111011111110111111101111111
),
bitboard:'and'(
bitboard:shift_right(Knight_bitboard@1, 15),
2#1111111011111110111111101111111011111110111111101111111011111110
)
),
West_target_squares = bitboard:'or'(
bitboard:'and'(
bitboard:'and'(
bitboard:shift_right(Knight_bitboard@1, 10),
2#0111111101111111011111110111111101111111011111110111111101111111
),
2#1011111110111111101111111011111110111111101111111011111110111111
),
bitboard:'and'(
bitboard:'and'(
bitboard:shift_left(Knight_bitboard@1, 6),
2#0111111101111111011111110111111101111111011111110111111101111111
),
2#1011111110111111101111111011111110111111101111111011111110111111
)
),
East_target_squares = bitboard:'or'(
bitboard:'and'(
bitboard:'and'(
bitboard:shift_right(Knight_bitboard@1, 6),
2#1111111011111110111111101111111011111110111111101111111011111110
),
2#1111110111111101111111011111110111111101111111011111110111111101
),
bitboard:'and'(
bitboard:'and'(
bitboard:shift_left(Knight_bitboard@1, 10),
2#1111111011111110111111101111111011111110111111101111111011111110
),
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,
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,
gleam@result:'try'(
board:get_positions(Simple_moves),
fun(Simple_moves_positions) ->
Simple_moves@1 = gleam@list:map(
Simple_moves_positions,
fun(Dest) -> {normal, Origin, Dest, none} end
),
gleam@result:'try'(
board:get_positions(Captures),
fun(Captures_positions) ->
Captures@1 = gleam@list:map(
Captures_positions,
fun(Dest@1) ->
{normal, Origin, Dest@1, none}
end
),
All_moves = gleam@list:append(
Simple_moves@1,
Captures@1
),
gleam@result:'try'(
Collector,
fun(Collector@2) ->
{ok,
gleam@list:append(
Collector@2,
All_moves
)}
end
)
end
)
end
)
end
)
end
).
-spec generate_pawn_attack_set(integer(), color:color()) -> integer().
generate_pawn_attack_set(Pawn_bitboard, Color) ->
case Color of
white ->
East_attack = bitboard:'and'(
bitboard:shift_left(Pawn_bitboard, 9),
2#1111111011111110111111101111111011111110111111101111111011111110
),
West_attack = bitboard:'and'(
bitboard:shift_left(Pawn_bitboard, 7),
2#0111111101111111011111110111111101111111011111110111111101111111
),
All_attacks = bitboard:'or'(East_attack, West_attack),
All_attacks;
black ->
East_attack@1 = bitboard:'and'(
bitboard:shift_right(Pawn_bitboard, 7),
2#1111111011111110111111101111111011111110111111101111111011111110
),
West_attack@1 = bitboard:'and'(
bitboard:shift_right(Pawn_bitboard, 9),
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()) -> {ok,
list(move:move())} |
{error, binary()}.
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,
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),
2#0111111101111111011111110111111101111111011111110111111101111111
),
West_origins = bitboard:'and'(
bitboard:shift_right(Pawn_capture_destination_set, 7),
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),
2#1111111011111110111111101111111011111110111111101111111011111110
),
East_origins@1 = bitboard:'and'(
bitboard:shift_left(Pawn_capture_destination_set, 7),
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),
gleam@result:'try'(
board:get_positions(Pawn_capture_origin_set),
fun(Pawn_capture_origin_list) ->
gleam@result:'try'(
board:get_positions(Pawn_capture_destination_set),
fun(Pawn_capture_destination_list) ->
Pawn_capture_move_list = gleam@list:fold(
Pawn_capture_origin_list,
{ok, []},
fun(Collector@1, Position) ->
gleam@result:'try'(case Color of
white ->
board:get_positions(
bitboard:'and'(
bitboard:shift_left(
position:to_bitboard(
Position
),
9
),
2#1111111011111110111111101111111011111110111111101111111011111110
)
);
black ->
board:get_positions(
bitboard:'and'(
bitboard:shift_right(
position:to_bitboard(
Position
),
7
),
2#1111111011111110111111101111111011111110111111101111111011111110
)
)
end, fun(East_attack) ->
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,
{some,
{piece,
Color,
queen}}},
{normal,
Position,
East_attack@1,
{some,
{piece,
Color,
rook}}},
{normal,
Position,
East_attack@1,
{some,
{piece,
Color,
bishop}}},
{normal,
Position,
East_attack@1,
{some,
{piece,
Color,
knight}}}];
{position, _, one} when Color =:= black ->
[{normal,
Position,
East_attack@1,
{some,
{piece,
Color,
queen}}},
{normal,
Position,
East_attack@1,
{some,
{piece,
Color,
rook}}},
{normal,
Position,
East_attack@1,
{some,
{piece,
Color,
bishop}}},
{normal,
Position,
East_attack@1,
{some,
{piece,
Color,
knight}}}];
_ ->
[{normal,
Position,
East_attack@1,
none}]
end,
East_moves
end,
East_moves@1;
_ ->
erlang:error(#{gleam_error => panic,
message => <<"panic expression evaluated"/utf8>>,
module => <<"game"/utf8>>,
function => <<"generate_pawn_capture_move_list"/utf8>>,
line => 3380})
end,
gleam@result:'try'(case Color of
white ->
board:get_positions(
bitboard:'and'(
bitboard:shift_left(
position:to_bitboard(
Position
),
7
),
2#0111111101111111011111110111111101111111011111110111111101111111
)
);
black ->
board:get_positions(
bitboard:'and'(
bitboard:shift_right(
position:to_bitboard(
Position
),
9
),
2#0111111101111111011111110111111101111111011111110111111101111111
)
)
end, fun(West_attack) ->
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,
{some,
{piece,
Color,
queen}}},
{normal,
Position,
West_attack@1,
{some,
{piece,
Color,
rook}}},
{normal,
Position,
West_attack@1,
{some,
{piece,
Color,
bishop}}},
{normal,
Position,
West_attack@1,
{some,
{piece,
Color,
knight}}}];
{position,
_,
one} when Color =:= black ->
[{normal,
Position,
West_attack@1,
{some,
{piece,
Color,
queen}}},
{normal,
Position,
West_attack@1,
{some,
{piece,
Color,
rook}}},
{normal,
Position,
West_attack@1,
{some,
{piece,
Color,
bishop}}},
{normal,
Position,
West_attack@1,
{some,
{piece,
Color,
knight}}}];
_ ->
[{normal,
Position,
West_attack@1,
none}]
end,
West_moves
end,
West_moves@1;
_ ->
erlang:error(
#{gleam_error => panic,
message => <<"panic expression evaluated"/utf8>>,
module => <<"game"/utf8>>,
function => <<"generate_pawn_capture_move_list"/utf8>>,
line => 3461}
)
end,
gleam@result:'try'(
Collector@1,
fun(Collector@2) ->
{ok,
gleam@list:append(
gleam@list:append(
Collector@2,
East_moves@2
),
West_moves@2
)}
end
)
end)
end)
end
),
Pawn_capture_move_list
end
)
end
).
-spec generate_pawn_starting_rank_double_move_bitboard(color:color(), game()) -> integer().
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)),
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,
2#0000000000000000000000000000000000000000111111110000000000000000
),
8
),
Moves
),
Moves@2 = bitboard:exclusive_or(
Moves@1,
White_pawn_target_squares@1
),
Moves@3 = bitboard:'and'(
Moves@2,
bitboard:'not'(
2#0000000000000000000000000000000000000000111111110000000000000000
)
),
Moves@3;
black ->
Black_pawn_target_squares = bitboard:'and'(
erlang:element(7, erlang:element(2, Game)),
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,
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'(
2#0000000000000000111111110000000000000000000000000000000000000000
)
),
Moves@7
end.
-spec generate_pawn_pseudo_legal_move_list(color:color(), game()) -> {ok,
list(move:move())} |
{error, binary()}.
generate_pawn_pseudo_legal_move_list(Color, Game) ->
gleam@result:'try'(
generate_pawn_capture_move_list(Color, Game),
fun(Capture_list) ->
Moves_no_captures = generate_pawn_non_capture_move_bitboard(
Color,
Game
),
gleam@result:'try'(
board:get_positions(Moves_no_captures),
fun(Non_capture_dest_list) ->
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,
{some, {piece, Color, queen}}},
{normal,
Origin,
Dest,
{some, {piece, Color, rook}}},
{normal,
Origin,
Dest,
{some, {piece, Color, bishop}}},
{normal,
Origin,
Dest,
{some, {piece, Color, knight}}}];
{position, _, one} when Color =:= black ->
[{normal,
Origin,
Dest,
{some, {piece, Color, queen}}},
{normal,
Origin,
Dest,
{some, {piece, Color, rook}}},
{normal,
Origin,
Dest,
{some, {piece, Color, bishop}}},
{normal,
Origin,
Dest,
{some, {piece, Color, knight}}}];
_ ->
[{normal, Origin, Dest, none}]
end,
gleam@list:append(Acc, Moves)
end
),
Initial_rank_double_move_list = generate_pawn_starting_rank_double_move_bitboard(
Color,
Game
),
gleam@result:'try'(
board:get_positions(Initial_rank_double_move_list),
fun(Initial_rank_double_dest_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};
b ->
{normal,
{position, b, two},
Dest@1,
none};
c ->
{normal,
{position, c, two},
Dest@1,
none};
d ->
{normal,
{position, d, two},
Dest@1,
none};
e ->
{normal,
{position, e, two},
Dest@1,
none};
f ->
{normal,
{position, f, two},
Dest@1,
none};
g ->
{normal,
{position, g, two},
Dest@1,
none};
h ->
{normal,
{position, h, two},
Dest@1,
none}
end;
black ->
case erlang:element(2, Dest@1) of
a ->
{normal,
{position, a, seven},
Dest@1,
none};
b ->
{normal,
{position, b, seven},
Dest@1,
none};
c ->
{normal,
{position, c, seven},
Dest@1,
none};
d ->
{normal,
{position, d, seven},
Dest@1,
none};
e ->
{normal,
{position, e, seven},
Dest@1,
none};
f ->
{normal,
{position, f, seven},
Dest@1,
none};
g ->
{normal,
{position, g, seven},
Dest@1,
none};
h ->
{normal,
{position, h, seven},
Dest@1,
none}
end
end end
),
{ok,
gleam@list:append(
gleam@list:append(
Capture_list,
Non_capture_move_list
),
Initial_rank_double_move_list@1
)}
end
)
end
)
end
).
-spec is_king_in_check(game(), color:color()) -> {ok, boolean()} |
{error, binary()}.
is_king_in_check(Game, Color) ->
Enemy_color = (case Color of
white ->
black;
black ->
white
end),
gleam@result:'try'(
begin
King_bb = case Color of
white ->
erlang:element(8, erlang:element(2, Game));
black ->
erlang:element(2, erlang:element(2, Game))
end,
gleam@result:'try'(case board:get_positions(King_bb) of
{ok, [King_pos]} ->
{ok, King_pos};
_ ->
{error, <<"Invalid king position"/utf8>>}
end, fun(King_pos@1) ->
Rook_bb = case Color of
white ->
erlang:element(4, erlang:element(2, Game));
black ->
erlang:element(10, erlang:element(2, Game))
end,
King_rook_ray_bb = begin
_pipe = bitboard:'or'(
look_up_east_ray_bb(King_pos@1),
look_up_west_ray_bb(King_pos@1)
),
_pipe@1 = bitboard:'or'(
_pipe,
look_up_north_ray_bb(King_pos@1)
),
bitboard:'or'(_pipe@1, look_up_south_ray_bb(King_pos@1))
end,
Viable_attacking_rook_bb = bitboard:'and'(
Rook_bb,
King_rook_ray_bb
),
gleam@result:'try'(case Viable_attacking_rook_bb of
0 ->
{ok, []};
_ ->
generate_rook_pseudo_legal_move_list(
Enemy_color,
Game
)
end, fun(Rook_move_list) ->
Bishop_bb = case Color of
white ->
erlang:element(5, erlang:element(2, Game));
black ->
erlang:element(11, erlang:element(2, Game))
end,
King_bishop_ray_bb = begin
_pipe@2 = bitboard:'or'(
look_up_north_east_ray_bb(King_pos@1),
look_up_north_west_ray_bb(King_pos@1)
),
_pipe@3 = bitboard:'or'(
_pipe@2,
look_up_south_east_ray_bb(King_pos@1)
),
bitboard:'or'(
_pipe@3,
look_up_south_west_ray_bb(King_pos@1)
)
end,
Viable_attacking_bishop_bb = bitboard:'and'(
Bishop_bb,
King_bishop_ray_bb
),
gleam@result:'try'(
case Viable_attacking_bishop_bb of
0 ->
{ok, []};
_ ->
generate_bishop_pseudo_legal_move_list(
Enemy_color,
Game
)
end,
fun(Bishop_move_list) ->
Queen_bb = case Color of
white ->
erlang:element(
3,
erlang:element(2, Game)
);
black ->
erlang:element(
9,
erlang:element(2, Game)
)
end,
King_queen_ray_bb = bitboard:'or'(
King_rook_ray_bb,
King_bishop_ray_bb
),
Viable_attacking_queen_bb = bitboard:'and'(
Queen_bb,
King_queen_ray_bb
),
gleam@result:'try'(
case Viable_attacking_queen_bb of
0 ->
{ok, []};
_ ->
generate_queen_pseudo_legal_move_list(
Enemy_color,
Game
)
end,
fun(Queen_move_list) ->
Knight_bb = case Color of
white ->
erlang:element(
6,
erlang:element(2, Game)
);
black ->
erlang:element(
12,
erlang:element(2, Game)
)
end,
King_knight_target_bb = look_up_knight_target_bb(
King_pos@1
),
Viable_attacking_knight_bb = bitboard:'and'(
Knight_bb,
King_knight_target_bb
),
gleam@result:'try'(
case Viable_attacking_knight_bb of
0 ->
{ok, []};
_ ->
generate_knight_pseudo_legal_move_list(
Enemy_color,
Game
)
end,
fun(Knight_move_list) ->
gleam@result:'try'(
generate_pawn_pseudo_legal_move_list(
Enemy_color,
Game
),
fun(Pawn_move_list) ->
gleam@result:'try'(
generate_king_pseudo_legal_move_list(
Enemy_color,
Game
),
fun(
Enemy_king_move_list
) ->
List_of_move_lists = [Rook_move_list,
Bishop_move_list,
Queen_move_list,
Knight_move_list,
Pawn_move_list,
Enemy_king_move_list],
Move_list = gleam@list:fold(
List_of_move_lists,
[],
fun(
Collector,
Next
) ->
gleam@list:append(
Collector,
Next
)
end
),
{ok,
Move_list}
end
)
end
)
end
)
end
)
end
)
end)
end)
end,
fun(Enemy_move_list) ->
gleam@result:'try'(
({ok,
begin
_pipe@4 = Enemy_move_list,
gleam@list:filter(
_pipe@4,
fun(Move) ->
Piece = piece_at_position(
Game,
erlang:element(3, Move)
),
case Piece of
none ->
false;
{some, Piece@1} ->
(erlang:element(2, Piece@1) =:= Color)
andalso (erlang:element(3, Piece@1) =:= king)
end
end
)
end}),
fun(Enemy_move_list@1) ->
{ok, gleam@list:length(Enemy_move_list@1) > 0}
end
)
end
).
-spec is_move_legal(game(), move:move()) -> {ok, boolean()} | {error, binary()}.
is_move_legal(Game, Move) ->
gleam@result:'try'(
apply_move_raw(Game, Move),
fun(New_game_state) -> case Move of
{normal, _, _, _} ->
gleam@result:'try'(
is_king_in_check(
New_game_state,
erlang:element(3, Game)
),
fun(Is_king_in_check) -> {ok, not Is_king_in_check} end
);
{en_passant, _, _} ->
gleam@result:'try'(
is_king_in_check(
New_game_state,
erlang:element(3, Game)
),
fun(Is_king_in_check) -> {ok, not Is_king_in_check} end
);
{castle, _, To} ->
gleam@result:'try'(
is_king_in_check(Game, erlang:element(3, Game)),
fun(Is_king_in_check_ok) -> case Is_king_in_check_ok of
true ->
{ok, false};
false ->
gleam@result:'try'(
is_king_in_check(
New_game_state,
erlang:element(3, Game)
),
fun(Is_king_in_check_ok@1) ->
case Is_king_in_check_ok@1 of
true ->
{ok, false};
false ->
King_castling_target_square = case To of
{position, g, one} ->
{ok,
{position,
f,
one}};
{position, g, eight} ->
{ok,
{position,
f,
eight}};
{position, c, one} ->
{ok,
{position,
d,
one}};
{position, c, eight} ->
{ok,
{position,
d,
eight}};
_ ->
{error,
<<"Invalid castle move"/utf8>>}
end,
case King_castling_target_square of
{error, _} ->
{ok, false};
{ok,
King_castling_target_square@1} ->
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@1,
{piece,
erlang:element(
3,
Game
),
king}
)
),
gleam@result:'try'(
board:remove_piece_at_position(
erlang:element(
2,
New_game_state@1
),
To
),
fun(New_board) ->
New_game_state@2 = erlang:setelement(
2,
New_game_state@1,
New_board
),
gleam@result:'try'(
is_king_in_check(
New_game_state@2,
erlang:element(
3,
Game
)
),
fun(
Is_king_in_check_ok@2
) ->
case Is_king_in_check_ok@2 of
true ->
{ok,
false};
false ->
{ok,
true}
end
end
)
end
)
end
end
end
)
end end
)
end end
).
-spec generate_castling_pseudo_legal_move_list(color:color(), game()) -> {ok,
list(move:move())} |
{error, binary()}.
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,
gleam@result:'try'(case board:get_positions(King_bitboard) of
{ok, []} ->
{error, <<"No king found on the board"/utf8>>};
{ok, [Position]} ->
{ok, Position};
_ ->
{error, <<"More than one king found on the board"/utf8>>}
end, fun(King_position) ->
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,
2#0000000100000001000000010000000100000001000000010000000100000001
),
2#0000000000000000000000000000000000000000000000000000000011111111
) of
0 ->
false;
_ ->
true
end;
black ->
case bitboard:'and'(
bitboard:'and'(
Rook_bitboard,
2#0000000100000001000000010000000100000001000000010000000100000001
),
2#1111111100000000000000000000000000000000000000000000000000000000
) of
0 ->
false;
_ ->
true
end
end,
Kingside_rook_flag = case Color of
white ->
case bitboard:'and'(
bitboard:'and'(
Rook_bitboard,
2#1000000010000000100000001000000010000000100000001000000010000000
),
2#0000000000000000000000000000000000000000000000000000000011111111
) of
0 ->
false;
_ ->
true
end;
black ->
case bitboard:'and'(
bitboard:'and'(
Rook_bitboard,
2#1000000010000000100000001000000010000000100000001000000010000000
),
2#1111111100000000000000000000000000000000000000000000000000000000
) of
0 ->
false;
_ ->
true
end
end,
Queenside_clear_flag = case Color of
white ->
case bitboard:'and'(
2#0000000000000000000000000000000000000000000000000000000000001110,
occupied_squares(erlang:element(2, Game))
) of
0 ->
true;
_ ->
false
end;
black ->
case bitboard:'and'(
2#0000111000000000000000000000000000000000000000000000000000000000,
occupied_squares(erlang:element(2, Game))
) of
0 ->
true;
_ ->
false
end
end,
Kingside_clear_flag = case Color of
white ->
case bitboard:'and'(
2#0000000000000000000000000000000000000000000000000000000001100000,
occupied_squares(erlang:element(2, Game))
) of
0 ->
true;
_ ->
false
end;
black ->
case bitboard:'and'(
2#0110000000000000000000000000000000000000000000000000000000000000,
occupied_squares(erlang:element(2, Game))
) of
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
),
{ok, Castling_moves}
end).
-spec generate_pseudo_legal_move_list(game(), color:color()) -> {ok,
list(move:move())} |
{error, binary()}.
generate_pseudo_legal_move_list(Game, Color) ->
gleam@result:'try'(
generate_queen_pseudo_legal_move_list(Color, Game),
fun(Queen_pseudo_legal_move_list) ->
gleam@result:'try'(
generate_king_pseudo_legal_move_list(Color, Game),
fun(King_pseudo_legal_move_list) ->
gleam@result:'try'(
generate_castling_pseudo_legal_move_list(Color, Game),
fun(Castling_pseudo_legal_move_list) ->
gleam@result:'try'(
generate_en_passant_pseudo_legal_move_list(
Color,
Game
),
fun(En_passant_pseudo_legal_move_list) ->
gleam@result:'try'(
generate_rook_pseudo_legal_move_list(
Color,
Game
),
fun(Rook_pseudo_legal_move_list) ->
gleam@result:'try'(
generate_pawn_pseudo_legal_move_list(
Color,
Game
),
fun(Pawn_pseudo_legal_move_list) ->
gleam@result:'try'(
generate_knight_pseudo_legal_move_list(
Color,
Game
),
fun(
Knight_pseudo_legal_move_list
) ->
gleam@result:'try'(
generate_bishop_pseudo_legal_move_list(
Color,
Game
),
fun(
Bishop_pseudo_legal_move_list
) ->
List_of_move_lists = [Rook_pseudo_legal_move_list,
Bishop_pseudo_legal_move_list,
Knight_pseudo_legal_move_list,
Pawn_pseudo_legal_move_list,
Queen_pseudo_legal_move_list,
King_pseudo_legal_move_list,
Castling_pseudo_legal_move_list,
En_passant_pseudo_legal_move_list],
Move_list = gleam@list:fold(
List_of_move_lists,
[],
fun(
Collector,
Next
) ->
gleam@list:append(
Collector,
Next
)
end
),
{ok,
Move_list}
end
)
end
)
end
)
end
)
end
)
end
)
end
)
end
).
-spec all_legal_moves(game()) -> {ok, list(move:move())} | {error, binary()}.
all_legal_moves(Game) ->
case erlang:element(5, Game) of
{some, {in_progress, _, _}} ->
Legal_moves = (gleam@result:'try'(
generate_pseudo_legal_move_list(Game, erlang:element(3, Game)),
fun(Pseudo_legal_move_list) ->
{ok,
begin
_pipe = Pseudo_legal_move_list,
gleam@list:filter(
_pipe,
fun(Move) -> case is_move_legal(Game, Move) of
{ok, Legality} ->
Legality;
{error, _} ->
false
end end
)
end}
end
)),
Legal_moves;
none ->
Legal_moves = (gleam@result:'try'(
generate_pseudo_legal_move_list(Game, erlang:element(3, Game)),
fun(Pseudo_legal_move_list) ->
{ok,
begin
_pipe = Pseudo_legal_move_list,
gleam@list:filter(
_pipe,
fun(Move) -> case is_move_legal(Game, Move) of
{ok, Legality} ->
Legality;
{error, _} ->
false
end end
)
end}
end
)),
Legal_moves;
{some, _} ->
{ok, []}
end.
-spec has_moves(game()) -> {ok, boolean()} | {error, binary()}.
has_moves(Game) ->
gleam@result:'try'(
all_legal_moves(Game),
fun(Move_list) -> {ok, not gleam@list:is_empty(Move_list)} end
).
-spec apply_move(game(), move:move()) -> {ok, game()} | {error, binary()}.
apply_move(Game, Move) ->
case erlang:element(5, Game) of
none ->
gleam@result:'try'(
(gleam@result:'try'(
generate_pseudo_legal_move_list(
Game,
erlang:element(3, Game)
),
fun(Pseudo_legal_move_list) ->
{ok,
begin
_pipe = Pseudo_legal_move_list,
gleam@list:filter(
_pipe,
fun(Move@1) ->
case is_move_legal(Game, Move@1) of
{ok, Legality} ->
Legality;
{error, _} ->
false
end
end
)
end}
end
)),
fun(Legal_moves) ->
New_game_state@1 = case gleam@list:contains(
Legal_moves,
Move
) of
true ->
New_game_state = apply_move_raw(Game, Move),
New_game_state;
false ->
{ok, Game}
end,
New_game_state@1
end
);
{some, {in_progress, _, _}} ->
gleam@result:'try'(
(gleam@result:'try'(
generate_pseudo_legal_move_list(
Game,
erlang:element(3, Game)
),
fun(Pseudo_legal_move_list@1) ->
{ok,
begin
_pipe@1 = Pseudo_legal_move_list@1,
gleam@list:filter(
_pipe@1,
fun(Move@2) ->
case is_move_legal(Game, Move@2) of
{ok, Legality@1} ->
Legality@1;
{error, _} ->
false
end
end
)
end}
end
)),
fun(Legal_moves@1) ->
New_game_state@3 = case gleam@list:contains(
Legal_moves@1,
Move
) of
true ->
New_game_state@2 = apply_move_raw(Game, Move),
New_game_state@2;
false ->
{ok, Game}
end,
gleam@result:'try'(
New_game_state@3,
fun(New_game_state@4) ->
gleam@result:'try'(
has_moves(New_game_state@4),
fun(Has_moves) ->
gleam@result:'try'(
is_king_in_check(
New_game_state@4,
erlang:element(3, New_game_state@4)
),
fun(Is_king_in_check) ->
New_game_state@6 = case [Is_king_in_check,
Has_moves] of
[true, false] ->
Winner = case erlang:element(
3,
New_game_state@4
) of
white ->
black;
black ->
white
end,
{ok,
erlang:setelement(
5,
New_game_state@4,
{some,
{win,
Winner,
<<"Checkmate"/utf8>>}}
)};
[true, true] ->
New_status@2 = case Move of
{normal, From, To, _} ->
gleam@result:'try'(
case board:get_piece_at_position(
erlang:element(
2,
Game
),
From
) of
{some,
Piece} ->
{ok,
Piece};
none ->
{error,
<<"no piece at from position"/utf8>>}
end,
fun(
Moving_piece
) ->
case erlang:element(
5,
Game
) of
none ->
{ok,
none};
{some,
{in_progress,
Fifty_move_rule,
Threefold_repetition_rule}} ->
Captured_piece = piece_at_position(
Game,
To
),
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@dict:get(
Threefold_repetition_rule,
New_threefold_position
) of
{error,
_} ->
New_threefold_repetition_rule = gleam@dict:insert(
Threefold_repetition_rule,
New_threefold_position,
1
),
{New_threefold_repetition_rule,
1};
{ok,
Count} ->
New_threefold_repetition_rule@1 = gleam@dict: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,
{ok,
New_status@1};
{some,
_} ->
{error,
<<"game is over, unable to apply moves to board"/utf8>>}
end
end
);
{castle, _, _} ->
case erlang:element(
5,
Game
) of
none ->
{ok, 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 ->
{ok,
{some,
{draw,
fifty_move_rule}}};
_ ->
{ok,
{some,
{in_progress,
New_fifty_move_rule@1,
Threefold_repetition_rule@1}}}
end;
{some, _} ->
erlang:error(
#{gleam_error => panic,
message => <<"game is over, unable to apply moves to board"/utf8>>,
module => <<"game"/utf8>>,
function => <<"apply_move"/utf8>>,
line => 3952}
)
end;
{en_passant, _, _} ->
case erlang:element(
5,
Game
) of
none ->
{ok, none};
{some,
{in_progress,
_,
Threefold_repetition_rule@2}} ->
{ok,
{some,
{in_progress,
0,
Threefold_repetition_rule@2}}};
{some, _} ->
{error,
<<"game is over, unable to apply moves to board"/utf8>>}
end
end,
gleam@result:'try'(
New_status@2,
fun(New_status@3) ->
New_game_state@5 = erlang:setelement(
5,
New_game_state@4,
New_status@3
),
{ok,
New_game_state@5}
end
);
[false, true] ->
New_status@2 = case Move of
{normal, From, To, _} ->
gleam@result:'try'(
case board:get_piece_at_position(
erlang:element(
2,
Game
),
From
) of
{some,
Piece} ->
{ok,
Piece};
none ->
{error,
<<"no piece at from position"/utf8>>}
end,
fun(
Moving_piece
) ->
case erlang:element(
5,
Game
) of
none ->
{ok,
none};
{some,
{in_progress,
Fifty_move_rule,
Threefold_repetition_rule}} ->
Captured_piece = piece_at_position(
Game,
To
),
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@dict:get(
Threefold_repetition_rule,
New_threefold_position
) of
{error,
_} ->
New_threefold_repetition_rule = gleam@dict:insert(
Threefold_repetition_rule,
New_threefold_position,
1
),
{New_threefold_repetition_rule,
1};
{ok,
Count} ->
New_threefold_repetition_rule@1 = gleam@dict: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,
{ok,
New_status@1};
{some,
_} ->
{error,
<<"game is over, unable to apply moves to board"/utf8>>}
end
end
);
{castle, _, _} ->
case erlang:element(
5,
Game
) of
none ->
{ok, 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 ->
{ok,
{some,
{draw,
fifty_move_rule}}};
_ ->
{ok,
{some,
{in_progress,
New_fifty_move_rule@1,
Threefold_repetition_rule@1}}}
end;
{some, _} ->
erlang:error(
#{gleam_error => panic,
message => <<"game is over, unable to apply moves to board"/utf8>>,
module => <<"game"/utf8>>,
function => <<"apply_move"/utf8>>,
line => 3952}
)
end;
{en_passant, _, _} ->
case erlang:element(
5,
Game
) of
none ->
{ok, none};
{some,
{in_progress,
_,
Threefold_repetition_rule@2}} ->
{ok,
{some,
{in_progress,
0,
Threefold_repetition_rule@2}}};
{some, _} ->
{error,
<<"game is over, unable to apply moves to board"/utf8>>}
end
end,
gleam@result:'try'(
New_status@2,
fun(New_status@3) ->
New_game_state@5 = erlang:setelement(
5,
New_game_state@4,
New_status@3
),
{ok,
New_game_state@5}
end
);
[false, false] ->
{ok,
erlang:setelement(
5,
New_game_state@4,
{some,
{draw,
stalemate}}
)};
_ ->
{error,
<<"This panic should be unreachable"/utf8>>}
end,
New_game_state@6
end
)
end
)
end
)
end
);
{some, _} ->
{error, <<"Game is over, unable to apply moves to board"/utf8>>}
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 = (gleam@result:'try'(
all_legal_moves(Game),
fun(All_legal_moves_ok) ->
Potential_moves = gleam@list:filter(
All_legal_moves_ok,
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 => <<"This panic should be unreachable"/utf8>>,
module => <<"game"/utf8>>,
function => <<"apply_move_san_string"/utf8>>,
line => 4032})
end;
Move_list ->
Maybe_move = gleam@list:filter(
Move_list,
fun(Move@3) -> case Move@3 of
{normal, From, _, _} ->
case board:get_piece_at_position(
erlang:element(2, Game),
From
) of
{some, Piece} ->
erlang:element(
3,
Piece
)
=:= Moving_piece;
none ->
false
end;
_ ->
false
end end
),
case Maybe_move of
[] ->
{error, <<"Move not found"/utf8>>};
[Move@4] ->
{ok, Move@4};
_ ->
erlang:error(#{gleam_error => panic,
message => <<"This panic should be unreachable"/utf8>>,
module => <<"game"/utf8>>,
function => <<"apply_move_san_string"/utf8>>,
line => 4056})
end
end
end
)),
case Move@5 of
{ok, Move@6} ->
New_game_state = apply_move(Game, Move@6),
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,
apply_move(Game, Move@7);
{en_passant, From@1, To@1, _} ->
gleam@result:'try'(
all_legal_moves(Game),
fun(All_legal_moves_ok@1) ->
Ep_moves = gleam@list:filter(
All_legal_moves_ok@1,
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] ->
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)
) ->
apply_move(Game, Move_1);
{some,
{position_san, {some, File@1}, _}} when File@1 =:= erlang:element(
2,
erlang:element(2, Move_2)
) ->
apply_move(Game, Move_2);
_ ->
{error, <<"Illegal move"/utf8>>}
end;
_ ->
{error, <<"Illegal move"/utf8>>}
end
end
)
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) ->
gleam@result:'try'(
Game@1,
fun(Game@2) ->
Game@6 = case gleam@string:split(Movetext, <<" "/utf8>>) of
[White_ply, Black_ply] ->
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] ->
Game@5 = apply_move_san_string(Game@2, White_ply@1),
Game@5;
[] ->
{error, <<"Invalid PGN"/utf8>>};
_ ->
{error, <<"Invalid PGN"/utf8>>}
end,
Game@6
end
)
end
).
-spec apply_move_uci(game(), binary()) -> {ok, game()} | {error, binary()}.
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>>} ->
{ok, a};
{ok, <<"b"/utf8>>} ->
{ok, b};
{ok, <<"c"/utf8>>} ->
{ok, c};
{ok, <<"d"/utf8>>} ->
{ok, d};
{ok, <<"e"/utf8>>} ->
{ok, e};
{ok, <<"f"/utf8>>} ->
{ok, f};
{ok, <<"g"/utf8>>} ->
{ok, g};
{ok, <<"h"/utf8>>} ->
{ok, h};
_ ->
{error, <<"Could not parse origin file"/utf8>>}
end,
case gleam@list:rest(Move_chars) of
{ok, Move_chars@1} ->
From_rank = case gleam@list:first(Move_chars@1) of
{ok, <<"1"/utf8>>} ->
{ok, one};
{ok, <<"2"/utf8>>} ->
{ok, two};
{ok, <<"3"/utf8>>} ->
{ok, three};
{ok, <<"4"/utf8>>} ->
{ok, four};
{ok, <<"5"/utf8>>} ->
{ok, five};
{ok, <<"6"/utf8>>} ->
{ok, six};
{ok, <<"7"/utf8>>} ->
{ok, seven};
{ok, <<"8"/utf8>>} ->
{ok, eight};
_ ->
{error,
<<"Could not parse origin rank"/utf8>>}
end,
case gleam@list:rest(Move_chars@1) of
{ok, Move_chars@2} ->
To_file = case gleam@list:first(
Move_chars@2
) of
{ok, <<"a"/utf8>>} ->
{ok, a};
{ok, <<"b"/utf8>>} ->
{ok, b};
{ok, <<"c"/utf8>>} ->
{ok, c};
{ok, <<"d"/utf8>>} ->
{ok, d};
{ok, <<"e"/utf8>>} ->
{ok, e};
{ok, <<"f"/utf8>>} ->
{ok, f};
{ok, <<"g"/utf8>>} ->
{ok, g};
{ok, <<"h"/utf8>>} ->
{ok, h};
_ ->
{error,
<<"Could not parse destination file"/utf8>>}
end,
case gleam@list:rest(Move_chars@2) of
{ok, Move_chars@3} ->
To_rank = case gleam@list:first(
Move_chars@3
) of
{ok, <<"1"/utf8>>} ->
{ok, one};
{ok, <<"2"/utf8>>} ->
{ok, two};
{ok, <<"3"/utf8>>} ->
{ok, three};
{ok, <<"4"/utf8>>} ->
{ok, four};
{ok, <<"5"/utf8>>} ->
{ok, five};
{ok, <<"6"/utf8>>} ->
{ok, six};
{ok, <<"7"/utf8>>} ->
{ok, seven};
{ok, <<"8"/utf8>>} ->
{ok, eight};
_ ->
{error,
<<"Could not parse destination rank"/utf8>>}
end,
case {From_file,
From_rank,
To_file,
To_rank} of
{{ok, From_file@1},
{ok, From_rank@1},
{ok, To_file@1},
{ok, To_rank@1}} ->
Promo = case gleam@string:slice(
Move,
4,
1
) of
<<"q"/utf8>> ->
{some, queen};
<<"r"/utf8>> ->
{some, rook};
<<"b"/utf8>> ->
{some, bishop};
<<"n"/utf8>> ->
{some, knight};
_ ->
none
end,
gleam@result:'try'(
case piece_at_position(
Game,
{position,
From_file@1,
From_rank@1}
) of
{some, Piece} ->
{ok, Piece};
none ->
{error,
<<"No piece at origin"/utf8>>}
end,
fun(Piece@1) ->
Maybe_enemy_piece = piece_at_position(
Game,
{position,
To_file@1,
To_rank@1}
),
Move@1 = case Promo of
{some, Promo@1} ->
{normal,
{position,
From_file@1,
From_rank@1},
{position,
To_file@1,
To_rank@1},
{some,
{piece,
erlang:element(
3,
Game
),
Promo@1}}};
none ->
case Piece@1 of
{piece,
_,
pawn} ->
case From_file@1
=:= To_file@1 of
true ->
{normal,
{position,
From_file@1,
From_rank@1},
{position,
To_file@1,
To_rank@1},
none};
false ->
case Maybe_enemy_piece of
{some,
_} ->
{normal,
{position,
From_file@1,
From_rank@1},
{position,
To_file@1,
To_rank@1},
none};
none ->
{en_passant,
{position,
From_file@1,
From_rank@1},
{position,
To_file@1,
To_rank@1}}
end
end;
{piece,
_,
king} ->
case position:file_to_int(
From_file@1
)
- position:file_to_int(
To_file@1
) of
2 ->
{castle,
{position,
e,
From_rank@1},
{position,
To_file@1,
To_rank@1}};
-2 ->
{castle,
{position,
e,
From_rank@1},
{position,
To_file@1,
To_rank@1}};
_ ->
{normal,
{position,
From_file@1,
From_rank@1},
{position,
To_file@1,
To_rank@1},
none}
end;
_ ->
{normal,
{position,
From_file@1,
From_rank@1},
{position,
To_file@1,
To_rank@1},
none}
end
end,
New_game_state = apply_move(
Game,
Move@1
),
New_game_state
end
);
{From_file_result,
From_rank_result,
To_file_result,
To_rank_result} ->
{_, File_errors} = gleam@result:partition(
[From_file_result,
To_file_result]
),
{_, Rank_errors} = gleam@result:partition(
[From_rank_result,
To_rank_result]
),
Errors = gleam@list:concat(
[File_errors,
Rank_errors]
),
{error,
gleam@string:join(
Errors,
<<", "/utf8>>
)}
end;
_ ->
{error, <<"Invalid move"/utf8>>}
end;
{error, _} ->
{error, <<"Invalid move"/utf8>>}
end;
{error, _} ->
{error, <<"Invalid move"/utf8>>}
end;
5 ->
Move_chars = gleam@string:to_graphemes(Move),
From_file = case gleam@list:first(Move_chars) of
{ok, <<"a"/utf8>>} ->
{ok, a};
{ok, <<"b"/utf8>>} ->
{ok, b};
{ok, <<"c"/utf8>>} ->
{ok, c};
{ok, <<"d"/utf8>>} ->
{ok, d};
{ok, <<"e"/utf8>>} ->
{ok, e};
{ok, <<"f"/utf8>>} ->
{ok, f};
{ok, <<"g"/utf8>>} ->
{ok, g};
{ok, <<"h"/utf8>>} ->
{ok, h};
_ ->
{error, <<"Could not parse origin file"/utf8>>}
end,
case gleam@list:rest(Move_chars) of
{ok, Move_chars@1} ->
From_rank = case gleam@list:first(Move_chars@1) of
{ok, <<"1"/utf8>>} ->
{ok, one};
{ok, <<"2"/utf8>>} ->
{ok, two};
{ok, <<"3"/utf8>>} ->
{ok, three};
{ok, <<"4"/utf8>>} ->
{ok, four};
{ok, <<"5"/utf8>>} ->
{ok, five};
{ok, <<"6"/utf8>>} ->
{ok, six};
{ok, <<"7"/utf8>>} ->
{ok, seven};
{ok, <<"8"/utf8>>} ->
{ok, eight};
_ ->
{error,
<<"Could not parse origin rank"/utf8>>}
end,
case gleam@list:rest(Move_chars@1) of
{ok, Move_chars@2} ->
To_file = case gleam@list:first(
Move_chars@2
) of
{ok, <<"a"/utf8>>} ->
{ok, a};
{ok, <<"b"/utf8>>} ->
{ok, b};
{ok, <<"c"/utf8>>} ->
{ok, c};
{ok, <<"d"/utf8>>} ->
{ok, d};
{ok, <<"e"/utf8>>} ->
{ok, e};
{ok, <<"f"/utf8>>} ->
{ok, f};
{ok, <<"g"/utf8>>} ->
{ok, g};
{ok, <<"h"/utf8>>} ->
{ok, h};
_ ->
{error,
<<"Could not parse destination file"/utf8>>}
end,
case gleam@list:rest(Move_chars@2) of
{ok, Move_chars@3} ->
To_rank = case gleam@list:first(
Move_chars@3
) of
{ok, <<"1"/utf8>>} ->
{ok, one};
{ok, <<"2"/utf8>>} ->
{ok, two};
{ok, <<"3"/utf8>>} ->
{ok, three};
{ok, <<"4"/utf8>>} ->
{ok, four};
{ok, <<"5"/utf8>>} ->
{ok, five};
{ok, <<"6"/utf8>>} ->
{ok, six};
{ok, <<"7"/utf8>>} ->
{ok, seven};
{ok, <<"8"/utf8>>} ->
{ok, eight};
_ ->
{error,
<<"Could not parse destination rank"/utf8>>}
end,
case {From_file,
From_rank,
To_file,
To_rank} of
{{ok, From_file@1},
{ok, From_rank@1},
{ok, To_file@1},
{ok, To_rank@1}} ->
Promo = case gleam@string:slice(
Move,
4,
1
) of
<<"q"/utf8>> ->
{some, queen};
<<"r"/utf8>> ->
{some, rook};
<<"b"/utf8>> ->
{some, bishop};
<<"n"/utf8>> ->
{some, knight};
_ ->
none
end,
gleam@result:'try'(
case piece_at_position(
Game,
{position,
From_file@1,
From_rank@1}
) of
{some, Piece} ->
{ok, Piece};
none ->
{error,
<<"No piece at origin"/utf8>>}
end,
fun(Piece@1) ->
Maybe_enemy_piece = piece_at_position(
Game,
{position,
To_file@1,
To_rank@1}
),
Move@1 = case Promo of
{some, Promo@1} ->
{normal,
{position,
From_file@1,
From_rank@1},
{position,
To_file@1,
To_rank@1},
{some,
{piece,
erlang:element(
3,
Game
),
Promo@1}}};
none ->
case Piece@1 of
{piece,
_,
pawn} ->
case From_file@1
=:= To_file@1 of
true ->
{normal,
{position,
From_file@1,
From_rank@1},
{position,
To_file@1,
To_rank@1},
none};
false ->
case Maybe_enemy_piece of
{some,
_} ->
{normal,
{position,
From_file@1,
From_rank@1},
{position,
To_file@1,
To_rank@1},
none};
none ->
{en_passant,
{position,
From_file@1,
From_rank@1},
{position,
To_file@1,
To_rank@1}}
end
end;
{piece,
_,
king} ->
case position:file_to_int(
From_file@1
)
- position:file_to_int(
To_file@1
) of
2 ->
{castle,
{position,
e,
From_rank@1},
{position,
To_file@1,
To_rank@1}};
-2 ->
{castle,
{position,
e,
From_rank@1},
{position,
To_file@1,
To_rank@1}};
_ ->
{normal,
{position,
From_file@1,
From_rank@1},
{position,
To_file@1,
To_rank@1},
none}
end;
_ ->
{normal,
{position,
From_file@1,
From_rank@1},
{position,
To_file@1,
To_rank@1},
none}
end
end,
New_game_state = apply_move(
Game,
Move@1
),
New_game_state
end
);
{From_file_result,
From_rank_result,
To_file_result,
To_rank_result} ->
{_, File_errors} = gleam@result:partition(
[From_file_result,
To_file_result]
),
{_, Rank_errors} = gleam@result:partition(
[From_rank_result,
To_rank_result]
),
Errors = gleam@list:concat(
[File_errors,
Rank_errors]
),
{error,
gleam@string:join(
Errors,
<<", "/utf8>>
)}
end;
_ ->
{error, <<"Invalid move"/utf8>>}
end;
{error, _} ->
{error, <<"Invalid move"/utf8>>}
end;
{error, _} ->
{error, <<"Invalid move"/utf8>>}
end;
_ ->
{error, <<"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>>} ->
{ok, a};
{ok, <<"b"/utf8>>} ->
{ok, b};
{ok, <<"c"/utf8>>} ->
{ok, c};
{ok, <<"d"/utf8>>} ->
{ok, d};
{ok, <<"e"/utf8>>} ->
{ok, e};
{ok, <<"f"/utf8>>} ->
{ok, f};
{ok, <<"g"/utf8>>} ->
{ok, g};
{ok, <<"h"/utf8>>} ->
{ok, h};
_ ->
{error, <<"Could not parse origin file"/utf8>>}
end,
case gleam@list:rest(Move_chars) of
{ok, Move_chars@1} ->
From_rank = case gleam@list:first(Move_chars@1) of
{ok, <<"1"/utf8>>} ->
{ok, one};
{ok, <<"2"/utf8>>} ->
{ok, two};
{ok, <<"3"/utf8>>} ->
{ok, three};
{ok, <<"4"/utf8>>} ->
{ok, four};
{ok, <<"5"/utf8>>} ->
{ok, five};
{ok, <<"6"/utf8>>} ->
{ok, six};
{ok, <<"7"/utf8>>} ->
{ok, seven};
{ok, <<"8"/utf8>>} ->
{ok, eight};
_ ->
{error,
<<"Could not parse origin rank"/utf8>>}
end,
case gleam@list:rest(Move_chars@1) of
{ok, Move_chars@2} ->
To_file = case gleam@list:first(
Move_chars@2
) of
{ok, <<"a"/utf8>>} ->
{ok, a};
{ok, <<"b"/utf8>>} ->
{ok, b};
{ok, <<"c"/utf8>>} ->
{ok, c};
{ok, <<"d"/utf8>>} ->
{ok, d};
{ok, <<"e"/utf8>>} ->
{ok, e};
{ok, <<"f"/utf8>>} ->
{ok, f};
{ok, <<"g"/utf8>>} ->
{ok, g};
{ok, <<"h"/utf8>>} ->
{ok, h};
_ ->
{error,
<<"Could not parse destination file"/utf8>>}
end,
case gleam@list:rest(Move_chars@2) of
{ok, Move_chars@3} ->
To_rank = case gleam@list:first(
Move_chars@3
) of
{ok, <<"1"/utf8>>} ->
{ok, one};
{ok, <<"2"/utf8>>} ->
{ok, two};
{ok, <<"3"/utf8>>} ->
{ok, three};
{ok, <<"4"/utf8>>} ->
{ok, four};
{ok, <<"5"/utf8>>} ->
{ok, five};
{ok, <<"6"/utf8>>} ->
{ok, six};
{ok, <<"7"/utf8>>} ->
{ok, seven};
{ok, <<"8"/utf8>>} ->
{ok, eight};
_ ->
{error,
<<"Could not parse destination rank"/utf8>>}
end,
case {From_file,
From_rank,
To_file,
To_rank} of
{{ok, From_file@1},
{ok, From_rank@1},
{ok, To_file@1},
{ok, To_rank@1}} ->
Promo = case gleam@string:slice(
Move,
4,
1
) of
<<"q"/utf8>> ->
{some, queen};
<<"r"/utf8>> ->
{some, rook};
<<"b"/utf8>> ->
{some, bishop};
<<"n"/utf8>> ->
{some, knight};
_ ->
none
end,
gleam@result:'try'(
case piece_at_position(
Game,
{position,
From_file@1,
From_rank@1}
) of
{some, Piece} ->
{ok, Piece};
none ->
{error,
<<"No piece at origin"/utf8>>}
end,
fun(Piece@1) ->
Maybe_enemy_piece = piece_at_position(
Game,
{position,
To_file@1,
To_rank@1}
),
Move@1 = case Promo of
{some, Promo@1} ->
{normal,
{position,
From_file@1,
From_rank@1},
{position,
To_file@1,
To_rank@1},
{some,
{piece,
erlang:element(
3,
Game
),
Promo@1}}};
none ->
case Piece@1 of
{piece,
_,
pawn} ->
case From_file@1
=:= To_file@1 of
true ->
{normal,
{position,
From_file@1,
From_rank@1},
{position,
To_file@1,
To_rank@1},
none};
false ->
case Maybe_enemy_piece of
{some,
_} ->
{normal,
{position,
From_file@1,
From_rank@1},
{position,
To_file@1,
To_rank@1},
none};
none ->
{en_passant,
{position,
From_file@1,
From_rank@1},
{position,
To_file@1,
To_rank@1}}
end
end;
{piece,
_,
king} ->
case position:file_to_int(
From_file@1
)
- position:file_to_int(
To_file@1
) of
2 ->
{castle,
{position,
e,
From_rank@1},
{position,
To_file@1,
To_rank@1}};
-2 ->
{castle,
{position,
e,
From_rank@1},
{position,
To_file@1,
To_rank@1}};
_ ->
{normal,
{position,
From_file@1,
From_rank@1},
{position,
To_file@1,
To_rank@1},
none}
end;
_ ->
{normal,
{position,
From_file@1,
From_rank@1},
{position,
To_file@1,
To_rank@1},
none}
end
end,
New_game_state = apply_move(
Game,
Move@1
),
New_game_state
end
);
{From_file_result,
From_rank_result,
To_file_result,
To_rank_result} ->
{_, File_errors} = gleam@result:partition(
[From_file_result,
To_file_result]
),
{_, Rank_errors} = gleam@result:partition(
[From_rank_result,
To_rank_result]
),
Errors = gleam@list:concat(
[File_errors,
Rank_errors]
),
{error,
gleam@string:join(
Errors,
<<", "/utf8>>
)}
end;
_ ->
{error, <<"Invalid move"/utf8>>}
end;
{error, _} ->
{error, <<"Invalid move"/utf8>>}
end;
{error, _} ->
{error, <<"Invalid move"/utf8>>}
end;
5 ->
Move_chars = gleam@string:to_graphemes(Move),
From_file = case gleam@list:first(Move_chars) of
{ok, <<"a"/utf8>>} ->
{ok, a};
{ok, <<"b"/utf8>>} ->
{ok, b};
{ok, <<"c"/utf8>>} ->
{ok, c};
{ok, <<"d"/utf8>>} ->
{ok, d};
{ok, <<"e"/utf8>>} ->
{ok, e};
{ok, <<"f"/utf8>>} ->
{ok, f};
{ok, <<"g"/utf8>>} ->
{ok, g};
{ok, <<"h"/utf8>>} ->
{ok, h};
_ ->
{error, <<"Could not parse origin file"/utf8>>}
end,
case gleam@list:rest(Move_chars) of
{ok, Move_chars@1} ->
From_rank = case gleam@list:first(Move_chars@1) of
{ok, <<"1"/utf8>>} ->
{ok, one};
{ok, <<"2"/utf8>>} ->
{ok, two};
{ok, <<"3"/utf8>>} ->
{ok, three};
{ok, <<"4"/utf8>>} ->
{ok, four};
{ok, <<"5"/utf8>>} ->
{ok, five};
{ok, <<"6"/utf8>>} ->
{ok, six};
{ok, <<"7"/utf8>>} ->
{ok, seven};
{ok, <<"8"/utf8>>} ->
{ok, eight};
_ ->
{error,
<<"Could not parse origin rank"/utf8>>}
end,
case gleam@list:rest(Move_chars@1) of
{ok, Move_chars@2} ->
To_file = case gleam@list:first(
Move_chars@2
) of
{ok, <<"a"/utf8>>} ->
{ok, a};
{ok, <<"b"/utf8>>} ->
{ok, b};
{ok, <<"c"/utf8>>} ->
{ok, c};
{ok, <<"d"/utf8>>} ->
{ok, d};
{ok, <<"e"/utf8>>} ->
{ok, e};
{ok, <<"f"/utf8>>} ->
{ok, f};
{ok, <<"g"/utf8>>} ->
{ok, g};
{ok, <<"h"/utf8>>} ->
{ok, h};
_ ->
{error,
<<"Could not parse destination file"/utf8>>}
end,
case gleam@list:rest(Move_chars@2) of
{ok, Move_chars@3} ->
To_rank = case gleam@list:first(
Move_chars@3
) of
{ok, <<"1"/utf8>>} ->
{ok, one};
{ok, <<"2"/utf8>>} ->
{ok, two};
{ok, <<"3"/utf8>>} ->
{ok, three};
{ok, <<"4"/utf8>>} ->
{ok, four};
{ok, <<"5"/utf8>>} ->
{ok, five};
{ok, <<"6"/utf8>>} ->
{ok, six};
{ok, <<"7"/utf8>>} ->
{ok, seven};
{ok, <<"8"/utf8>>} ->
{ok, eight};
_ ->
{error,
<<"Could not parse destination rank"/utf8>>}
end,
case {From_file,
From_rank,
To_file,
To_rank} of
{{ok, From_file@1},
{ok, From_rank@1},
{ok, To_file@1},
{ok, To_rank@1}} ->
Promo = case gleam@string:slice(
Move,
4,
1
) of
<<"q"/utf8>> ->
{some, queen};
<<"r"/utf8>> ->
{some, rook};
<<"b"/utf8>> ->
{some, bishop};
<<"n"/utf8>> ->
{some, knight};
_ ->
none
end,
gleam@result:'try'(
case piece_at_position(
Game,
{position,
From_file@1,
From_rank@1}
) of
{some, Piece} ->
{ok, Piece};
none ->
{error,
<<"No piece at origin"/utf8>>}
end,
fun(Piece@1) ->
Maybe_enemy_piece = piece_at_position(
Game,
{position,
To_file@1,
To_rank@1}
),
Move@1 = case Promo of
{some, Promo@1} ->
{normal,
{position,
From_file@1,
From_rank@1},
{position,
To_file@1,
To_rank@1},
{some,
{piece,
erlang:element(
3,
Game
),
Promo@1}}};
none ->
case Piece@1 of
{piece,
_,
pawn} ->
case From_file@1
=:= To_file@1 of
true ->
{normal,
{position,
From_file@1,
From_rank@1},
{position,
To_file@1,
To_rank@1},
none};
false ->
case Maybe_enemy_piece of
{some,
_} ->
{normal,
{position,
From_file@1,
From_rank@1},
{position,
To_file@1,
To_rank@1},
none};
none ->
{en_passant,
{position,
From_file@1,
From_rank@1},
{position,
To_file@1,
To_rank@1}}
end
end;
{piece,
_,
king} ->
case position:file_to_int(
From_file@1
)
- position:file_to_int(
To_file@1
) of
2 ->
{castle,
{position,
e,
From_rank@1},
{position,
To_file@1,
To_rank@1}};
-2 ->
{castle,
{position,
e,
From_rank@1},
{position,
To_file@1,
To_rank@1}};
_ ->
{normal,
{position,
From_file@1,
From_rank@1},
{position,
To_file@1,
To_rank@1},
none}
end;
_ ->
{normal,
{position,
From_file@1,
From_rank@1},
{position,
To_file@1,
To_rank@1},
none}
end
end,
New_game_state = apply_move(
Game,
Move@1
),
New_game_state
end
);
{From_file_result,
From_rank_result,
To_file_result,
To_rank_result} ->
{_, File_errors} = gleam@result:partition(
[From_file_result,
To_file_result]
),
{_, Rank_errors} = gleam@result:partition(
[From_rank_result,
To_rank_result]
),
Errors = gleam@list:concat(
[File_errors,
Rank_errors]
),
{error,
gleam@string:join(
Errors,
<<", "/utf8>>
)}
end;
_ ->
{error, <<"Invalid move"/utf8>>}
end;
{error, _} ->
{error, <<"Invalid move"/utf8>>}
end;
{error, _} ->
{error, <<"Invalid move"/utf8>>}
end;
_ ->
{error, <<"Invalid move"/utf8>>}
end;
{some, _} ->
{ok, Game}
end.