Advertisement
Guest User

Untitled

a guest
Mar 23rd, 2017
68
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.83 KB | None | 0 0
  1. -module(rps2).
  2. -export([play/1,echo/1,play_two/3,rock/1,no_repeat/1,const/1,enum/1,cycle/1,rand/1,val/1,tournament/2]).
  3.  
  4.  
  5. %
  6. % play one strategy against another, for N moves.
  7. %
  8.  
  9. play_two(StrategyL,StrategyR,N) ->
  10. play_two(StrategyL,StrategyR,[],[],N).
  11.  
  12. % tail recursive loop for play_two/3
  13. % 0 case computes the result of the tournament
  14.  
  15. % FOR YOU TO DEFINE
  16. % REPLACE THE dummy DEFINITIONS
  17.  
  18. play_two(_,_,PlaysL,PlaysR,0) ->
  19. dummy;
  20.  
  21. play_two(StrategyL,StrategyR,PlaysL,PlaysR,N) ->
  22. dummy.
  23.  
  24. %
  25. % interactively play against a strategy, provided as argument.
  26. %
  27.  
  28. play(Strategy) ->
  29. io:format("Rock - paper - scissors~n"),
  30. io:format("Play one of rock, paper, scissors, ...~n"),
  31. io:format("... r, p, s, stop, followed by '.'~n"),
  32. play(Strategy,[]).
  33.  
  34. % tail recursive loop for play/1
  35.  
  36. play(Strategy,Moves) ->
  37. {ok,P} = io:read("Play: "),
  38. Play = expand(P),
  39. case Play of
  40. stop ->
  41. io:format("Stopped~n");
  42. _ ->
  43. Result = result(Play,Strategy(Moves)),
  44. io:format("Result: ~p~n",[Result]),
  45. play(Strategy,[Play|Moves])
  46. end.
  47.  
  48. %
  49. % auxiliary functions
  50. %
  51.  
  52. % transform shorthand atoms to expanded form
  53.  
  54. expand(r) -> rock;
  55. expand(p) -> paper;
  56. expand(s) -> scissors;
  57. expand(X) -> X.
  58.  
  59. % result of one set of plays
  60.  
  61. result(rock,rock) -> draw;
  62. result(rock,paper) -> lose;
  63. result(rock,scissors) -> win;
  64. result(paper,rock) -> win;
  65. result(paper,paper) -> draw;
  66. result(paper,scissors) -> lose;
  67. result(scissors,rock) -> lose;
  68. result(scissors,paper) -> win;
  69. result(scissors,scissors) -> draw.
  70.  
  71. % result of a tournament
  72.  
  73. tournament(PlaysL,PlaysR) ->
  74. lists:sum(
  75. lists:map(fun outcome/1,
  76. lists:zipwith(fun result/2,PlaysL,PlaysR))).
  77.  
  78. outcome(win) -> 1;
  79. outcome(lose) -> -1;
  80. outcome(draw) -> 0.
  81.  
  82. % transform 0, 1, 2 to rock, paper, scissors and vice versa.
  83.  
  84. enum(0) -> rock;
  85. enum(1) -> paper;
  86. enum(2) -> scissors.
  87.  
  88. val(rock) -> 0;
  89. val(paper) -> 1;
  90. val(scissors) -> 2.
  91.  
  92. % give the play which the argument beats.
  93.  
  94. beats(rock) -> scissors;
  95. beats(paper) -> rock;
  96. beats(scissors) -> paper.
  97.  
  98. loses(rock) -> paper;
  99. loses(paper) -> scissors;
  100. loses(scissors) -> rock.
  101.  
  102. %
  103. % strategies.
  104. %
  105. echo([]) -> paper;
  106. echo([Last|_]) -> Last.
  107.  
  108. rock(_) -> rock.
  109.  
  110. no_repeat([]) -> paper;
  111. no_repeat([Previous|_]) -> beats(Previous).
  112.  
  113. % Not quite sure what this one is for... so assuming 'constant'
  114. % which just returns one particular value.
  115. const(_Play) -> paper.
  116.  
  117. % I peeked at other solutions for this one as couldn't figure out
  118. % how to cycle through the values, and I liked this solution
  119. cycle(Xs) -> enum(length(Xs) rem 3).
  120.  
  121. % Returns a random rock paper or scissors
  122. rand(_) -> enum(rand:uniform(3) - 1).
  123.  
  124. % Choose the least frequent play, assuming that in the long run your opponent will
  125. % play each choice equally
  126. leastfrequent([]) -> rand([]);
  127. leastfrequent(Plays) -> mincount(addcounts(Plays)).
  128.  
  129. % Choose the most frequent play, assuming that in the long run your opponent is going to
  130. % play that choice more often than the others.
  131. mostfrequent([]) -> rand([]);
  132. mostfrequent(Plays) -> maxcount(addcounts(Plays)).
  133.  
  134.  
  135. mincount([{rock, CntRock},{paper, CntPaper},{scissors, CntScissors}]) ->
  136. % Returns the play with the least number of uses
  137. matchcount(min(min(CntRock, CntPaper), min(CntPaper, CntScissors)), CntRock, CntPaper, CntScissors).
  138.  
  139. maxcount([{rock, CntRock},{paper, CntPaper},{scissors, CntScissors}]) ->
  140. % Returns the play with the most number of uses
  141. matchcount(max(max(CntRock, CntPaper), max(CntPaper, CntScissors)), CntRock, CntPaper, CntScissors).
  142.  
  143. % Doesnt' matter if the count matches >1, the first hit will always be used
  144. matchcount(MatchCount, MatchCount, _PaperCount, _ScissorsCount) -> rock;
  145. matchcount(MatchCount, _RockCount, MatchCount, _ScissorsCount) -> paper;
  146. matchcount(MatchCount, _Rockcount, _PaperCount, MatchCount) -> scissors.
  147.  
  148. addcounts(Plays) -> addcounts(Plays, [{rock, 0},{paper, 0},{scissors, 0}]).
  149.  
  150. addcounts([], Counts) -> Counts;
  151. addcounts([rock | Plays] , [{rock, CntRock},{paper, CntPaper},{scissors, CntScissors}]) -> addcounts(Plays , [{rock, CntRock + 1},{paper, CntPaper},{scissors, CntScissors}]);
  152. addcounts([paper | Plays] , [{rock, CntRock},{paper, CntPaper},{scissors, CntScissors}]) -> addcounts(Plays , [{rock, CntRock},{paper, CntPaper + 1},{scissors, CntScissors}]);
  153. addcounts([scissors | Plays] , [{rock, CntRock},{paper, CntPaper},{scissors, CntScissors}]) -> addcounts(Plays , [{rock, CntRock},{paper, CntPaper},{scissors, CntScissors + 1}]).
  154.  
  155.  
  156. % Take a list of strategies and each play chooses a random one to apply.
  157. randomstrategy([]) -> fun rand/1;
  158. randomstrategy(Strategies) -> lists:nth(rand:uniform(length(Strategies)), Strategies).
  159.  
  160. % Todo: Take a list of strategies and each play chooses from the list the
  161. % strategy which gets the best result when played against the list
  162. % of plays made so far
  163. %
  164. % Will have to play each strategy, store the results, then return the best
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement