Download:
child 36:4d40c4b8e8b0
parent 34:19dac34d9a51
35:1963573a943e
Anton Shestakov <engored@ya.ru>, Mon, 03 Mar 2014 19:46:02 +0900
Make rps3 a gen_server under the hood.

2 файлов изменено, 52 вставок(+), 17 удалений(-) [+]
src/rps.erl file | annotate | diff | comparison | revisions
src/rps3.erl file | annotate | diff | comparison | revisions
--- a/src/rps.erl Mon Mar 03 15:42:17 2014 +0900
+++ b/src/rps.erl Mon Mar 03 19:46:02 2014 +0900
@@ -4,10 +4,11 @@
lobby/0, counter/0, printer/0]).
-define(BOTS, [fool, copycat, gambler]).
--define(RULES, rps5).
+-define(RULES, rps3).
go() ->
rps_nickserv:start_link(),
+ rps3:start_link(),
register(lobby, spawn_link(?MODULE, lobby, [])),
register(counter, spawn_link(?MODULE, counter, [])),
register(printer, spawn_link(?MODULE, printer, [])),
--- a/src/rps3.erl Mon Mar 03 15:42:17 2014 +0900
+++ b/src/rps3.erl Mon Mar 03 19:46:02 2014 +0900
@@ -1,19 +1,31 @@
-module(rps3).
--export([get_hands/0, winning_hand/1]).
+-behaviour(gen_server).
+-export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3]).
+-export([start_link/0, get_hands/0, winning_hand/1, why/2]).
-get_hands() -> [rock, paper, scissors].
+-record(state, {hands=[], beats=dict:new(), loses=dict:new(), why=dict:new()}).
-beats(H, [H|Tail]) ->
- lists:last(Tail);
+start_link() ->
+ gen_server:start_link({local, ?MODULE}, ?MODULE, [], []).
-beats(H, [B,H|_]) ->
- B;
+parse_rules([V1,Label,V2|T], #state{hands=Hands, beats=Beats, loses=Loses, why=Why}) ->
+ Acc = #state{
+ hands=[V1|Hands],
+ beats=dict:append(V1, V2, Beats),
+ loses=dict:append(V2, V1, Loses),
+ why=dict:store({V1, V2}, Label, Why)},
+ parse_rules([V2|T], Acc);
-beats(H, [_|T]) ->
- beats(H, T).
+parse_rules([_V2], Acc) ->
+ Acc.
-loses(H) ->
- beats(H, lists:reverse(get_hands())).
+init([]) ->
+ Text = "scissors cut paper covers rock crushes scissors",
+ Tokens = lists:map(fun list_to_atom/1, string:tokens(Text, " ")),
+ {ok, parse_rules(Tokens, #state{})}.
+
+handle_call(get_hands, _From, State=#state{hands=Hands}) ->
+ {reply, Hands, State};
% winner for 3 hands is:
% rock, rock, rock -> rock
@@ -21,12 +33,34 @@
% rock, paper, paper -> paper
% rock, rock, paper -> paper
-winning_hand(Hands) ->
+handle_call({winning_hand, Hands}, _From, State) ->
HSet = sets:from_list(Hands),
- sets:fold(
+ WHand = sets:fold(
fun(Hand, Acc) ->
- case sets:is_element(loses(Hand), HSet) of
- true -> Acc;
- false -> Hand
+ Loses = dict:fetch(Hand, State#state.loses),
+ case sets:is_disjoint(sets:from_list(Loses), HSet) of
+ false -> Acc;
+ true -> Hand
end
- end, undefined, HSet).
+ end, undefined, HSet),
+ {reply, WHand, State};
+
+handle_call({why, H1, H2}, _From, State=#state{why=Why}) ->
+ {reply, dict:fetch({H1, H2}, Why), State}.
+
+handle_cast(_Msg, State) -> {noreply, State}.
+
+handle_info(_Msg, State) -> {noreply, State}.
+
+terminate(_Reason, _State) -> ok.
+
+code_change(_OldVersion, State, _Extra) -> {ok, State}.
+
+get_hands() ->
+ gen_server:call(?MODULE, get_hands).
+
+winning_hand(Hands) ->
+ gen_server:call(?MODULE, {winning_hand, Hands}).
+
+why(H1, H2) ->
+ gen_server:call(?MODULE, {why, H1, H2}).