Skip to content

Instantly share code, notes, and snippets.

@StachuDotNet StachuDotNet/rps.fs
Last active Nov 5, 2015

Embed
What would you like to do?
open System
type Choice = Rock | Scissors | Paper
type RoundResult = WinRound | TieRound | LoseRound
let roundResult = function
| Rock, Rock | Scissors, Scissors | Paper, Paper -> TieRound
| Rock, Scissors | Scissors, Paper | Paper, Rock -> WinRound
| Rock, Paper | Scissors, Rock | Paper, Scissors -> LoseRound
let keyMap = function
| ConsoleKey.R -> Some Rock
| ConsoleKey.P -> Some Paper
| ConsoleKey.S -> Some Scissors
| _ -> None
let choiceName = function
| Rock -> "Rock"
| Paper -> "Paper"
| Scissors -> "Scissors"
let rec readPlayerChoice () =
let keyPressed = System.Console.ReadKey(true).Key
match keyMap keyPressed with
| Some a -> a
| None -> readPlayerChoice()
let randomChoice () =
[Rock; Scissors; Paper]
|> List.sortBy(fun x -> System.Guid.NewGuid())
|> List.head
let resultMessage = function
| WinRound -> "Player wins round!"
| LoseRound -> "Computer wins round!"
| TieRound -> "Tie!"
let playRound () =
printfn "Choose [R]ock, [S]cissors, [P]aper:"
let playerChoice = readPlayerChoice()
printfn "Player Choice: %A" (choiceName playerChoice)
let computerChoice = randomChoice()
printfn "Computer Choice: %A" (choiceName computerChoice)
let roundResult = roundResult (playerChoice, computerChoice)
printfn "%A" (resultMessage roundResult)
roundResult
type Game = {
round: int
playerScore: int
computerScore: int
winsPerGame: int }
let (|HumanWin|ComputerWin|GameInProgress|) game =
if game.computerScore >= game.winsPerGame then HumanWin
elif game.playerScore >= game.winsPerGame then ComputerWin
else GameInProgress
let gameFromRound game roundResult =
match roundResult with
| WinRound ->
{ game with
round = game.round + 1
playerScore = game.playerScore + 1 }
| LoseRound ->
{ game with
round = game.round + 1
playerScore = game.playerScore + 1
computerScore = game.computerScore + 1 }
| TieRound -> { game with round = game.round + 1 }
let rec playGame game =
match game with
| HumanWin -> printfn "Computer wins!"
| ComputerWin -> printfn "Player wins!"
| GameInProgress ->
printfn "Round %d" game.round
printfn "Player Score: %d" game.playerScore
printfn "Computer Score: %d" game.computerScore
playRound() |> gameFromRound game |> playGame
[<EntryPoint>]
let main argv =
{ round = 1
playerScore = 0
computerScore = 0
winsPerGame = 3
} |> playGame
System.Console.ReadLine() |> ignore
0
@StachuDotNet

This comment has been minimized.

Copy link
Owner Author

commented Nov 5, 2015

under 100 LOC and still pretty and legible. I'm happy now.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.