Skip to content

Instantly share code, notes, and snippets.

@StachuDotNet
Last active November 5, 2015 20:12
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save StachuDotNet/f6fcb1b36af0b677f63f to your computer and use it in GitHub Desktop.
Save StachuDotNet/f6fcb1b36af0b677f63f to your computer and use it in GitHub Desktop.
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
Copy link
Author

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