-module(position). -compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch]). -export([are_the_same/2, file_to_string/1, rank_to_string/1, to_string/1, file_to_int/1, rank_to_int/1, to_int/1, distance_between/2, to_bitboard/1, int_to_rank/1, int_to_file/1, from_int/1, get_file/2, get_file_relative/3, get_rank/2, get_position/3, get_rank_relative/3, get_position_relative/4, get_rear_white_rank/1, get_rear_black_rank/1, get_rear_rank/2, get_rear_position/2]). -export_type([position/0, file/0, rank/0]). -type position() :: {position, file(), rank()}. -type file() :: a | b | c | d | e | f | g | h. -type rank() :: one | two | three | four | five | six | seven | eight. -spec are_the_same(position(), position()) -> boolean(). are_the_same(Position1, Position2) -> (erlang:element(2, Position1) =:= erlang:element(2, Position2)) andalso (erlang:element( 3, Position1 ) =:= erlang:element(3, Position2)). -spec file_to_string(file()) -> binary(). file_to_string(File) -> case File of a -> <<"a"/utf8>>; b -> <<"b"/utf8>>; c -> <<"c"/utf8>>; d -> <<"d"/utf8>>; e -> <<"e"/utf8>>; f -> <<"f"/utf8>>; g -> <<"g"/utf8>>; h -> <<"h"/utf8>> end. -spec rank_to_string(rank()) -> binary(). rank_to_string(Rank) -> case Rank of one -> <<"1"/utf8>>; two -> <<"2"/utf8>>; three -> <<"3"/utf8>>; four -> <<"4"/utf8>>; five -> <<"5"/utf8>>; six -> <<"6"/utf8>>; seven -> <<"7"/utf8>>; eight -> <<"8"/utf8>> end. -spec to_string(position()) -> binary(). to_string(Position) -> File = file_to_string(erlang:element(2, Position)), Rank = rank_to_string(erlang:element(3, Position)), Pos_as_string = <>, Pos_as_string. -spec file_to_int(file()) -> integer(). file_to_int(File) -> case File of a -> 0; b -> 1; c -> 2; d -> 3; e -> 4; f -> 5; g -> 6; h -> 7 end. -spec rank_to_int(rank()) -> integer(). rank_to_int(Rank) -> case Rank of one -> 0; two -> 1; three -> 2; four -> 3; five -> 4; six -> 5; seven -> 6; eight -> 7 end. -spec to_int(position()) -> integer(). to_int(Position) -> File = file_to_int(erlang:element(2, Position)), Rank = rank_to_int(erlang:element(3, Position)), Pos_as_int = File + (Rank * 8), Pos_as_int. -spec distance_between(position(), position()) -> integer(). distance_between(Position1, Position2) -> Pos1_as_int = to_int(Position1), Pos2_as_int = to_int(Position2), Distance = Pos1_as_int - Pos2_as_int, Distance. -spec to_bitboard(position()) -> integer(). to_bitboard(Position) -> Pos_as_int = to_int(Position), Bitboard = bitboard:shift_left(1, Pos_as_int), Bitboard. -spec int_to_rank(integer()) -> rank(). int_to_rank(I) -> case I of 0 -> one; 1 -> two; 2 -> three; 3 -> four; 4 -> five; 5 -> six; 6 -> seven; 7 -> eight; _ -> erlang:error(#{gleam_error => panic, message => <<"panic expression evaluated"/utf8>>, module => <<"position"/utf8>>, function => <<"int_to_rank"/utf8>>, line => 135}) end. -spec int_to_file(integer()) -> file(). int_to_file(I) -> case I of 0 -> a; 1 -> b; 2 -> c; 3 -> d; 4 -> e; 5 -> f; 6 -> g; 7 -> h; _ -> erlang:error(#{gleam_error => panic, message => <<"panic expression evaluated"/utf8>>, module => <<"position"/utf8>>, function => <<"int_to_file"/utf8>>, line => 150}) end. -spec from_int(integer()) -> {ok, position()} | {error, binary()}. from_int(I) -> case I of I@1 when (I@1 >= 0) andalso (I@1 < 64) -> File = int_to_file(I@1 rem 8), Rank = int_to_rank(I@1 div 8), {ok, {position, File, Rank}}; _ -> {error, <<"Invalid position"/utf8>>} end. -spec get_file(file(), integer()) -> file(). get_file(File, Y) -> File_as_int = file_to_int(File), New_file_as_int = File_as_int + Y, New_file = int_to_file(New_file_as_int), New_file. -spec get_file_relative(file(), integer(), color:color()) -> file(). get_file_relative(File, Y, Relative_to) -> case Relative_to of white -> get_file(File, Y); black -> get_file(File, - Y) end. -spec get_rank(rank(), integer()) -> rank(). get_rank(Rank, X) -> Rank_as_int = rank_to_int(Rank), New_rank_as_int = Rank_as_int + X, New_rank = int_to_rank(New_rank_as_int), New_rank. -spec get_position(position(), integer(), integer()) -> position(). get_position(Position, X, Y) -> File = get_file(erlang:element(2, Position), Y), Rank = get_rank(erlang:element(3, Position), X), {position, File, Rank}. -spec get_rank_relative(rank(), integer(), color:color()) -> rank(). get_rank_relative(Rank, X, Relative_to) -> case Relative_to of white -> get_rank(Rank, X); black -> get_rank(Rank, - X) end. -spec get_position_relative(position(), integer(), integer(), color:color()) -> position(). get_position_relative(Position, X, Y, Relative_to) -> File = get_file_relative(erlang:element(2, Position), Y, Relative_to), Rank = get_rank_relative(erlang:element(3, Position), X, Relative_to), {position, File, Rank}. -spec get_rear_white_rank(rank()) -> rank(). get_rear_white_rank(Rank) -> case Rank of one -> one; two -> one; three -> two; four -> three; five -> four; six -> five; seven -> six; eight -> seven end. -spec get_rear_black_rank(rank()) -> rank(). get_rear_black_rank(Rank) -> case Rank of one -> two; two -> three; three -> four; four -> five; five -> six; six -> seven; seven -> eight; eight -> eight end. -spec get_rear_rank(rank(), color:color()) -> rank(). get_rear_rank(Rank, Color) -> case Color of white -> get_rear_white_rank(Rank); black -> get_rear_black_rank(Rank) end. -spec get_rear_position(position(), color:color()) -> position(). get_rear_position(Position, Color) -> Rank = get_rear_rank(erlang:element(3, Position), Color), {position, erlang:element(2, Position), Rank}.