Anton Shestakov <engored@ya.ru>, Sat, 01 Mar 2014 22:46:52 +0900
Emakefile.
src/rps.erl
Permissions: -rw-r--r--
-import(rps3, [get_rules/0, winning_hand/1]). lobby/0, counter/0, printer/0, room/1, fool/0, copycat/0, gambler/0]). -define(BOTS, [fool, copycat, gambler]). % 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( dict:append(Hand, Who, Acc) end, dict:new(), Choices), WHand = winning_hand([Hand || {Hand, _} <- Choices]), WHand =:= undefined -> []; WHand =/= undefined -> dict:fetch(WHand, PlayersByHand) 1 -> {WHand, hd(Players)}; register(lobby, spawn_link(?MODULE, lobby, [])), register(counter, spawn_link(?MODULE, counter, [])), register(printer, spawn_link(?MODULE, printer, [])), [spawn_link(?MODULE, Bot, []) || Bot <- ?BOTS]. lobby(Players) when length(Players) =:= length(?BOTS) -> Room = spawn_link(?MODULE, room, [Players]), lists:foreach(fun(Player) -> Player ! {room, Room} end, Players), counter(0, 0, dict:new(), dict:new()). counter(Plays, Draws, Wins, Hands) -> counter(Plays + 1, Draws + 1, Wins, Hands); {winner, {Hand, Winner}} -> counter(Plays + 1, Draws, dict:update_counter(Winner, 1, Wins), dict:update_counter(Hand, 1, Hands)); wins, dict:to_list(Wins), hands, dict:to_list(Hands)}}, counter(Plays, Draws, Wins, Hands) io:format("Stats: ~w.~n", [Stats]) counter ! {sendstats, self()} lists:foreach(fun(Player) -> Player ! start end, Players), room(Players, Choices) when length(Players) =:= length(Choices) -> Winner = winner(Choices), lists:foreach(fun(Player) -> Player ! Msg end, Players), room(Players, Choices) -> ObjectIsOk = lists:any(fun(X) -> X =:= Hand end, get_rules()), ChoiceMade = lists:keymember(Who, 2, Choices), case ObjectIsOk andalso not ChoiceMade of room(Players, [{Hand, Who}|Choices]); io:format("~w picks ~w, not allowed.~n", [Who, Hand]), Hand = lists:nth(random:uniform(length(get_rules())), get_rules()), copycat(Room, hd(get_rules())) {winner, {NewHand, _}} -> Wins = dict:from_list([{C, 0} || C <- get_rules()]), F = fun({_, A}, {_, B}) -> A =< B end, {Hand, _} = hd(lists:sort(F, dict:to_list(Wins))), gambler(Room, dict:update_counter(Hand, 1, Wins))