Skip to content

Instantly share code, notes, and snippets.

@fjpse
Created May 29, 2020 23:38
Show Gist options
  • Save fjpse/19807c5413f315c1b7846c7626633512 to your computer and use it in GitHub Desktop.
Save fjpse/19807c5413f315c1b7846c7626633512 to your computer and use it in GitHub Desktop.
-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