Download:
child 20:3f27b5c2f402
parent 18:9f635022d12d
19:22714b5dcb49
Anton Shestakov <engored@ya.ru>, Sat, 01 Mar 2014 22:45:21 +0900
src directory.

6 файлов изменено, 326 вставок(+), 326 удалений(-) [+]
rps.erl file | annotate | diff | comparison | revisions
rps3.erl file | annotate | diff | comparison | revisions
rps5.erl file | annotate | diff | comparison | revisions
src/rps.erl file | annotate | diff | comparison | revisions
src/rps3.erl file | annotate | diff | comparison | revisions
src/rps5.erl file | annotate | diff | comparison | revisions
--- a/rps.erl Sat Mar 01 15:35:23 2014 +0900
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,171 +0,0 @@
--module(rps).
--import(rps3, [get_rules/0, winning_hand/1]).
--export([
- go/0,
- winner/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(
- 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.
-
-go() ->
- 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() ->
- lobby([]).
-
-lobby(Players) when length(Players) =:= length(?BOTS) ->
- Room = spawn_link(?MODULE, room, [Players]),
- lists:foreach(fun(Player) -> Player ! {room, Room} end, Players),
- lobby([]);
-
-lobby(Players) ->
- receive
- {join, Who} ->
- lobby([Who|Players])
- end.
-
-counter() ->
- counter(0, 0, dict:new(), dict:new()).
-
-counter(Plays, Draws, Wins, Hands) ->
- receive
- {draw, _} ->
- 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));
- {sendstats, Pid} ->
- Pid ! {stats, {
- plays, Plays,
- draws, Draws,
- wins, dict:to_list(Wins),
- hands, dict:to_list(Hands)}},
- counter(Plays, Draws, Wins, Hands)
- end.
-
-printer() ->
- receive
- {stats, Stats} ->
- io:format("Stats: ~w.~n", [Stats])
- after 1000 ->
- counter ! {sendstats, self()}
- end,
- printer().
-
-room(Players) ->
- lists:foreach(fun(Player) -> Player ! start end, Players),
- room(Players, []).
-
-room(Players, 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(Players, Choices) ->
- receive
- {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(Players, [{Hand, Who}|Choices]);
- false ->
- io:format("~w picks ~w, not allowed.~n", [Who, Hand]),
- room(Players, Choices)
- end
- end.
-
-fool() ->
- lobby ! {join, self()},
- fool(joined).
-
-fool(joined) ->
- receive
- {room, Room} ->
- random:seed(now()),
- fool(Room)
- end;
-
-fool(Room) ->
- receive
- start ->
- Hand = lists:nth(random:uniform(length(get_rules())), get_rules()),
- Room ! {Hand, self()},
- fool(Room);
- {winner, _} ->
- fool(Room)
- end.
-
-copycat() ->
- lobby ! {join, self()},
- copycat(joined).
-
-copycat(joined) ->
- receive
- {room, Room} ->
- copycat(Room, hd(get_rules()))
- end.
-
-copycat(Room, Hand) ->
- receive
- start ->
- Room ! {Hand, self()},
- copycat(Room, Hand);
- {winner, {NewHand, _}} ->
- copycat(Room, NewHand)
- end.
-
-gambler() ->
- lobby ! {join, self()},
- gambler(joined).
-
-gambler(joined) ->
- receive
- {room, Room} ->
- Wins = dict:from_list([{C, 0} || C <- get_rules()]),
- gambler(Room, Wins)
- end.
-
-gambler(Room, Wins) ->
- receive
- start ->
- F = fun({_, A}, {_, B}) -> A =< B end,
- {Hand, _} = hd(lists:sort(F, dict:to_list(Wins))),
- Room ! {Hand, self()},
- gambler(Room, Wins);
- {winner, {Hand, _}} ->
- gambler(Room, dict:update_counter(Hand, 1, Wins))
- end.
--- a/rps3.erl Sat Mar 01 15:35:23 2014 +0900
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,70 +0,0 @@
--module(rps3).
--export([
- get_rules/0,
- beats/1, test_beats/0,
- loses/1, test_loses/0,
- winning_hand/1, test_winning_hand/0]).
-
-get_rules() -> [rock, paper, scissors].
-
-beats(H) ->
- beats(H, get_rules()).
-
-beats(H, [H|Tail]) ->
- lists:last(Tail);
-
-beats(H, [B,H|_]) ->
- B;
-
-beats(H, [_|T]) ->
- beats(H, T).
-
-loses(H) ->
- beats(H, lists:reverse(get_rules())).
-
-test_beats() ->
- lists:foreach(
- fun(H) ->
- io:format("~w beats ~w.~n", [H, beats(H)])
- end,
- get_rules()).
-
-test_loses() ->
- lists:foreach(
- fun(H) ->
- io:format("~w loses to ~w.~n", [H, loses(H)])
- end,
- get_rules()).
-
-% winner for 3 hands is:
-% rock, rock, rock -> rock
-% rock, paper, scissors -> undefined
-% rock, paper, paper -> paper
-% rock, rock, paper -> paper
-
-winning_hand(Hands) ->
- HSet = sets:from_list(Hands),
- sets:fold(
- fun(Hand, Acc) ->
- case sets:is_element(loses(Hand), HSet) of
- true -> Acc;
- false -> Hand
- end
- end, undefined, HSet).
-
-test_winning_hand() ->
- Cases = [
- [rock, rock, rock],
- [rock, paper, scissors],
- [rock, paper, paper],
- [rock, rock, paper],
- [rock, paper],
- [paper, scissors],
- [scissors, rock]
- ],
- lists:foreach(
- fun(Hands) ->
- Winner = winning_hand(Hands),
- io:format("~w wins in ~w.~n", [Winner, Hands])
- end,
- Cases).
--- a/rps5.erl Sat Mar 01 15:35:23 2014 +0900
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,85 +0,0 @@
--module(rps5).
--export([
- get_rules/0,
- beats/1, test_beats/0,
- loses/1, test_loses/0,
- winning_hand/1, test_winning_hand/0]).
-
-get_rules() -> [rock, paper, scissors, spock, lizard].
-
-beats(rock) ->
- [scissors, lizard];
-
-beats(paper) ->
- [spock, rock];
-
-beats(scissors) ->
- [lizard, paper];
-
-beats(spock) ->
- [rock, scissors];
-
-beats(lizard) ->
- [paper, spock].
-
-loses(lizard) ->
- [scissors, rock];
-
-loses(spock) ->
- [paper, lizard];
-
-loses(scissors) ->
- [rock, spock];
-
-loses(paper) ->
- [lizard, scissors];
-
-loses(rock) ->
- [spock, paper].
-
-test_beats() ->
- lists:foreach(
- fun(H) ->
- io:format("~w beats ~w.~n", [H, beats(H)])
- end,
- get_rules()).
-
-test_loses() ->
- lists:foreach(
- fun(H) ->
- io:format("~w loses to ~w.~n", [H, loses(H)])
- end,
- get_rules()).
-
-% winner for 3 hands is:
-% rock, rock, rock -> rock
-% rock, paper, scissors -> undefined
-% rock, paper, paper -> paper
-% rock, rock, paper -> paper
-
-winning_hand(Hands) ->
- HSet = sets:from_list(Hands),
- sets:fold(
- fun(Hand, Acc) ->
- Loses = loses(Hand),
- case sets:is_disjoint(sets:from_list(Loses), HSet) of
- true -> Hand;
- false -> Acc
- end
- end, undefined, HSet).
-
-test_winning_hand() ->
- Exclude = fun(Hand) -> lists:delete(Hand, get_rules()) end,
- Cases = [
- [rock, rock, rock],
- [rock, paper, scissors],
- [rock, paper, paper],
- [rock, rock, paper]
- |lists:map(Exclude, get_rules())
- ],
- lists:foreach(
- fun(Hands) ->
- Winner = winning_hand(Hands),
- io:format("~w wins in ~w.~n", [Winner, Hands])
- end,
- Cases).
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/rps.erl Sat Mar 01 22:45:21 2014 +0900
@@ -0,0 +1,171 @@
+-module(rps).
+-import(rps3, [get_rules/0, winning_hand/1]).
+-export([
+ go/0,
+ winner/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(
+ 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.
+
+go() ->
+ 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() ->
+ lobby([]).
+
+lobby(Players) when length(Players) =:= length(?BOTS) ->
+ Room = spawn_link(?MODULE, room, [Players]),
+ lists:foreach(fun(Player) -> Player ! {room, Room} end, Players),
+ lobby([]);
+
+lobby(Players) ->
+ receive
+ {join, Who} ->
+ lobby([Who|Players])
+ end.
+
+counter() ->
+ counter(0, 0, dict:new(), dict:new()).
+
+counter(Plays, Draws, Wins, Hands) ->
+ receive
+ {draw, _} ->
+ 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));
+ {sendstats, Pid} ->
+ Pid ! {stats, {
+ plays, Plays,
+ draws, Draws,
+ wins, dict:to_list(Wins),
+ hands, dict:to_list(Hands)}},
+ counter(Plays, Draws, Wins, Hands)
+ end.
+
+printer() ->
+ receive
+ {stats, Stats} ->
+ io:format("Stats: ~w.~n", [Stats])
+ after 1000 ->
+ counter ! {sendstats, self()}
+ end,
+ printer().
+
+room(Players) ->
+ lists:foreach(fun(Player) -> Player ! start end, Players),
+ room(Players, []).
+
+room(Players, 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(Players, Choices) ->
+ receive
+ {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(Players, [{Hand, Who}|Choices]);
+ false ->
+ io:format("~w picks ~w, not allowed.~n", [Who, Hand]),
+ room(Players, Choices)
+ end
+ end.
+
+fool() ->
+ lobby ! {join, self()},
+ fool(joined).
+
+fool(joined) ->
+ receive
+ {room, Room} ->
+ random:seed(now()),
+ fool(Room)
+ end;
+
+fool(Room) ->
+ receive
+ start ->
+ Hand = lists:nth(random:uniform(length(get_rules())), get_rules()),
+ Room ! {Hand, self()},
+ fool(Room);
+ {winner, _} ->
+ fool(Room)
+ end.
+
+copycat() ->
+ lobby ! {join, self()},
+ copycat(joined).
+
+copycat(joined) ->
+ receive
+ {room, Room} ->
+ copycat(Room, hd(get_rules()))
+ end.
+
+copycat(Room, Hand) ->
+ receive
+ start ->
+ Room ! {Hand, self()},
+ copycat(Room, Hand);
+ {winner, {NewHand, _}} ->
+ copycat(Room, NewHand)
+ end.
+
+gambler() ->
+ lobby ! {join, self()},
+ gambler(joined).
+
+gambler(joined) ->
+ receive
+ {room, Room} ->
+ Wins = dict:from_list([{C, 0} || C <- get_rules()]),
+ gambler(Room, Wins)
+ end.
+
+gambler(Room, Wins) ->
+ receive
+ start ->
+ F = fun({_, A}, {_, B}) -> A =< B end,
+ {Hand, _} = hd(lists:sort(F, dict:to_list(Wins))),
+ Room ! {Hand, self()},
+ gambler(Room, Wins);
+ {winner, {Hand, _}} ->
+ gambler(Room, dict:update_counter(Hand, 1, Wins))
+ end.
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/rps3.erl Sat Mar 01 22:45:21 2014 +0900
@@ -0,0 +1,70 @@
+-module(rps3).
+-export([
+ get_rules/0,
+ beats/1, test_beats/0,
+ loses/1, test_loses/0,
+ winning_hand/1, test_winning_hand/0]).
+
+get_rules() -> [rock, paper, scissors].
+
+beats(H) ->
+ beats(H, get_rules()).
+
+beats(H, [H|Tail]) ->
+ lists:last(Tail);
+
+beats(H, [B,H|_]) ->
+ B;
+
+beats(H, [_|T]) ->
+ beats(H, T).
+
+loses(H) ->
+ beats(H, lists:reverse(get_rules())).
+
+test_beats() ->
+ lists:foreach(
+ fun(H) ->
+ io:format("~w beats ~w.~n", [H, beats(H)])
+ end,
+ get_rules()).
+
+test_loses() ->
+ lists:foreach(
+ fun(H) ->
+ io:format("~w loses to ~w.~n", [H, loses(H)])
+ end,
+ get_rules()).
+
+% winner for 3 hands is:
+% rock, rock, rock -> rock
+% rock, paper, scissors -> undefined
+% rock, paper, paper -> paper
+% rock, rock, paper -> paper
+
+winning_hand(Hands) ->
+ HSet = sets:from_list(Hands),
+ sets:fold(
+ fun(Hand, Acc) ->
+ case sets:is_element(loses(Hand), HSet) of
+ true -> Acc;
+ false -> Hand
+ end
+ end, undefined, HSet).
+
+test_winning_hand() ->
+ Cases = [
+ [rock, rock, rock],
+ [rock, paper, scissors],
+ [rock, paper, paper],
+ [rock, rock, paper],
+ [rock, paper],
+ [paper, scissors],
+ [scissors, rock]
+ ],
+ lists:foreach(
+ fun(Hands) ->
+ Winner = winning_hand(Hands),
+ io:format("~w wins in ~w.~n", [Winner, Hands])
+ end,
+ Cases).
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/rps5.erl Sat Mar 01 22:45:21 2014 +0900
@@ -0,0 +1,85 @@
+-module(rps5).
+-export([
+ get_rules/0,
+ beats/1, test_beats/0,
+ loses/1, test_loses/0,
+ winning_hand/1, test_winning_hand/0]).
+
+get_rules() -> [rock, paper, scissors, spock, lizard].
+
+beats(rock) ->
+ [scissors, lizard];
+
+beats(paper) ->
+ [spock, rock];
+
+beats(scissors) ->
+ [lizard, paper];
+
+beats(spock) ->
+ [rock, scissors];
+
+beats(lizard) ->
+ [paper, spock].
+
+loses(lizard) ->
+ [scissors, rock];
+
+loses(spock) ->
+ [paper, lizard];
+
+loses(scissors) ->
+ [rock, spock];
+
+loses(paper) ->
+ [lizard, scissors];
+
+loses(rock) ->
+ [spock, paper].
+
+test_beats() ->
+ lists:foreach(
+ fun(H) ->
+ io:format("~w beats ~w.~n", [H, beats(H)])
+ end,
+ get_rules()).
+
+test_loses() ->
+ lists:foreach(
+ fun(H) ->
+ io:format("~w loses to ~w.~n", [H, loses(H)])
+ end,
+ get_rules()).
+
+% winner for 3 hands is:
+% rock, rock, rock -> rock
+% rock, paper, scissors -> undefined
+% rock, paper, paper -> paper
+% rock, rock, paper -> paper
+
+winning_hand(Hands) ->
+ HSet = sets:from_list(Hands),
+ sets:fold(
+ fun(Hand, Acc) ->
+ Loses = loses(Hand),
+ case sets:is_disjoint(sets:from_list(Loses), HSet) of
+ true -> Hand;
+ false -> Acc
+ end
+ end, undefined, HSet).
+
+test_winning_hand() ->
+ Exclude = fun(Hand) -> lists:delete(Hand, get_rules()) end,
+ Cases = [
+ [rock, rock, rock],
+ [rock, paper, scissors],
+ [rock, paper, paper],
+ [rock, rock, paper]
+ |lists:map(Exclude, get_rules())
+ ],
+ lists:foreach(
+ fun(Hands) ->
+ Winner = winning_hand(Hands),
+ io:format("~w wins in ~w.~n", [Winner, Hands])
+ end,
+ Cases).