aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTrygve Laugstøl <trygvis@inamo.no>2024-03-05 21:28:46 +0100
committerTrygve Laugstøl <trygvis@inamo.no>2024-03-05 21:28:46 +0100
commit900bda5f4c60898c07e81ff25be57ffc835b68d8 (patch)
tree89bdc84b235c551f235aab6dd1a56d0cfb36eae8
parentc34d7363b61a9e00c986b79793bf7cdc03e9ea99 (diff)
downloaderlang-workshop-900bda5f4c60898c07e81ff25be57ffc835b68d8.tar.gz
erlang-workshop-900bda5f4c60898c07e81ff25be57ffc835b68d8.tar.bz2
erlang-workshop-900bda5f4c60898c07e81ff25be57ffc835b68d8.tar.xz
erlang-workshop-900bda5f4c60898c07e81ff25be57ffc835b68d8.zip
wip
-rw-r--r--tictactoe-2/apps/ttt_server/src/game.erl36
-rw-r--r--tictactoe-2/apps/ttt_server/src/ttt_server.erl72
2 files changed, 76 insertions, 32 deletions
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() ->