28:44aa20fdf779
Anton Shestakov <engored@ya.ru>, Sun, 02 Mar 2014 18:00:14 +0900
Bots must know rules of current room (only rps3 at the moment).

next change 29:0f29304f36f4
previous change 27:19ca2615be8f

src/rps_room.erl

Permissions: -rw-r--r--

Other formats: Feeds:
-module(rps_room).
-import(rps3, [get_rules/0, winning_hand/1]).
-export([room/1]).
-record(state, {players=[], choices=[], nicknames=dict:new()}).
% 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 ->
PlayersByHand = lists:foldl(
fun({Hand, Who}, Acc) ->
dict:append(Hand, Who, Acc)
end, dict:new(), Choices),
WHand = winning_hand([Hand || {Hand, _} <- Choices]),
Players = if
WHand =:= undefined -> [];
WHand =/= undefined -> dict:fetch(WHand, PlayersByHand)
end,
case length(Players) of
1 -> {WHand, hd(Players)};
_ -> undefined
end.
room(Players) when is_list(Players) ->
lists:foreach(fun(Player) -> Player ! {start, rps3} end, Players),
room(#state{players=Players});
room(#state{players=Players, choices=Choices}) when length(Players) =:= length(Choices) ->
Winner = winner(Choices),
Msg = if
Winner =:= undefined ->
{draw, Choices};
true ->
{winner, Winner}
end,
counter ! Msg,
lists:foreach(fun(Player) -> Player ! Msg end, Players),
room(Players);
room(State=#state{choices=Choices, nicknames=Nicknames}) ->
receive
{nickname, Who, Nickname} ->
room(State#state{nicknames=dict:store(Who, Nickname, Nicknames)});
{Hand, Who} ->
ObjectIsOk = lists:any(fun(X) -> X =:= Hand end, get_rules()),
ChoiceMade = lists:keymember(Who, 2, Choices),
case ObjectIsOk andalso not ChoiceMade of
true ->
room(State#state{choices=[{Hand, Who}|Choices]});
false ->
io:format("~w picks ~w, not allowed.~n", [Who, Hand]),
room(State)
end
end.