54:2e633dc02528 default tip
Anton Shestakov <engored@ya.ru>, Sat, 08 Mar 2014 23:46:38 +0900
Strictly speaking, rps_rules has no state.

previous change 51:24ba56a575b1

src/rps_rules.erl

Permissions: -rw-r--r--

Other formats: Feeds:
-module(rps_rules).
-export([parse/1, winning_hand/2, why/3]).
-include("rps_rules.hrl").
add_unique(Elem, List) ->
case lists:member(Elem, List) of
true -> List;
false -> [Elem|List]
end.
parse(Text) ->
Tokens = lists:map(fun list_to_atom/1, string:tokens(Text, " ")),
parse(Tokens, #ruleinfo{}).
parse([H1,Label,H2|T], #ruleinfo{hands=Hands, beats=Beats, loses=Loses, why=Why}) ->
Acc = #ruleinfo{
hands=add_unique(H1, Hands),
beats=dict:append(H1, H2, Beats),
loses=dict:append(H2, H1, Loses),
why=dict:store({H1, H2}, Label, Why)},
parse([H2|T], Acc);
parse([_H2], Acc) ->
Acc.
% winner for 3 hands is:
% rock, rock, rock -> rock
% rock, paper, scissors -> undefined
% rock, paper, paper -> paper
% rock, rock, paper -> paper
winning_hand(Hands, Ruleinfo=#ruleinfo{}) ->
HSet = sets:from_list(Hands),
sets:fold(
fun(Hand, Acc) ->
Loses = dict:fetch(Hand, Ruleinfo#ruleinfo.loses),
case sets:is_disjoint(sets:from_list(Loses), HSet) of
false -> Acc;
true -> Hand
end
end, undefined, HSet).
why(H1, H2, Ruleinfo=#ruleinfo{}) when is_atom(H2) ->
atom_to_list(dict:fetch({H1, H2}, Ruleinfo#ruleinfo.why));
why(H1, Hands, Ruleinfo=#ruleinfo{}) when is_list(Hands) ->
F = fun(H2) -> why(H1, H2, Ruleinfo) ++ " " ++ atom_to_list(H2) end,
atom_to_list(H1) ++ " " ++ string:join(lists:map(F, Hands), ", ").