module Main where import System.Random (randomRIO) import Data.IORef import Data.Char (toUpper) main :: IO () main = do putStrLn "*** ACEY DUCEY : HASKELL ***" running <- newIORef True gameOver <- newIORef False wallet <- newIORef 0 card1 <- newIORef 0 card2 <- newIORef 0 card3 <- newIORef 0 bet <- newIORef 0 resp <- askToSeeTheRules if resp then do displayRules else putStrLn "" runningLoop running gameOver wallet card1 card2 card3 bet putStrLn "OK, HOPE YOU HAD FUN." putStrLn "THANKS FOR PLAYING!" displayRules :: IO () displayRules = do putStrLn "ACEY DUCEY IS PLAYED IN THE FOLLOWING MANNER:" putStrLn "THE DEALER (COMPUTER) DEALS TWO CARDS FACE UP" putStrLn "YOU HAVE THE OPTION TO BET OR NOT BET DEPENDING" putStrLn "ON WHETHER OR NOT YOU FEEL THE NEXT CARD WILL " putStrLn "HAVE A VALUE BETWEEN THE FIRST TWO." putStrLn "" putStrLn "IF YOU DO NOT WANT TO BET, INPUT A 0 (ZERO)." runningLoop :: IORef Bool -> IORef Bool -> IORef Int -> IORef Int -> IORef Int -> IORef Int -> IORef Int -> IO () runningLoop running gameOver wallet card1 card2 card3 bet = do runningVal <- readIORef running if runningVal then do writeIORef wallet 100 writeIORef gameOver False gameLoop running gameOver wallet card1 card2 card3 bet else do putStrLn "" gameLoop :: IORef Bool -> IORef Bool -> IORef Int -> IORef Int -> IORef Int -> IORef Int -> IORef Int -> IO () gameLoop running gameOver wallet card1 card2 card3 bet = do gameOverVal <- readIORef gameOver walletVal <- readIORef wallet if not gameOverVal then do putStrLn $ "YOU NOW HAVE " ++ show walletVal ++ " DOLLARS." writeIORef card1 0 writeIORef card2 0 writeIORef card3 0 card1Val <- selectCard card1 card2 card3 writeIORef card1 card1Val card2Val <- selectCard card1 card2 card3 writeIORef card2 card2Val betVal <- askForBet walletVal writeIORef bet betVal if betVal > 0 then do card3Val <- selectCard card1 card2 card3 writeIORef card3 card3Val if ((card3Val > card1Val && card3Val < card2Val) || (card3Val > card2Val && card3Val < card1Val)) then do putStrLn "YOU WIN!!!" modifyIORef wallet (+ betVal) else do putStrLn "SORRY, YOU LOSE." modifyIORef wallet (\w -> w - betVal) money <- readIORef wallet if money < 1 then do putStrLn "SORRY FRIEND, YOU ARE BROKE." writeIORef gameOver True else putStrLn "" else do writeIORef gameOver True gameLoop running gameOver wallet card1 card2 card3 bet else do putStrLn "*** GAME OVER ***" runningVal <- askToPlayAgain writeIORef running runningVal runningLoop running gameOver wallet card1 card2 card3 bet selectCard :: IORef Int -> IORef Int -> IORef Int -> IO Int selectCard card1 card2 card3 = do card <- randomRIO (2, 14) card1Val <- readIORef card1 card2Val <- readIORef card2 card3Val <- readIORef card3 if card == card1Val || card == card2Val || card == card3Val then do selectCard card1 card2 card3 else do displayCard card return card askForBet :: Int -> IO Int askForBet wallet = do putStrLn "WHAT IS YOUR BET?" bet <- readLn if bet < 0 then do putStrLn "PLEASE BET A NON-NEGATIVE AMOUNT." askForBet wallet else if bet > wallet then do putStrLn "SORRY MY FRIEND, BUT YOU BET TOO MUCH." putStrLn $ "YOU HAVE ONLY " ++ show wallet ++ " DOLLARS TO BET." askForBet wallet else return bet askQuestion :: String -> IO Bool askQuestion prompt = do putStrLn (prompt ++ "?") ans <- getLine let answer = map toUpper ans if answer == "YES" || answer == "Y" then return True else if answer == "NO" || answer == "N" then return False else if answer == "" then do putStrLn "PLEASE ANSWER THE QUESTION." askQuestion prompt else do putStrLn "PLEASE ANSWER \"YES\" OR \"NO\"" askQuestion prompt askToSeeTheRules :: IO Bool askToSeeTheRules = askQuestion "DO YOU WANT TO SEE THE RULES" askToPlayAgain :: IO Bool askToPlayAgain = askQuestion "DO YOU WANT TO PLAY AGAIN" displayCard :: Int -> IO () displayCard card = do if card == 11 then putStrLn "JACK" else if card == 12 then putStrLn "QUEEN" else if card == 13 then putStrLn "KING" else if card == 14 then putStrLn "ACE" else putStrLn $ show card