aboutsummaryrefslogtreecommitdiff
path: root/tictactoe-2/apps/ttt_server
diff options
context:
space:
mode:
authorTrygve Laugstøl <trygvis@inamo.no>2024-03-04 09:15:01 +0100
committerTrygve Laugstøl <trygvis@inamo.no>2024-03-04 09:15:01 +0100
commitc34d7363b61a9e00c986b79793bf7cdc03e9ea99 (patch)
tree79c9121e2bff6bc938b7b36d1195e5759b163d2c /tictactoe-2/apps/ttt_server
parent0be77ac09408c13cc12b5953b9ac7459b549c202 (diff)
downloaderlang-workshop-c34d7363b61a9e00c986b79793bf7cdc03e9ea99.tar.gz
erlang-workshop-c34d7363b61a9e00c986b79793bf7cdc03e9ea99.tar.bz2
erlang-workshop-c34d7363b61a9e00c986b79793bf7cdc03e9ea99.tar.xz
erlang-workshop-c34d7363b61a9e00c986b79793bf7cdc03e9ea99.zip
wip
Diffstat (limited to 'tictactoe-2/apps/ttt_server')
-rw-r--r--tictactoe-2/apps/ttt_server/.gitignore20
-rw-r--r--tictactoe-2/apps/ttt_server/rebar.config2
-rw-r--r--tictactoe-2/apps/ttt_server/rebar.lock1
-rw-r--r--tictactoe-2/apps/ttt_server/src/ttt_server.app.src14
-rw-r--r--tictactoe-2/apps/ttt_server/src/ttt_server.erl93
-rw-r--r--tictactoe-2/apps/ttt_server/test/server_tests.erl14
6 files changed, 144 insertions, 0 deletions
diff --git a/tictactoe-2/apps/ttt_server/.gitignore b/tictactoe-2/apps/ttt_server/.gitignore
new file mode 100644
index 0000000..b0d808b
--- /dev/null
+++ b/tictactoe-2/apps/ttt_server/.gitignore
@@ -0,0 +1,20 @@
+_build/default/lib/.rebar3
+_build
+_checkouts
+_vendor
+.eunit
+*.o
+*.beam
+*.plt
+*.swp
+*.swo
+.erlang.cookie
+ebin
+log
+erl_crash.dump
+.rebar
+logs
+.idea
+*.iml
+rebar3.crashdump
+*~
diff --git a/tictactoe-2/apps/ttt_server/rebar.config b/tictactoe-2/apps/ttt_server/rebar.config
new file mode 100644
index 0000000..2656fd5
--- /dev/null
+++ b/tictactoe-2/apps/ttt_server/rebar.config
@@ -0,0 +1,2 @@
+{erl_opts, [debug_info]}.
+{deps, []}.
diff --git a/tictactoe-2/apps/ttt_server/rebar.lock b/tictactoe-2/apps/ttt_server/rebar.lock
new file mode 100644
index 0000000..57afcca
--- /dev/null
+++ b/tictactoe-2/apps/ttt_server/rebar.lock
@@ -0,0 +1 @@
+[].
diff --git a/tictactoe-2/apps/ttt_server/src/ttt_server.app.src b/tictactoe-2/apps/ttt_server/src/ttt_server.app.src
new file mode 100644
index 0000000..d3de90f
--- /dev/null
+++ b/tictactoe-2/apps/ttt_server/src/ttt_server.app.src
@@ -0,0 +1,14 @@
+{application, ttt_server,
+ [{description, "An OTP library"},
+ {vsn, "0.1.0"},
+ {registered, []},
+ {applications,
+ [kernel,
+ stdlib
+ ]},
+ {env,[]},
+ {modules, []},
+
+ {licenses, ["Apache-2.0"]},
+ {links, []}
+ ]}.
diff --git a/tictactoe-2/apps/ttt_server/src/ttt_server.erl b/tictactoe-2/apps/ttt_server/src/ttt_server.erl
new file mode 100644
index 0000000..62979e8
--- /dev/null
+++ b/tictactoe-2/apps/ttt_server/src/ttt_server.erl
@@ -0,0 +1,93 @@
+-module(ttt_server).
+
+-export([
+ start/0,
+ start_local/0,
+ stop/0,
+ stop/2,
+ loop/1,
+
+ start_game/1,
+ dump/1]).
+
+-import(ttt, [move/4, who_wins/1, format/1, empty_board/0]).
+
+-record(ttt_game, {
+ ref = make_ref(),
+ board,
+ player1,
+ player2}).
+
+-record(ttt_state, {
+ 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).
+
+start_game(Server) ->
+ Server ! {self(), start},
+ receive
+ {ok, Game} ->
+ io:format("Game started: ~w~n", [Game]),
+ {ok, Game};
+ X ->
+ io:format("Game start failed: ~w~n", [X]),
+ X
+ after 100 ->
+ io:format("timeout~n", []),
+ {timeout}
+ end.
+
+dump(Server) ->
+ Server ! dump.
+
+start_local() ->
+ InitialState = #ttt_state{},
+ spawn(?MODULE, loop, [InitialState]).
+
+start() ->
+ Pid = start_local(),
+ case global:register_name(?GLOBAL_NAME, Pid) of
+ yes ->
+ io:format("Server started, pid=~p~n", [Pid]);
+ X ->
+ io:format("Register name failed: ~p~n", [X]),
+ Pid ! stop
+ end.
+
+stop(Server, Pid) ->
+ Server ! {stop, Pid}.
+
+stop() ->
+ case global:whereis_name(?GLOBAL_NAME) of
+ undefined -> io:format("Server not running~n");
+ Pid -> Pid ! {stop, self()}
+ end.
diff --git a/tictactoe-2/apps/ttt_server/test/server_tests.erl b/tictactoe-2/apps/ttt_server/test/server_tests.erl
new file mode 100644
index 0000000..322f9ed
--- /dev/null
+++ b/tictactoe-2/apps/ttt_server/test/server_tests.erl
@@ -0,0 +1,14 @@
+-module(server_tests).
+
+-include_lib("eunit/include/eunit.hrl").
+
+simple_test() ->
+ Server = ttt_server:start_local(),
+ P1 = ttt_server:start_game(Server),
+ ?debugFmt("P1:~p~n", [P1]),
+ ttt_server:dump(Server),
+ ttt_server:stop(Server, self()),
+ ?assert(receive
+ ok -> true
+ after 100 -> false
+ end).