SHOW:
|
|
- or go back to the newest paste.
| 1 | import qualified System.Random as R | |
| 2 | import Control.Applicative ((<*>), (<$>), pure) | |
| 3 | import Control.Monad.State (State, state, evalState) | |
| 4 | import Control.Arrow (first) | |
| 5 | import Control.Exception (bracket) | |
| 6 | ||
| 7 | data RPS = Rock | Paper | Scissors deriving (Eq, Show, Read) | |
| 8 | type Score = (Int, Int) | |
| 9 | ||
| 10 | instance R.Random RPS where | |
| 11 | random = first pick . R.randomR (0,2) | |
| 12 | where pick :: Int -> RPS | |
| 13 | pick 0 = Rock | |
| 14 | pick 1 = Paper | |
| 15 | pick 2 = Scissors | |
| 16 | randomR = error "Unsupported data type" | |
| 17 | ||
| 18 | newGame :: Score | |
| 19 | newGame = (0,0) | |
| 20 | ||
| 21 | beats :: RPS -> RPS -> Bool | |
| 22 | beats Rock Scissors = True | |
| 23 | beats Paper Rock = True | |
| 24 | beats Scissors Paper = True | |
| 25 | beats _ _ = False | |
| 26 | ||
| 27 | play :: RPS -> RPS -> Score -> Score | |
| 28 | play ca cb (sa,sb) | |
| 29 | | ca `beats` cb = (sa+1, sb) | |
| 30 | | cb `beats` ca = (sa, sb+1) | |
| 31 | | otherwise = (sa, sb) | |
| 32 | ||
| 33 | getChoice :: IO RPS | |
| 34 | getChoice = fmap read getLine | |
| 35 | ||
| 36 | - | getRandom = do c <- R.randomIO |
| 36 | + | |
| 37 | - | putStrLn $ "PC picked " ++ show c |
| 37 | + | getRandom = bracket R.randomIO output return |
| 38 | - | return c |
| 38 | + | where output c = putStrLn $ "PC picked " ++ show c |
| 39 | ||
| 40 | playRound :: Score -> IO Score | |
| 41 | playRound s = play <$> getChoice <*> getRandom <*> pure s | |
| 42 | ||
| 43 | playLoop :: Score -> IO Score | |
| 44 | playLoop s = do r <- playRound s | |
| 45 | print r | |
| 46 | playLoop r | |
| 47 | ||
| 48 | main = playLoop newGame |