Current section
Files
Jump to
Current section
Files
src/fen.erl
-module(fen).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]).
-export([to_string/1, parse_board/1, to_board/1, from_string/1]).
-export_type([castling_status/0, fen/0]).
-type castling_status() :: {castling_status,
boolean(),
boolean(),
boolean(),
boolean()}.
-type fen() :: {fen,
board:board_bb(),
color:color(),
castling_status(),
gleam@option:option(position:position()),
integer(),
integer()}.
-spec piece_to_fen_string(piece:piece()) -> binary().
piece_to_fen_string(Piece) ->
case Piece of
{piece, white, king} ->
<<"K"/utf8>>;
{piece, white, queen} ->
<<"Q"/utf8>>;
{piece, white, rook} ->
<<"R"/utf8>>;
{piece, white, bishop} ->
<<"B"/utf8>>;
{piece, white, knight} ->
<<"N"/utf8>>;
{piece, white, pawn} ->
<<"P"/utf8>>;
{piece, black, king} ->
<<"k"/utf8>>;
{piece, black, queen} ->
<<"q"/utf8>>;
{piece, black, rook} ->
<<"r"/utf8>>;
{piece, black, bishop} ->
<<"b"/utf8>>;
{piece, black, knight} ->
<<"n"/utf8>>;
{piece, black, pawn} ->
<<"p"/utf8>>
end.
-spec board_to_fen_string(board:board_bb()) -> binary().
board_to_fen_string(Board) ->
Board_string = gleam@list:fold(
[{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}],
<<""/utf8>>,
fun(Acc, Pos) ->
Piece = board:get_piece_at_position(Board, Pos),
Acc@1 = case Piece of
none ->
Last_char = gleam@string:last(Acc),
case Last_char of
{error, nil} ->
gleam@string:append(Acc, <<"1"/utf8>>);
{ok, <<"/"/utf8>>} ->
gleam@string:append(Acc, <<"1"/utf8>>);
{ok, <<"1"/utf8>>} ->
gleam@string:append(
gleam@string:drop_right(Acc, 1),
<<"2"/utf8>>
);
{ok, <<"2"/utf8>>} ->
gleam@string:append(
gleam@string:drop_right(Acc, 1),
<<"3"/utf8>>
);
{ok, <<"3"/utf8>>} ->
gleam@string:append(
gleam@string:drop_right(Acc, 1),
<<"4"/utf8>>
);
{ok, <<"4"/utf8>>} ->
gleam@string:append(
gleam@string:drop_right(Acc, 1),
<<"5"/utf8>>
);
{ok, <<"5"/utf8>>} ->
gleam@string:append(
gleam@string:drop_right(Acc, 1),
<<"6"/utf8>>
);
{ok, <<"6"/utf8>>} ->
gleam@string:append(
gleam@string:drop_right(Acc, 1),
<<"7"/utf8>>
);
{ok, <<"7"/utf8>>} ->
gleam@string:append(
gleam@string:drop_right(Acc, 1),
<<"8"/utf8>>
);
{ok, <<"8"/utf8>>} ->
(erlang:error(#{gleam_error => panic,
message => <<"panic expression evaluated"/utf8>>,
module => <<"fen"/utf8>>,
function => <<"board_to_fen_string"/utf8>>,
line => 150}))(
<<"Unable to encode BoardBB to FEN string"/utf8>>
);
{ok, _} ->
gleam@string:append(Acc, <<"1"/utf8>>)
end;
{some, Piece@1} ->
Piece_string = piece_to_fen_string(Piece@1),
gleam@string:append(Acc, Piece_string)
end,
Acc@2 = case Pos of
{position, h, one} ->
Acc@1;
{position, h, _} ->
gleam@string:append(Acc@1, <<"/"/utf8>>);
_ ->
Acc@1
end,
Acc@2
end
),
Board_string.
-spec turn_to_fen_string(color:color()) -> binary().
turn_to_fen_string(Turn) ->
case Turn of
white ->
<<"w"/utf8>>;
black ->
<<"b"/utf8>>
end.
-spec castling_to_fen_string(castling_status()) -> binary().
castling_to_fen_string(Castling) ->
White_kingside_castling = case erlang:element(2, Castling) of
true ->
<<"K"/utf8>>;
false ->
<<""/utf8>>
end,
White_queenside_castling = case erlang:element(3, Castling) of
true ->
<<"Q"/utf8>>;
false ->
<<""/utf8>>
end,
Black_kingside_castling = case erlang:element(4, Castling) of
true ->
<<"k"/utf8>>;
false ->
<<""/utf8>>
end,
Black_queenside_castling = case erlang:element(5, Castling) of
true ->
<<"q"/utf8>>;
false ->
<<""/utf8>>
end,
Castling_string = gleam@string:join(
[White_kingside_castling,
White_queenside_castling,
Black_kingside_castling,
Black_queenside_castling],
<<""/utf8>>
),
case Castling_string of
<<""/utf8>> ->
<<"-"/utf8>>;
_ ->
Castling_string
end.
-spec en_passant_to_fen_string(gleam@option:option(position:position())) -> binary().
en_passant_to_fen_string(En_passant) ->
case En_passant of
none ->
<<"-"/utf8>>;
{some, Pos} ->
File_string = position:file_to_string(erlang:element(2, Pos)),
Rank_string = position:rank_to_string(erlang:element(3, Pos)),
gleam@string:join([File_string, Rank_string], <<""/utf8>>)
end.
-spec to_string(fen()) -> binary().
to_string(Fen) ->
Board_string = board_to_fen_string(erlang:element(2, Fen)),
Turn_string = turn_to_fen_string(erlang:element(3, Fen)),
Castling_string = castling_to_fen_string(erlang:element(4, Fen)),
En_passant_string = en_passant_to_fen_string(erlang:element(5, Fen)),
Halfmove_string = gleam@int:to_string(erlang:element(6, Fen)),
Fullmove_string = gleam@int:to_string(erlang:element(7, Fen)),
Fen_string = gleam@string:join(
[Board_string,
Turn_string,
Castling_string,
En_passant_string,
Halfmove_string,
Fullmove_string],
<<" "/utf8>>
),
Fen_string.
-spec expand_rank(list(binary())) -> list(binary()).
expand_rank(Rank) ->
Accumulator = [],
gleam@list:fold(Rank, Accumulator, fun(Acc, Part) -> case Part of
<<"1"/utf8>> ->
gleam@list:append(Acc, [<<""/utf8>>]);
<<"2"/utf8>> ->
gleam@list:append(Acc, [<<""/utf8>>, <<""/utf8>>]);
<<"3"/utf8>> ->
gleam@list:append(
Acc,
[<<""/utf8>>, <<""/utf8>>, <<""/utf8>>]
);
<<"4"/utf8>> ->
gleam@list:append(
Acc,
[<<""/utf8>>, <<""/utf8>>, <<""/utf8>>, <<""/utf8>>]
);
<<"5"/utf8>> ->
gleam@list:append(
Acc,
[<<""/utf8>>,
<<""/utf8>>,
<<""/utf8>>,
<<""/utf8>>,
<<""/utf8>>]
);
<<"6"/utf8>> ->
gleam@list:append(
Acc,
[<<""/utf8>>,
<<""/utf8>>,
<<""/utf8>>,
<<""/utf8>>,
<<""/utf8>>,
<<""/utf8>>]
);
<<"7"/utf8>> ->
gleam@list:append(
Acc,
[<<""/utf8>>,
<<""/utf8>>,
<<""/utf8>>,
<<""/utf8>>,
<<""/utf8>>,
<<""/utf8>>,
<<""/utf8>>]
);
<<"8"/utf8>> ->
gleam@list:append(
Acc,
[<<""/utf8>>,
<<""/utf8>>,
<<""/utf8>>,
<<""/utf8>>,
<<""/utf8>>,
<<""/utf8>>,
<<""/utf8>>,
<<""/utf8>>]
);
<<"K"/utf8>> ->
gleam@list:append(Acc, [<<"K"/utf8>>]);
<<"Q"/utf8>> ->
gleam@list:append(Acc, [<<"Q"/utf8>>]);
<<"R"/utf8>> ->
gleam@list:append(Acc, [<<"R"/utf8>>]);
<<"B"/utf8>> ->
gleam@list:append(Acc, [<<"B"/utf8>>]);
<<"N"/utf8>> ->
gleam@list:append(Acc, [<<"N"/utf8>>]);
<<"P"/utf8>> ->
gleam@list:append(Acc, [<<"P"/utf8>>]);
<<"k"/utf8>> ->
gleam@list:append(Acc, [<<"k"/utf8>>]);
<<"q"/utf8>> ->
gleam@list:append(Acc, [<<"q"/utf8>>]);
<<"r"/utf8>> ->
gleam@list:append(Acc, [<<"r"/utf8>>]);
<<"b"/utf8>> ->
gleam@list:append(Acc, [<<"b"/utf8>>]);
<<"n"/utf8>> ->
gleam@list:append(Acc, [<<"n"/utf8>>]);
<<"p"/utf8>> ->
gleam@list:append(Acc, [<<"p"/utf8>>]);
_ ->
gleam@list:append(Acc, [Part])
end end).
-spec parse_board(binary()) -> board:board_bb().
parse_board(Board_string) ->
List_of_ranks_as_strings = gleam@string:split(Board_string, <<"/"/utf8>>),
Accumulator = {board_bb,
{bitboard, 0},
{bitboard, 0},
{bitboard, 0},
{bitboard, 0},
{bitboard, 0},
{bitboard, 0},
{bitboard, 0},
{bitboard, 0},
{bitboard, 0},
{bitboard, 0},
{bitboard, 0},
{bitboard, 0}},
gleam@list:index_fold(
List_of_ranks_as_strings,
Accumulator,
fun(Acc, Rank_as_string, Rank_index) ->
Rank_index@1 = position:int_to_rank(7 - Rank_index),
Rank_parts = gleam@string:to_graphemes(Rank_as_string),
Expanded_rank = expand_rank(Rank_parts),
gleam@list:index_fold(
Expanded_rank,
Acc,
fun(Acc@1, Square, File_index) ->
File_index@1 = position:int_to_file(File_index),
case Square of
<<""/utf8>> ->
Acc@1;
<<"K"/utf8>> ->
New_white_king_bitboard = board:from_position(
{position, File_index@1, Rank_index@1}
),
{board_bb,
erlang:element(2, Acc@1),
erlang:element(3, Acc@1),
erlang:element(4, Acc@1),
erlang:element(5, Acc@1),
erlang:element(6, Acc@1),
erlang:element(7, Acc@1),
bitboard:'or'(
erlang:element(8, Acc@1),
New_white_king_bitboard
),
erlang:element(9, Acc@1),
erlang:element(10, Acc@1),
erlang:element(11, Acc@1),
erlang:element(12, Acc@1),
erlang:element(13, Acc@1)};
<<"Q"/utf8>> ->
New_white_queen_bitboard = board:from_position(
{position, File_index@1, Rank_index@1}
),
{board_bb,
erlang:element(2, Acc@1),
erlang:element(3, Acc@1),
erlang:element(4, Acc@1),
erlang:element(5, Acc@1),
erlang:element(6, Acc@1),
erlang:element(7, Acc@1),
erlang:element(8, Acc@1),
bitboard:'or'(
erlang:element(9, Acc@1),
New_white_queen_bitboard
),
erlang:element(10, Acc@1),
erlang:element(11, Acc@1),
erlang:element(12, Acc@1),
erlang:element(13, Acc@1)};
<<"R"/utf8>> ->
New_white_rook_bitboard = board:from_position(
{position, File_index@1, Rank_index@1}
),
{board_bb,
erlang:element(2, Acc@1),
erlang:element(3, Acc@1),
erlang:element(4, Acc@1),
erlang:element(5, Acc@1),
erlang:element(6, Acc@1),
erlang:element(7, Acc@1),
erlang:element(8, Acc@1),
erlang:element(9, Acc@1),
bitboard:'or'(
erlang:element(10, Acc@1),
New_white_rook_bitboard
),
erlang:element(11, Acc@1),
erlang:element(12, Acc@1),
erlang:element(13, Acc@1)};
<<"B"/utf8>> ->
New_white_bishop_bitboard = board:from_position(
{position, File_index@1, Rank_index@1}
),
{board_bb,
erlang:element(2, Acc@1),
erlang:element(3, Acc@1),
erlang:element(4, Acc@1),
erlang:element(5, Acc@1),
erlang:element(6, Acc@1),
erlang:element(7, Acc@1),
erlang:element(8, Acc@1),
erlang:element(9, Acc@1),
erlang:element(10, Acc@1),
bitboard:'or'(
erlang:element(11, Acc@1),
New_white_bishop_bitboard
),
erlang:element(12, Acc@1),
erlang:element(13, Acc@1)};
<<"N"/utf8>> ->
New_white_knight_bitboard = board:from_position(
{position, File_index@1, Rank_index@1}
),
{board_bb,
erlang:element(2, Acc@1),
erlang:element(3, Acc@1),
erlang:element(4, Acc@1),
erlang:element(5, Acc@1),
erlang:element(6, Acc@1),
erlang:element(7, Acc@1),
erlang:element(8, Acc@1),
erlang:element(9, Acc@1),
erlang:element(10, Acc@1),
erlang:element(11, Acc@1),
bitboard:'or'(
erlang:element(12, Acc@1),
New_white_knight_bitboard
),
erlang:element(13, Acc@1)};
<<"P"/utf8>> ->
New_white_pawn_bitboard = board:from_position(
{position, File_index@1, Rank_index@1}
),
{board_bb,
erlang:element(2, Acc@1),
erlang:element(3, Acc@1),
erlang:element(4, Acc@1),
erlang:element(5, Acc@1),
erlang:element(6, Acc@1),
erlang:element(7, Acc@1),
erlang:element(8, Acc@1),
erlang:element(9, Acc@1),
erlang:element(10, Acc@1),
erlang:element(11, Acc@1),
erlang:element(12, Acc@1),
bitboard:'or'(
erlang:element(13, Acc@1),
New_white_pawn_bitboard
)};
<<"k"/utf8>> ->
New_black_king_bitboard = board:from_position(
{position, File_index@1, Rank_index@1}
),
{board_bb,
bitboard:'or'(
erlang:element(2, Acc@1),
New_black_king_bitboard
),
erlang:element(3, Acc@1),
erlang:element(4, Acc@1),
erlang:element(5, Acc@1),
erlang:element(6, Acc@1),
erlang:element(7, Acc@1),
erlang:element(8, Acc@1),
erlang:element(9, Acc@1),
erlang:element(10, Acc@1),
erlang:element(11, Acc@1),
erlang:element(12, Acc@1),
erlang:element(13, Acc@1)};
<<"q"/utf8>> ->
New_black_queen_bitboard = board:from_position(
{position, File_index@1, Rank_index@1}
),
{board_bb,
erlang:element(2, Acc@1),
bitboard:'or'(
erlang:element(3, Acc@1),
New_black_queen_bitboard
),
erlang:element(4, Acc@1),
erlang:element(5, Acc@1),
erlang:element(6, Acc@1),
erlang:element(7, Acc@1),
erlang:element(8, Acc@1),
erlang:element(9, Acc@1),
erlang:element(10, Acc@1),
erlang:element(11, Acc@1),
erlang:element(12, Acc@1),
erlang:element(13, Acc@1)};
<<"r"/utf8>> ->
New_black_rook_bitboard = board:from_position(
{position, File_index@1, Rank_index@1}
),
{board_bb,
erlang:element(2, Acc@1),
erlang:element(3, Acc@1),
bitboard:'or'(
erlang:element(4, Acc@1),
New_black_rook_bitboard
),
erlang:element(5, Acc@1),
erlang:element(6, Acc@1),
erlang:element(7, Acc@1),
erlang:element(8, Acc@1),
erlang:element(9, Acc@1),
erlang:element(10, Acc@1),
erlang:element(11, Acc@1),
erlang:element(12, Acc@1),
erlang:element(13, Acc@1)};
<<"b"/utf8>> ->
New_black_bishop_bitboard = board:from_position(
{position, File_index@1, Rank_index@1}
),
{board_bb,
erlang:element(2, Acc@1),
erlang:element(3, Acc@1),
erlang:element(4, Acc@1),
bitboard:'or'(
erlang:element(5, Acc@1),
New_black_bishop_bitboard
),
erlang:element(6, Acc@1),
erlang:element(7, Acc@1),
erlang:element(8, Acc@1),
erlang:element(9, Acc@1),
erlang:element(10, Acc@1),
erlang:element(11, Acc@1),
erlang:element(12, Acc@1),
erlang:element(13, Acc@1)};
<<"n"/utf8>> ->
New_black_knight_bitboard = board:from_position(
{position, File_index@1, Rank_index@1}
),
{board_bb,
erlang:element(2, Acc@1),
erlang:element(3, Acc@1),
erlang:element(4, Acc@1),
erlang:element(5, Acc@1),
bitboard:'or'(
erlang:element(6, Acc@1),
New_black_knight_bitboard
),
erlang:element(7, Acc@1),
erlang:element(8, Acc@1),
erlang:element(9, Acc@1),
erlang:element(10, Acc@1),
erlang:element(11, Acc@1),
erlang:element(12, Acc@1),
erlang:element(13, Acc@1)};
<<"p"/utf8>> ->
New_black_pawns_bitboard = board:from_position(
{position, File_index@1, Rank_index@1}
),
{board_bb,
erlang:element(2, Acc@1),
erlang:element(3, Acc@1),
erlang:element(4, Acc@1),
erlang:element(5, Acc@1),
erlang:element(6, Acc@1),
bitboard:'or'(
erlang:element(7, Acc@1),
New_black_pawns_bitboard
),
erlang:element(8, Acc@1),
erlang:element(9, Acc@1),
erlang:element(10, Acc@1),
erlang:element(11, Acc@1),
erlang:element(12, Acc@1),
erlang:element(13, Acc@1)};
_ ->
erlang:error(#{gleam_error => panic,
message => <<"panic expression evaluated"/utf8>>,
module => <<"fen"/utf8>>,
function => <<"parse_board"/utf8>>,
line => 628})
end
end
)
end
).
-spec to_board(binary()) -> board:board_bb().
to_board(Fen) ->
Fen_string_parts = gleam@string:split(Fen, <<" "/utf8>>),
Parsed_board@1 = case gleam@list:length(Fen_string_parts) =:= 6 of
false ->
erlang:error(#{gleam_error => panic,
message => <<"Invalid FEN string"/utf8>>,
module => <<"fen"/utf8>>,
function => <<"to_board"/utf8>>,
line => 107});
true ->
[Board_string | _] = Fen_string_parts,
Parsed_board = parse_board(Board_string),
Parsed_board
end,
Parsed_board@1.
-spec parse_turn(binary()) -> color:color().
parse_turn(Turn_string) ->
case Turn_string of
<<"w"/utf8>> ->
white;
<<"b"/utf8>> ->
black;
_ ->
erlang:error(#{gleam_error => panic,
message => <<"Invalid turn string, must be 'w' or 'b'"/utf8>>,
module => <<"fen"/utf8>>,
function => <<"parse_turn"/utf8>>,
line => 674})
end.
-spec parse_castling(binary()) -> castling_status().
parse_castling(Castling_string) ->
case gleam@string:length(Castling_string) =< 4 of
true ->
Cs_parts = gleam@string:split(Castling_string, <<""/utf8>>),
gleam@list:each(Cs_parts, fun(Part) -> case Part of
<<"K"/utf8>> ->
nil;
<<"Q"/utf8>> ->
nil;
<<"k"/utf8>> ->
nil;
<<"q"/utf8>> ->
nil;
<<"-"/utf8>> ->
nil;
_ ->
erlang:error(#{gleam_error => panic,
message => <<"Invalid castling string"/utf8>>,
module => <<"fen"/utf8>>,
function => <<"parse_castling"/utf8>>,
line => 691})
end end),
White_queenside_castling = gleam@string:contains(
Castling_string,
<<"Q"/utf8>>
),
White_kingside_castling = gleam@string:contains(
Castling_string,
<<"K"/utf8>>
),
Black_queenside_castling = gleam@string:contains(
Castling_string,
<<"q"/utf8>>
),
Black_kingside_castling = gleam@string:contains(
Castling_string,
<<"k"/utf8>>
),
{castling_status,
White_kingside_castling,
White_queenside_castling,
Black_kingside_castling,
Black_queenside_castling};
false ->
erlang:error(#{gleam_error => panic,
message => <<"Invalid castling string"/utf8>>,
module => <<"fen"/utf8>>,
function => <<"parse_castling"/utf8>>,
line => 707})
end.
-spec parse_file(binary()) -> position:file().
parse_file(File_string) ->
case File_string of
<<"a"/utf8>> ->
a;
<<"b"/utf8>> ->
b;
<<"c"/utf8>> ->
c;
<<"d"/utf8>> ->
d;
<<"e"/utf8>> ->
e;
<<"f"/utf8>> ->
f;
<<"g"/utf8>> ->
g;
<<"h"/utf8>> ->
h;
_ ->
erlang:error(#{gleam_error => panic,
message => <<"Invalid file string"/utf8>>,
module => <<"fen"/utf8>>,
function => <<"parse_file"/utf8>>,
line => 738})
end.
-spec parse_rank(binary()) -> position:rank().
parse_rank(Rank_string) ->
case Rank_string of
<<"1"/utf8>> ->
one;
<<"2"/utf8>> ->
two;
<<"3"/utf8>> ->
three;
<<"4"/utf8>> ->
four;
<<"5"/utf8>> ->
five;
<<"6"/utf8>> ->
six;
<<"7"/utf8>> ->
seven;
<<"8"/utf8>> ->
eight;
_ ->
erlang:error(#{gleam_error => panic,
message => <<"Invalid rank string"/utf8>>,
module => <<"fen"/utf8>>,
function => <<"parse_rank"/utf8>>,
line => 752})
end.
-spec parse_en_passant(binary()) -> gleam@option:option(position:position()).
parse_en_passant(En_passant_string) ->
case En_passant_string of
<<"-"/utf8>> ->
none;
_ ->
case gleam@string:length(En_passant_string) =:= 2 of
true ->
nil;
false ->
erlang:error(#{gleam_error => panic,
message => <<"Invalid en passant string"/utf8>>,
module => <<"fen"/utf8>>,
function => <<"parse_en_passant"/utf8>>,
line => 717})
end,
En_passant_parts = gleam@string:split(
En_passant_string,
<<""/utf8>>
),
[File_string, Rank_string] = En_passant_parts,
File = parse_file(File_string),
Rank = parse_rank(Rank_string),
{some, {position, File, Rank}}
end.
-spec string_to_int(binary()) -> integer().
string_to_int(String) ->
case gleam@string:length(String) of
1 ->
case String of
<<"0"/utf8>> ->
0;
<<"1"/utf8>> ->
1;
<<"2"/utf8>> ->
2;
<<"3"/utf8>> ->
3;
<<"4"/utf8>> ->
4;
<<"5"/utf8>> ->
5;
<<"6"/utf8>> ->
6;
<<"7"/utf8>> ->
7;
<<"8"/utf8>> ->
8;
<<"9"/utf8>> ->
9;
_ ->
erlang:error(#{gleam_error => panic,
message => <<"Invalid halfmove string"/utf8>>,
module => <<"fen"/utf8>>,
function => <<"string_to_int"/utf8>>,
line => 778})
end;
2 ->
[Tenths_place_string, Ones_place_string] = gleam@string:split(
String,
<<""/utf8>>
),
Tenths_place = case Tenths_place_string of
<<"0"/utf8>> ->
0;
<<"1"/utf8>> ->
10;
<<"2"/utf8>> ->
20;
<<"3"/utf8>> ->
30;
<<"4"/utf8>> ->
40;
<<"5"/utf8>> ->
50;
<<"6"/utf8>> ->
60;
<<"7"/utf8>> ->
70;
<<"8"/utf8>> ->
80;
<<"9"/utf8>> ->
90;
_ ->
erlang:error(#{gleam_error => panic,
message => <<"Invalid halfmove string"/utf8>>,
module => <<"fen"/utf8>>,
function => <<"string_to_int"/utf8>>,
line => 794})
end,
Ones_place = case Ones_place_string of
<<"0"/utf8>> ->
0;
<<"1"/utf8>> ->
1;
<<"2"/utf8>> ->
2;
<<"3"/utf8>> ->
3;
<<"4"/utf8>> ->
4;
<<"5"/utf8>> ->
5;
<<"6"/utf8>> ->
6;
<<"7"/utf8>> ->
7;
<<"8"/utf8>> ->
8;
<<"9"/utf8>> ->
9;
_ ->
erlang:error(#{gleam_error => panic,
message => <<"Invalid halfmove string"/utf8>>,
module => <<"fen"/utf8>>,
function => <<"string_to_int"/utf8>>,
line => 808})
end,
Tenths_place + Ones_place;
3 ->
[Hundreds_place_string, Tenths_place_string@1, Ones_place_string@1] = gleam@string:split(
String,
<<""/utf8>>
),
Hundreds_place = case Hundreds_place_string of
<<"0"/utf8>> ->
0;
<<"1"/utf8>> ->
100;
<<"2"/utf8>> ->
200;
<<"3"/utf8>> ->
300;
<<"4"/utf8>> ->
400;
<<"5"/utf8>> ->
500;
<<"6"/utf8>> ->
600;
<<"7"/utf8>> ->
700;
<<"8"/utf8>> ->
800;
<<"9"/utf8>> ->
900;
_ ->
erlang:error(#{gleam_error => panic,
message => <<"Invalid halfmove string"/utf8>>,
module => <<"fen"/utf8>>,
function => <<"string_to_int"/utf8>>,
line => 826})
end,
Tenths_place@1 = case Tenths_place_string@1 of
<<"0"/utf8>> ->
0;
<<"1"/utf8>> ->
10;
<<"2"/utf8>> ->
20;
<<"3"/utf8>> ->
30;
<<"4"/utf8>> ->
40;
<<"5"/utf8>> ->
50;
<<"6"/utf8>> ->
60;
<<"7"/utf8>> ->
70;
<<"8"/utf8>> ->
80;
<<"9"/utf8>> ->
90;
_ ->
erlang:error(#{gleam_error => panic,
message => <<"Invalid halfmove string"/utf8>>,
module => <<"fen"/utf8>>,
function => <<"string_to_int"/utf8>>,
line => 840})
end,
Ones_place@1 = case Ones_place_string@1 of
<<"0"/utf8>> ->
0;
<<"1"/utf8>> ->
1;
<<"2"/utf8>> ->
2;
<<"3"/utf8>> ->
3;
<<"4"/utf8>> ->
4;
<<"5"/utf8>> ->
5;
<<"6"/utf8>> ->
6;
<<"7"/utf8>> ->
7;
<<"8"/utf8>> ->
8;
<<"9"/utf8>> ->
9;
_ ->
erlang:error(#{gleam_error => panic,
message => <<"Invalid halfmove string"/utf8>>,
module => <<"fen"/utf8>>,
function => <<"string_to_int"/utf8>>,
line => 854})
end,
(Hundreds_place + Tenths_place@1) + Ones_place@1;
_ ->
erlang:error(#{gleam_error => panic,
message => <<"Invalid halfmove string"/utf8>>,
module => <<"fen"/utf8>>,
function => <<"string_to_int"/utf8>>,
line => 858})
end.
-spec parse_halfmove(binary()) -> integer().
parse_halfmove(Halfmove_string) ->
string_to_int(Halfmove_string).
-spec parse_fullmove(binary()) -> integer().
parse_fullmove(Fullmove_string) ->
string_to_int(Fullmove_string).
-spec from_string(binary()) -> fen().
from_string(Fen) ->
Fen_string_parts = gleam@string:split(Fen, <<" "/utf8>>),
case gleam@list:length(Fen_string_parts) =:= 6 of
false ->
erlang:error(#{gleam_error => panic,
message => <<"Invalid FEN string"/utf8>>,
module => <<"fen"/utf8>>,
function => <<"from_string"/utf8>>,
line => 270});
true ->
[Board_string | Rest] = Fen_string_parts,
[Turn_string | Rest@1] = Rest,
[Castling_string | Rest@2] = Rest@1,
[En_passant_string | Rest@3] = Rest@2,
[Halfmove_string | Rest@4] = Rest@3,
[Fullmove_string | _] = Rest@4,
Parsed_board = parse_board(Board_string),
Parsed_turn = parse_turn(Turn_string),
Parsed_castling = parse_castling(Castling_string),
Parsed_en_passant = parse_en_passant(En_passant_string),
Parsed_halfmove = parse_halfmove(Halfmove_string),
Parsed_fullmove = parse_fullmove(Fullmove_string),
Fen@1 = {fen,
Parsed_board,
Parsed_turn,
Parsed_castling,
Parsed_en_passant,
Parsed_halfmove,
Parsed_fullmove},
Fen@1
end.