--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/rps.erl Sun Feb 23 00:04:28 2014 +0900
+-export([lobby/0, room/1, beats/1, winner/1, go/0, fool/1]).
+-define(RULES, [rock, paper, scissors]).
+% winner for 3 players is:
+% rock, rock, rock -> undefined
+% rock, paper, scissors -> undefined
+% rock, paper, paper -> undefined
+% rock, rock, paper -> {paper, Who}
+winner(Choices) when length(Choices) > 1 ->
+ CSet = sets:from_list([C || {C, _} <- Choices]),
+ RSet = sets:from_list(?RULES),
+ Absents = sets:subtract(RSet, CSet),
+ case sets:size(Absents) of
+ Absent = hd(sets:to_list(Absents)),
+ Unbeaten = beats(Absent),
+ Winners = [{C, Who} || {C, Who} <- Choices, C =:= Unbeaten],
+ case length(Winners) of
+ Lobby = spawn(rps, lobby, []),
+ [spawn(rps, fool, [Lobby]) || _ <- lists:seq(1, 3)].
+lobby(Players) when length(Players) =:= 3 ->
+ Room = spawn(rps, room, [Players]),
+ lists:foreach(fun(Player) -> Player ! {room, Room} end, Players),
+ lists:foreach(fun(Player) -> Player ! start end, Players),
+room(Players, Choices) when length(Players) =:= length(Choices) ->
+ Best = winner(Choices),
+ io:format("draw: ~w.~n", [Choices]),
+ io:format("the winner is ~w.~n", [Best]),
+ lists:foreach(fun(Player) -> Player ! Msg end, Players),
+room(Players, Choices) ->
+ ObjectIsOk = lists:any(fun(X) -> X =:= Object end, ?RULES),
+ ChoiceMade = lists:any(fun({_, Player}) -> Player =:= Who end, Choices),
+ case ObjectIsOk andalso not ChoiceMade of
+ room(Players, [{Object, Who}|Choices]);
+ io:format("~w picks ~w, not allowed.~n", [Who, Object]),
+ Lobby ! {join, self()},
+ fool(Lobby, undefined).
+fool(Lobby, undefined) ->
+ Choice = lists:nth(random:uniform(length(?RULES)), ?RULES),
+ Room ! {Choice, self()},