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.




open System
 
let random = Random ()
let rand = random.NextDouble () //Gets a random number in the range (0.0, 1.0)
 
/// Union of possible choices for a round of rock-paper-scissors
type Choice =
| Rock
| Paper
| Scissors
 
/// Gets the string representation of a Choice
let getString = function
    | Rock -> "Rock"
    | Paper -> "Paper"
    | Scissors -> "Scissors"
 
/// Defines rules for winning and losing
let beats (a : Choice, b : Choice) =
    match a, b with
    | Rock, Scissors -> true    // Rock beats Scissors
    | Paper, Rock -> true       // Paper beats Rock
    | Scissors, Paper -> true   // Scissors beat Paper
    | _, _ -> false
 
/// Generates the next move for the computer based on probability derived from previous player moves.
let genMove r p s =
    let tot = r + p + s
    let n = rand
    if n <= s / tot then Rock
    elif n <= (s + r) / tot then Paper
    else Scissors
 
/// Gets the move chosen by the player
let rec getMove () =
    printf "[R]ock, [P]aper, or [S]cissors?: "
    let choice = Console.ReadLine ()
    match choice with
    | "r" | "R" -> Rock
    | "p" | "P" -> Paper
    | "s" | "S" -> Scissors
    | _ ->
        printf "Invalid choice.\n\n"
        getMove ()
 
/// Place where all the game logic takes place.
let rec game (r : float, p : float, s : float) =
    let comp = genMove r p s
    let player = getMove ()
    Console.WriteLine ("Player: {0} vs Computer: {1}", getString player, getString comp)
    Console.WriteLine (
        if beats(player, comp) then "Player Wins!\n"
        elif beats(comp, player) then "Computer Wins!\n"
        else "Draw!\n"
    )
    let nextR = if player = Rock then r + 1.0 else r
    let nextP = if player = Paper then p + 1.0 else p
    let nextS = if player = Scissors then s + 1.0 else s
    game (nextR, nextP, nextS)
 
game(1.0, 1.0, 1.0)
 