-module(game_server). -compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch]). -export([print_board/1, apply_move/2, apply_move_uci_string/2, apply_move_san_string/2, apply_move_raw/2, undo_move/1, all_legal_moves/1, get_fen/1, get_status/1, disable_status/1, new_game/1, new_game_from_fen/2, shutdown/1, new_server/0, load_pgn/1]). -export_type([message/0]). -type message() :: {all_legal_moves, gleam@erlang@process:subject(list(move:move()))} | {apply_move, gleam@erlang@process:subject({ok, game:game()} | {error, binary()}), move:move()} | {apply_move_uci_string, gleam@erlang@process:subject({ok, game:game()} | {error, binary()}), binary()} | {apply_move_san_string, gleam@erlang@process:subject({ok, game:game()} | {error, binary()}), binary()} | {apply_move_raw, gleam@erlang@process:subject({ok, game:game()} | {error, binary()}), move:move()} | {undo_move, gleam@erlang@process:subject({ok, game:game()} | {error, binary()})} | {get_state, gleam@erlang@process:subject(game:game())} | {get_side_to_move, gleam@erlang@process:subject(color:color())} | {get_fen, gleam@erlang@process:subject(binary())} | {get_status, gleam@erlang@process:subject(gleam@option:option(status:status()))} | {new_game, gleam@erlang@process:subject(game:game())} | {new_game_from_fen, gleam@erlang@process:subject({ok, game:game()} | {error, binary()}), binary()} | {disable_status, gleam@erlang@process:subject({ok, game:game()} | {error, nil})} | shutdown | {print_board, gleam@erlang@process:subject({ok, binary()} | {error, binary()})}. -spec print_board(gleam@erlang@process:subject(message())) -> {ok, binary()} | {error, binary()}. print_board(Game_actor) -> gleam@erlang@process:call( Game_actor, fun(Field@0) -> {print_board, Field@0} end, 1000 ). -spec apply_move(gleam@erlang@process:subject(message()), move:move()) -> {ok, game:game()} | {error, binary()}. apply_move(Game_actor, Move) -> gleam@erlang@process:call( Game_actor, fun(_capture) -> {apply_move, _capture, Move} end, 1000 ). -spec apply_move_uci_string(gleam@erlang@process:subject(message()), binary()) -> {ok, game:game()} | {error, binary()}. apply_move_uci_string(Game_actor, Move_uci) -> gleam@erlang@process:call( Game_actor, fun(_capture) -> {apply_move_uci_string, _capture, Move_uci} end, 1000 ). -spec apply_move_san_string(gleam@erlang@process:subject(message()), binary()) -> {ok, game:game()} | {error, binary()}. apply_move_san_string(Game_actor, Move_san) -> gleam@erlang@process:call( Game_actor, fun(_capture) -> {apply_move_san_string, _capture, Move_san} end, 1000 ). -spec apply_move_raw(gleam@erlang@process:subject(message()), move:move()) -> {ok, game:game()} | {error, binary()}. apply_move_raw(Game_actor, Move) -> gleam@erlang@process:call( Game_actor, fun(_capture) -> {apply_move_raw, _capture, Move} end, 1000 ). -spec undo_move(gleam@erlang@process:subject(message())) -> {ok, game:game()} | {error, binary()}. undo_move(Game_actor) -> gleam@erlang@process:call( Game_actor, fun(Field@0) -> {undo_move, Field@0} end, 1000 ). -spec all_legal_moves(gleam@erlang@process:subject(message())) -> list(move:move()). all_legal_moves(Game_actor) -> gleam@erlang@process:call( Game_actor, fun(Field@0) -> {all_legal_moves, Field@0} end, 1000 ). -spec get_fen(gleam@erlang@process:subject(message())) -> binary(). get_fen(Game_actor) -> gleam@erlang@process:call( Game_actor, fun(Field@0) -> {get_fen, Field@0} end, 1000 ). -spec get_status(gleam@erlang@process:subject(message())) -> gleam@option:option(status:status()). get_status(Game_actor) -> gleam@erlang@process:call( Game_actor, fun(Field@0) -> {get_status, Field@0} end, 1000 ). -spec disable_status(gleam@erlang@process:subject(message())) -> {ok, game:game()} | {error, nil}. disable_status(Game_actor) -> gleam@erlang@process:call( Game_actor, fun(Field@0) -> {disable_status, Field@0} end, 1000 ). -spec new_game(gleam@erlang@process:subject(message())) -> game:game(). new_game(Game_actor) -> gleam@erlang@process:call( Game_actor, fun(Field@0) -> {new_game, Field@0} end, 1000 ). -spec new_game_from_fen(gleam@erlang@process:subject(message()), binary()) -> {ok, game:game()} | {error, binary()}. new_game_from_fen(Game_actor, Fen) -> gleam@erlang@process:call( Game_actor, fun(_capture) -> {new_game_from_fen, _capture, Fen} end, 1000 ). -spec shutdown(gleam@erlang@process:subject(message())) -> nil. shutdown(Game_actor) -> gleam@erlang@process:send(Game_actor, shutdown). -spec handle_all_legal_moves( game:game(), gleam@erlang@process:subject(list(move:move())) ) -> {ok, gleam@otp@actor:next(message(), game:game())} | {error, binary()}. handle_all_legal_moves(Game, Client) -> gleam@result:'try'( game:all_legal_moves(Game), fun(All_legal_moves) -> gleam@erlang@process:send(Client, All_legal_moves), {ok, gleam@otp@actor:continue(Game)} end ). -spec handle_undo_move( game:game(), gleam@erlang@process:subject({ok, game:game()} | {error, binary()}) ) -> {ok, gleam@otp@actor:next(message(), game:game())} | {error, any()}. handle_undo_move(Game, Client) -> case game:undo_move(Game) of {ok, New_game_state} -> gleam@erlang@process:send(Client, {ok, New_game_state}), {ok, gleam@otp@actor:continue(New_game_state)}; {error, _} -> gleam@erlang@process:send( Client, {error, <<"Failed to undo move"/utf8>>} ), {ok, gleam@otp@actor:continue(Game)} end. -spec handle_apply_move_san_string( game:game(), gleam@erlang@process:subject({ok, game:game()} | {error, binary()}), binary() ) -> {ok, gleam@otp@actor:next(message(), game:game())} | {error, any()}. handle_apply_move_san_string(Game, Client, Move) -> case game:apply_move_san_string(Game, Move) of {ok, New_game_state} -> gleam@erlang@process:send(Client, {ok, New_game_state}), {ok, gleam@otp@actor:continue(New_game_state)}; {error, _} -> gleam@erlang@process:send( Client, {error, <<"Failed to apply move"/utf8>>} ), {ok, gleam@otp@actor:continue(Game)} end. -spec handle_apply_move_uci( game:game(), gleam@erlang@process:subject({ok, game:game()} | {error, binary()}), binary() ) -> {ok, gleam@otp@actor:next(message(), game:game())} | {error, any()}. handle_apply_move_uci(Game, Client, Move) -> case game:apply_move_uci(Game, Move) of {ok, New_game_state} -> gleam@erlang@process:send(Client, {ok, New_game_state}), {ok, gleam@otp@actor:continue(New_game_state)}; {error, _} -> gleam@erlang@process:send( Client, {error, <<"Failed to apply move"/utf8>>} ), {ok, gleam@otp@actor:continue(Game)} end. -spec handle_apply_move( game:game(), gleam@erlang@process:subject({ok, game:game()} | {error, binary()}), move:move() ) -> {ok, gleam@otp@actor:next(message(), game:game())} | {error, any()}. handle_apply_move(Game, Client, Move) -> case game:apply_move(Game, Move) of {ok, New_game_state} -> gleam@erlang@process:send(Client, {ok, New_game_state}), {ok, gleam@otp@actor:continue(New_game_state)}; {error, _} -> gleam@erlang@process:send( Client, {error, <<"Failed to apply move"/utf8>>} ), {ok, gleam@otp@actor:continue(Game)} end. -spec handle_apply_move_raw( game:game(), gleam@erlang@process:subject({ok, game:game()} | {error, binary()}), move:move() ) -> {ok, gleam@otp@actor:next(message(), game:game())} | {error, any()}. handle_apply_move_raw(Game, Client, Move) -> New_game_state = game:apply_move_raw(Game, Move), gleam@erlang@process:send(Client, New_game_state), {ok, case New_game_state of {ok, New_game_state@1} -> gleam@otp@actor:continue(New_game_state@1); {error, _} -> gleam@otp@actor:continue(Game) end}. -spec handle_get_fen(game:game(), gleam@erlang@process:subject(binary())) -> {ok, gleam@otp@actor:next(any(), game:game())} | {error, any()}. handle_get_fen(Game, Client) -> gleam@erlang@process:send(Client, game:to_fen(Game)), {ok, gleam@otp@actor:continue(Game)}. -spec handle_print_board( game:game(), gleam@erlang@process:subject({ok, binary()} | {error, binary()}) ) -> gleam@otp@actor:next(message(), game:game()). handle_print_board(Game, Client) -> gleam@erlang@process:send(Client, game:print_board(Game)), gleam@otp@actor:continue(Game). -spec handle_message(message(), game:game()) -> gleam@otp@actor:next(message(), game:game()). handle_message(Message, Game) -> case Message of {all_legal_moves, Client} -> case handle_all_legal_moves(Game, Client) of {ok, Next} -> Next; {error, _} -> gleam@otp@actor:continue(Game) end; {apply_move, Client@1, Move} -> case handle_apply_move(Game, Client@1, Move) of {ok, Next@1} -> Next@1; {error, _} -> gleam@otp@actor:continue(Game) end; {apply_move_uci_string, Client@2, Move@1} -> case handle_apply_move_uci(Game, Client@2, Move@1) of {ok, Next@2} -> Next@2; {error, _} -> gleam@otp@actor:continue(Game) end; {apply_move_san_string, Client@3, Move@2} -> case handle_apply_move_san_string(Game, Client@3, Move@2) of {ok, Next@3} -> Next@3; {error, _} -> gleam@otp@actor:continue(Game) end; {apply_move_raw, Client@4, Move@3} -> case handle_apply_move_raw(Game, Client@4, Move@3) of {ok, Next@4} -> Next@4; {error, _} -> gleam@otp@actor:continue(Game) end; {undo_move, Client@5} -> case handle_undo_move(Game, Client@5) of {ok, Next@5} -> Next@5; {error, _} -> gleam@otp@actor:continue(Game) end; {get_state, Client@6} -> gleam@erlang@process:send(Client@6, Game), gleam@otp@actor:continue(Game); {get_fen, Client@7} -> case handle_get_fen(Game, Client@7) of {ok, Next@6} -> Next@6; {error, _} -> gleam@otp@actor:continue(Game) end; {get_status, Client@8} -> gleam@erlang@process:send(Client@8, erlang:element(5, Game)), gleam@otp@actor:continue(Game); {get_side_to_move, Client@9} -> gleam@erlang@process:send(Client@9, erlang:element(3, Game)), gleam@otp@actor:continue(Game); {new_game, Client@10} -> New_game = game:new_game(), gleam@erlang@process:send(Client@10, New_game), gleam@otp@actor:continue(New_game); {new_game_from_fen, Client@11, Fen} -> case game:from_fen_string(Fen) of {ok, New_game@1} -> gleam@erlang@process:send(Client@11, {ok, New_game@1}), gleam@otp@actor:continue(New_game@1); {error, _} -> gleam@erlang@process:send( Client@11, {error, <<"Failed to create game from fen"/utf8>>} ), gleam@otp@actor:continue(Game) end; {disable_status, Client@12} -> New_game@2 = game:disable_status(Game), gleam@erlang@process:send(Client@12, {ok, New_game@2}), gleam@otp@actor:continue(New_game@2); shutdown -> {stop, normal}; {print_board, Client@13} -> handle_print_board(Game, Client@13) end. -spec new_server() -> {ok, gleam@erlang@process:subject(message())} | {error, gleam@otp@actor:start_error()}. new_server() -> gleam@otp@actor:start(game:new_game(), fun handle_message/2). -spec load_pgn(binary()) -> {ok, gleam@erlang@process:subject(message())} | {error, binary()}. load_pgn(Pgn_string) -> case game:load_pgn(Pgn_string) of {ok, Game} -> case gleam@otp@actor:start(Game, fun handle_message/2) of {ok, Actor} -> {ok, Actor}; {error, _} -> {error, <<"Failed to start actor"/utf8>>} end; {error, Error} -> {error, Error} end.