Last active
November 5, 2015 20:12
-
-
Save StachuDotNet/f6fcb1b36af0b677f63f to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
under 100 LOC and still pretty and legible. I'm happy now.