patternMinor
First attempt at writing Rock Paper Scissors game
Viewed 0 times
paperscissorswritingattemptfirstrockgame
Problem
I made this Rock Paper Scissors game and I would like for this to be critiqued.
import System.IO
import System.Random
import Control.Monad
import Control.Arrow
data Throw = Rock | Paper | Scissors
deriving (Show, Read, Enum, Bounded)
instance Random Throw where
random g = first toEnum $ randomR (a, b) g
where a = fromEnum (minBound :: Throw)
b = fromEnum (maxBound :: Throw)
randomR (a, b) g = first toEnum $ randomR (a', b') g
where a' = fromEnum a
b' = fromEnum b
beats :: Throw -> Throw -> Bool
Rock `beats` Scissors = True
Paper `beats` Rock = True
Scissors `beats` Paper = True
_ `beats` _ = False
play :: Throw -> Throw -> String
play p1 p2
| p1 `beats` p2 = "You win!"
| p2 `beats` p1 = "You lose."
| otherwise = "Tie."
main :: IO ()
main = do
putStr "Enter your move [Rock, Paper, or Scissors]: "
hFlush stdout
p1 >= readIO
p2 <- liftM (fst . random) getStdGen
putStrLn $ show p1 ++ " vs. " ++ show p2
putStrLn $ play p1 p2Solution
The style is pretty good, I can just see two minor improvements you could do: Firstly, you can define
At this point Haskell's typing even derives the type of
Second, you should probably use
random in terms of your own randomR in order to save a few keystrokes:instance Random Throw where
random = randomR (minBound, maxBound)
randomR (a, b) g = ...At this point Haskell's typing even derives the type of
minBound for you, so you can lose the explicit annotations.Second, you should probably use
randomIO instead of liftM (fst . random) getStdGen. That is not only shorter, but also updates the generator state, which means that you won't get the same result if you call it twice in the program.Code Snippets
instance Random Throw where
random = randomR (minBound, maxBound)
randomR (a, b) g = ...Context
StackExchange Code Review Q#18422, answer score: 3
Revisions (0)
No revisions yet.