Task

Implement the classic children's game Rock-paper-scissors, as well as a simple predictive   AI   (artificial intelligence)   player.

Rock Paper Scissors is a two player game.

Each player chooses one of rock, paper or scissors, without knowing the other player's choice.

The winner is decided by a set of rules:

   Rock beats scissors
   Scissors beat paper
   Paper beats rock


If both players choose the same thing, there is no winner for that round.

For this task, the computer will be one of the players.

The operator will select Rock, Paper or Scissors and the computer will keep a record of the choice frequency, and use that information to make a weighted random choice in an attempt to defeat its opponent.



Extra credit

Support additional choices   additional weapons.




defmodule Rock_paper_scissors do
  def play, do: loop([1,1,1])
 
  defp loop([r,p,s]=odds) do
    IO.gets("What is your move? (R,P,S,Q) ") |> String.upcase |> String.first
    |> case do
           "Q" -> IO.puts "Good bye!"
           human when human in ["R","P","S"] ->
              IO.puts "Your move is #{play_to_string(human)}."
              computer = select_play(odds)
              IO.puts "My move is #{play_to_string(computer)}"
              case beats(human,computer) do
                  true  -> IO.puts "You win!"
                  false -> IO.puts "I win!"
                  _     -> IO.puts "Draw"
              end
              case human do
                  "R" -> loop([r+1,p,s])
                  "P" -> loop([r,p+1,s])
                  "S" -> loop([r,p,s+1])
              end
           _ ->
              IO.puts "Invalid play"
              loop(odds)
       end
  end
 
  defp beats("R","S"), do: true
  defp beats("P","R"), do: true
  defp beats("S","P"), do: true
  defp beats(x,x), do: :draw
  defp beats(_,_), do: false
 
  defp play_to_string("R"), do: "Rock"
  defp play_to_string("P"), do: "Paper"
  defp play_to_string("S"), do: "Scissors"
 
  defp select_play([r,p,s]) do
    n = :rand.uniform(r+p+s)
    cond do
        n <= r   -> "P"
        n <= r+p -> "S"
        true     -> "R"
    end
  end
end
 
Rock_paper_scissors.play