Created
May 29, 2020 23:38
-
-
Save fjpse/19807c5413f315c1b7846c7626633512 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-module(rps2). | |
-export([ | |
play/1, | |
echo/1, | |
play_two/3, | |
rock/1, | |
no_repeat/1, | |
const/1, | |
least_frequent/1, | |
more_frequent/1, | |
enum/1, | |
cycle/1, | |
rand/1, | |
val/1, | |
tournament/2 | |
]). | |
% | |
% play one strategy against another, for N moves. | |
% | |
play_two(StrategyL,StrategyR,N) -> | |
play_two(StrategyL,StrategyR,[],[],N). | |
% tail recursive loop for play_two/3 | |
% 0 case computes the result of the tournament | |
% FOR YOU TO DEFINE | |
% REPLACE THE dummy DEFINITIONS | |
play_two(_,_,PlaysL,PlaysR,0) -> | |
io:format("Tournament result: ~p~n", [tournament(PlaysL, PlaysR)]); | |
play_two(StrategyL,StrategyR,PlaysL,PlaysR,N) -> | |
PlayL = StrategyL(PlaysR), | |
PlayR = StrategyR(PlaysL), | |
Result = result(PlayL, PlayR), | |
io:format("Left: ~p, Right: ~p, Result: ~p~n",[PlayL, PlayR, Result]), | |
play_two(StrategyL, StrategyR, [PlayL|PlaysL],[PlayR|PlaysR], N-1). | |
% | |
% interactively play against a strategy, provided as argument. | |
% | |
play(Strategy) -> | |
io:format("Rock - paper - scissors~n"), | |
io:format("Play one of rock, paper, scissors, ...~n"), | |
io:format("... r, p, s, stop, followed by '.'~n"), | |
play(Strategy,[]). | |
% tail recursive loop for play/1 | |
play(Strategy,Moves) -> | |
{ok,P} = io:read("Play: "), | |
Play = expand(P), | |
case Play of | |
stop -> | |
io:format("Stopped~n"); | |
_ -> | |
Result = result(Play,Strategy(Moves)), | |
io:format("Result: ~p~n",[Result]), | |
play(Strategy,[Play|Moves]) | |
end. | |
% | |
% auxiliary functions | |
% | |
% transform shorthand atoms to expanded form | |
expand(r) -> rock; | |
expand(p) -> paper; | |
expand(s) -> scissors; | |
expand(X) -> X. | |
% result of one set of plays | |
result(rock,rock) -> draw; | |
result(rock,paper) -> lose; | |
result(rock,scissors) -> win; | |
result(paper,rock) -> win; | |
result(paper,paper) -> draw; | |
result(paper,scissors) -> lose; | |
result(scissors,rock) -> lose; | |
result(scissors,paper) -> win; | |
result(scissors,scissors) -> draw. | |
% result of a tournament | |
tournament(PlaysL,PlaysR) -> | |
lists:sum( | |
lists:map(fun outcome/1, | |
lists:zipwith(fun result/2,PlaysL,PlaysR))). | |
outcome(win) -> 1; | |
outcome(lose) -> -1; | |
outcome(draw) -> 0. | |
% transform 0, 1, 2 to rock, paper, scissors and vice versa. | |
enum(0) -> | |
rock; | |
enum(1) -> | |
paper; | |
enum(2) -> | |
scissors. | |
val(rock) -> | |
0; | |
val(paper) -> | |
1; | |
val(scissors) -> | |
2. | |
% | |
% strategies. | |
% | |
echo([]) -> | |
paper; | |
echo([Last|_]) -> | |
Last. | |
rock(_) -> | |
rock. | |
% FOR YOU TO DEFINE | |
% REPLACE THE dummy DEFINITIONS | |
no_repeat([]) -> | |
rand([]); | |
no_repeat([X|_]) -> | |
case X of | |
rock -> scissors; | |
paper -> rock; | |
scissors -> paper | |
end. | |
const(Play) -> | |
fun (_) -> Play end. | |
cycle(Xs) -> | |
enum(length(Xs) rem 3). | |
rand(_) -> | |
enum(rand:uniform(3) - 1). | |
least_frequent(Xs) -> | |
{_X, Play} = lists:min(expand_count(lists:foldl(fun count_plays/2, {0,0,0}, Xs))), | |
wins_to(Play). | |
more_frequent(Xs) -> | |
{_X, Play} = lists:max(expand_count(lists:foldl(fun count_plays/2, {0,0,0}, Xs))), | |
wins_to(Play). | |
count_plays(rock, {R,P,S}) -> {R+1, P, S}; | |
count_plays(paper, {R,P,S}) -> {R, P+1, S}; | |
count_plays(scissors, {R,P,S}) -> {R, P, S+1}. | |
expand_count({R,P,S}) -> [{R, rock}, {P, paper}, {S, scissors}]. | |
wins_to(rock)->paper; | |
wins_to(paper)->scissors; | |
wins_to(scissors)->rock. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment