-module(game_server). -compile([no_auto_import, nowarn_unused_vars]). -export([print_board/1, apply_move/2, apply_move_uci/2, undo_move/1, all_legal_moves/1, get_fen/1, from_fen/1, new_game/0]). -export_type([message/0]). -type message() :: {all_legal_moves, gleam@erlang@process:subject(list(move:move()))} | {apply_move, gleam@erlang@process:subject(game:game()), move:move()} | {apply_move_uci, gleam@erlang@process:subject(game:game()), binary()} | {undo_move, gleam@erlang@process:subject(game:game())} | {get_fen, gleam@erlang@process:subject(binary())} | shutdown | {print_board, gleam@erlang@process:subject(nil)}. -spec print_board(gleam@erlang@process:subject(message())) -> nil. 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()) -> game:game(). apply_move(Game_actor, Move) -> gleam@erlang@process:call( Game_actor, fun(_capture) -> {apply_move, _capture, Move} end, 1000 ). -spec apply_move_uci(gleam@erlang@process:subject(message()), binary()) -> game:game(). apply_move_uci(Game_actor, Move_uci) -> gleam@erlang@process:call( Game_actor, fun(_capture) -> {apply_move_uci, _capture, Move_uci} end, 1000 ). -spec undo_move(gleam@erlang@process:subject(message())) -> game:game(). 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 handle_all_legal_moves( game:game(), gleam@erlang@process:subject(list(move:move())) ) -> gleam@otp@actor:next(message(), game:game()). handle_all_legal_moves(Game, Client) -> gleam@erlang@process:send(Client, game:all_legal_moves(Game)), gleam@otp@actor:continue(Game). -spec handle_undo_move(game:game(), gleam@erlang@process:subject(game:game())) -> gleam@otp@actor:next(any(), game:game()). handle_undo_move(Game, Client) -> New_game_state = game:undo_move(Game), gleam@erlang@process:send(Client, New_game_state), gleam@otp@actor:continue(New_game_state). -spec handle_apply_move_uci( game:game(), gleam@erlang@process:subject(game:game()), binary() ) -> gleam@otp@actor:next(any(), game:game()). handle_apply_move_uci(Game, Client, Move) -> New_game_state = game:apply_move_uci(Game, Move), gleam@erlang@process:send(Client, New_game_state), gleam@otp@actor:continue(New_game_state). -spec handle_apply_move( game:game(), gleam@erlang@process:subject(game:game()), move:move() ) -> gleam@otp@actor:next(any(), game:game()). handle_apply_move(Game, Client, Move) -> New_game_state = game:apply_move(Game, Move), gleam@erlang@process:send(Client, New_game_state), gleam@otp@actor:continue(New_game_state). -spec handle_get_fen(game:game(), gleam@erlang@process:subject(binary())) -> gleam@otp@actor:next(any(), game:game()). handle_get_fen(Game, Client) -> gleam@erlang@process:send(Client, game:to_fen(Game)), gleam@otp@actor:continue(Game). -spec handle_print_board(game:game(), gleam@erlang@process:subject(nil)) -> gleam@otp@actor:next(message(), game:game()). handle_print_board(Game, Client) -> game:print_board(Game), gleam@erlang@process:send(Client, nil), 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} -> handle_all_legal_moves(Game, Client); {apply_move, Client@1, Move} -> handle_apply_move(Game, Client@1, Move); {apply_move_uci, Client@2, Move@1} -> handle_apply_move_uci(Game, Client@2, Move@1); {undo_move, Client@3} -> handle_undo_move(Game, Client@3); {get_fen, Client@4} -> handle_get_fen(Game, Client@4); shutdown -> {stop, normal}; {print_board, Client@5} -> handle_print_board(Game, Client@5) end. -spec from_fen(binary()) -> gleam@erlang@process:subject(message()). from_fen(Fen_string) -> Fen = fen:from_string(Fen_string), Status = in_progress, Ply = case erlang:element(3, Fen) of white -> (erlang:element(7, Fen) - 1) * 2; black -> ((erlang:element(7, Fen) - 1) * 2) + 1 end, White_kingside_castle = case erlang:element(2, erlang:element(4, Fen)) of true -> yes; false -> {no, 1} end, White_queenside_castle = case erlang:element(3, erlang:element(4, Fen)) of true -> yes; false -> {no, 1} end, Black_kingside_castle = case erlang:element(4, erlang:element(4, Fen)) of true -> yes; false -> {no, 2} end, Black_queenside_castle = case erlang:element(5, erlang:element(4, Fen)) of true -> yes; false -> {no, 2} end, Game = {game, erlang:element(2, Fen), erlang:element(3, Fen), [], {some, Status}, Ply, erlang:element(6, Fen), White_kingside_castle, White_queenside_castle, Black_kingside_castle, Black_queenside_castle, erlang:element(5, Fen)}, _assert_subject = gleam@otp@actor:start(Game, fun handle_message/2), {ok, Actor} = case _assert_subject of {ok, _} -> _assert_subject; _assert_fail -> erlang:error(#{gleam_error => let_assert, message => <<"Assertion pattern match failed"/utf8>>, value => _assert_fail, module => <<"game_server"/utf8>>, function => <<"from_fen"/utf8>>, line => 148}) end, Actor. -spec new_game() -> gleam@erlang@process:subject(message()). new_game() -> White_king_bitboard = {bitboard, 2#0000000000000000000000000000000000000000000000000000000000001000}, White_queen_bitboard = {bitboard, 2#0000000000000000000000000000000000000000000000000000000000010000}, White_rook_bitboard = {bitboard, 2#0000000000000000000000000000000000000000000000000000000010000001}, White_bishop_bitboard = {bitboard, 2#0000000000000000000000000000000000000000000000000000000000100100}, White_knight_bitboard = {bitboard, 2#0000000000000000000000000000000000000000000000000000000001000010}, White_pawns_bitboard = {bitboard, 2#0000000000000000000000000000000000000000000000001111111100000000}, Black_king_bitboard = {bitboard, 2#0000100000000000000000000000000000000000000000000000000000000000}, Black_queen_bitboard = {bitboard, 2#0001000000000000000000000000000000000000000000000000000000000000}, Black_rook_bitboard = {bitboard, 2#1000000100000000000000000000000000000000000000000000000000000000}, Black_bishop_bitboard = {bitboard, 2#0010010000000000000000000000000000000000000000000000000000000000}, Black_knight_bitboard = {bitboard, 2#0100001000000000000000000000000000000000000000000000000000000000}, Black_pawns_bitboard = {bitboard, 2#0000000011111111000000000000000000000000000000000000000000000000}, Board = {board_bb, Black_king_bitboard, Black_queen_bitboard, Black_rook_bitboard, Black_bishop_bitboard, Black_knight_bitboard, Black_pawns_bitboard, White_king_bitboard, White_queen_bitboard, White_rook_bitboard, White_bishop_bitboard, White_knight_bitboard, White_pawns_bitboard}, Turn = white, History = [], Status = in_progress, Ply = 0, _assert_subject = gleam@otp@actor:start( {game, Board, Turn, History, {some, Status}, Ply, 0, yes, yes, yes, yes, none}, fun handle_message/2 ), {ok, Actor} = case _assert_subject of {ok, _} -> _assert_subject; _assert_fail -> erlang:error(#{gleam_error => let_assert, message => <<"Assertion pattern match failed"/utf8>>, value => _assert_fail, module => <<"game_server"/utf8>>, function => <<"new_game"/utf8>>, line => 237}) end, Actor.