Data commit
This commit is contained in:
parent
7387c8f97b
commit
cb5bb5e222
199093 changed files with 3378972 additions and 0 deletions
91
Task/Penneys-game/Haskell/penneys-game.hs
Normal file
91
Task/Penneys-game/Haskell/penneys-game.hs
Normal file
|
|
@ -0,0 +1,91 @@
|
|||
import qualified Data.List as L
|
||||
import System.IO
|
||||
import System.Random
|
||||
|
||||
data CoinToss = H | T deriving (Read, Show, Eq)
|
||||
|
||||
parseToss :: String -> [CoinToss]
|
||||
parseToss [] = []
|
||||
parseToss (s:sx)
|
||||
| s == 'h' || s == 'H' = H : parseToss sx
|
||||
| s == 't' || s == 'T' = T : parseToss sx
|
||||
| otherwise = parseToss sx
|
||||
|
||||
notToss :: CoinToss -> CoinToss
|
||||
notToss H = T
|
||||
notToss T = H
|
||||
|
||||
instance Random CoinToss where
|
||||
random g = let (b, gb) = random g in (if b then H else T, gb)
|
||||
randomR = undefined
|
||||
|
||||
prompt :: (Read a) => String -> String -> (String -> Maybe a) -> IO a
|
||||
prompt msg err parse = do
|
||||
putStrLn msg
|
||||
line <- getLine
|
||||
let ans = parse line
|
||||
case ans of
|
||||
Nothing -> do
|
||||
putStrLn err
|
||||
prompt msg err parse
|
||||
Just ansB -> return ansB
|
||||
|
||||
showCat :: (Show a) => [a] -> String
|
||||
showCat = concatMap show
|
||||
|
||||
data Winner = Player | CPU
|
||||
|
||||
-- This may never terminate.
|
||||
runToss :: (RandomGen g) => [CoinToss] -> [CoinToss] -> g -> ([CoinToss], Winner)
|
||||
runToss player cpu gen =
|
||||
let stream = randoms gen
|
||||
run ss@(s:sx)
|
||||
| L.isPrefixOf player ss = player
|
||||
| L.isPrefixOf cpu ss = cpu
|
||||
| otherwise = s : run sx
|
||||
winner = run stream
|
||||
in if L.isSuffixOf player winner
|
||||
then (winner, Player)
|
||||
else (winner, CPU)
|
||||
|
||||
game :: (RandomGen g, Num a, Show a) => Bool -> a -> a -> g -> IO ()
|
||||
game cpuTurn playerScore cpuScore gen = do
|
||||
putStrLn $ "\nThe current score is CPU: " ++ show cpuScore
|
||||
++ ", You: " ++ show playerScore
|
||||
|
||||
let (genA, genB) = split gen
|
||||
promptPlayer check =
|
||||
prompt "Pick 3 coin sides: " "Invalid input." $ \s ->
|
||||
let tosses = parseToss s in
|
||||
if check tosses then Just tosses else Nothing
|
||||
promptCpu x = putStrLn $ "I have chosen: " ++ showCat x
|
||||
|
||||
(tosses, winner) <-
|
||||
if cpuTurn
|
||||
then do
|
||||
let cpuChoice = take 3 $ randoms gen
|
||||
promptCpu cpuChoice
|
||||
playerChoice <- promptPlayer $ \n -> n /= cpuChoice && 3 == length n
|
||||
return $ runToss playerChoice cpuChoice genA
|
||||
else do
|
||||
playerChoice <- promptPlayer $ \n -> 3 == length n
|
||||
let cpuChoice = case playerChoice of [a,b,_] -> [notToss b, a, b]
|
||||
promptCpu cpuChoice
|
||||
return $ runToss playerChoice cpuChoice genA
|
||||
|
||||
putStrLn $ "The sequence tossed was: " ++ showCat tosses
|
||||
|
||||
case winner of
|
||||
Player -> do
|
||||
putStrLn "You win!"
|
||||
game (not cpuTurn) (playerScore + 1) cpuScore genB
|
||||
CPU -> do
|
||||
putStrLn "I win!"
|
||||
game (not cpuTurn) playerScore (cpuScore + 1) genB
|
||||
|
||||
main :: IO ()
|
||||
main = do
|
||||
hSetBuffering stdin LineBuffering
|
||||
stdgen <- getStdGen
|
||||
let (cpuFirst, genA) = random stdgen
|
||||
game cpuFirst 0 0 genA
|
||||
Loading…
Add table
Add a link
Reference in a new issue