From 900bda5f4c60898c07e81ff25be57ffc835b68d8 Mon Sep 17 00:00:00 2001 From: Trygve Laugstøl Date: Tue, 5 Mar 2024 21:28:46 +0100 Subject: wip --- tictactoe-2/apps/ttt_server/src/game.erl | 36 +++++++++++++ tictactoe-2/apps/ttt_server/src/ttt_server.erl | 72 ++++++++++++++------------ 2 files changed, 76 insertions(+), 32 deletions(-) create mode 100644 tictactoe-2/apps/ttt_server/src/game.erl diff --git a/tictactoe-2/apps/ttt_server/src/game.erl b/tictactoe-2/apps/ttt_server/src/game.erl new file mode 100644 index 0000000..8c6550a --- /dev/null +++ b/tictactoe-2/apps/ttt_server/src/game.erl @@ -0,0 +1,36 @@ +-module(game). +-author("trygvis"). + +-export([ + game_loop/2]). + +-import(ttt, [empty_board/0]). + +-record(state, { + id, + board = ttt:empty_board(), + player1, + player2}). + +game_loop(Id, Player1) -> loop(#state{ + id = Id, + player1 = Player1}). + +loop(State) -> + Id = State#state.id, + receive + {From, join} when not is_pid(State#state.player2) -> + io:format("game ~p: player joined: ~p~n", [Id, From]), + From ! {joined, State#state.id}, + loop(#state{player2 = From}); + {From, join} -> + io:format("game ~p: busy: ~p~n", [Id, From]), + From ! {busy}, + loop(State); + {From, show} -> + Str = ttt:format(State#state.board), + io:format("game ~p: current state:~n~p~n", [Id, Str]), + From ! Str, + loop(State) + end, + State. diff --git a/tictactoe-2/apps/ttt_server/src/ttt_server.erl b/tictactoe-2/apps/ttt_server/src/ttt_server.erl index 62979e8..c7167fb 100644 --- a/tictactoe-2/apps/ttt_server/src/ttt_server.erl +++ b/tictactoe-2/apps/ttt_server/src/ttt_server.erl @@ -11,46 +11,54 @@ dump/1]). -import(ttt, [move/4, who_wins/1, format/1, empty_board/0]). +-import(orddict, [new/0]). +-import(game, [game_loop/0]). -record(ttt_game, { - ref = make_ref(), - board, - player1, - player2}). + id :: integer(), + pid :: pid()}). -record(ttt_state, { + seq = 1000 :: integer(), games = []}). -define(GLOBAL_NAME, ttt). loop(State) -> - _State = - receive - {Player1, start} when is_pid(Player1) -> - Board = ttt:empty_board(), - io:format("board:~n~s~n", [ttt:format(Board)]), - Game = #ttt_game{board = Board, player1 = Player1}, - #ttt_state{games = [Game, State#ttt_state.games]}, - Player1 ! {ok, Game#ttt_game.ref}; - dump -> - io:format("Server state:~n~p~n", [State]), - State; - stop -> - io:format("Exiting~n", []), - exit(normal); - {stop, Pid} -> - Pid ! ok, - exit(normal); - X -> - io:format("unexpected message: ~p~n", [X]), - State - end, - case _State of - _ when _State =/= State -> - io:format("New State: ~p~n", [_State]); - _ -> _State - end, - ?MODULE:loop(_State). + receive + {Player, create} -> + io:format("Creating game for player ~p~n", [Player]), + Id = State#ttt_state.seq, + Pid = spawn(game, game_loop, [Id, Player]), + Game = #ttt_game{id = Id, pid = Pid}, + Player ! {ok, Id}, + io:format("Game created: ~p/~p~n", [Id, Pid]), + loop(#ttt_state{ + seq = Id + 1, + games = orddict:append(Id, Game, State#ttt_state.games)}); + {Player, show, Ref} -> + case orddict:find(Ref, State#ttt_state.games) of + error -> + Player ! no_such_game; + {ok, [Game]} -> + io:format("show: ~p~n", [Game]), + Game#ttt_game.pid ! {Player, show} + end, + loop(State); + dump -> + io:format("Server state:~n~p~n", [State]), + loop(State); + stop -> + io:format("Exiting~n", []); + {stop, Pid} -> + Pid ! ok; + recompiled -> + io:format("Reloading~n", []), + ?MODULE:loop(State); + X -> + io:format("unexpected message: ~p~n", [X]), + loop(State) + end. start_game(Server) -> Server ! {self(), start}, @@ -70,7 +78,7 @@ dump(Server) -> Server ! dump. start_local() -> - InitialState = #ttt_state{}, + InitialState = #ttt_state{games = orddict:new()}, spawn(?MODULE, loop, [InitialState]). start() -> -- cgit v1.2.3