In today’s Programming Praxis exercise, our goal is to create a game that simulates a slot machine. Let’s get started, shall we?
import Control.Monad import Data.List import System.Random import Text.Printf import Text.Read.HT
Pulling the lever spins the wheels, prints the result and returns the amount of money gained or lost.
pull :: Int -> IO Int pull n = do ws <- replicateM 3 $ randomRIO (0,5) putStrLn . unwords $ map (wheel !!) ws result . group $ sort ws where wheel = words "BAR BELL ORANGE LEMON PLUM CHERRY" result [[0,0,0]] = win "JACKPOT" 101 result [_] = win "TOP DOLLAR" 11 result [[0,0],_] = win "DOUBLE BAR" 6 result [_,_] = win "DOUBLE" 3 result _ = printf "YOU LOSE $%d\n" n >> return (-n) win msg d = printf "***%s***\nYOU WIN $%d\n" msg (n*d) >> return (n*d)
In order not to have to repeat ourselves in the main loop, we create a function that gets a valid bet.
prompt :: IO Int prompt = do putStr "ENTER YOUR BET: " maybe prompt check . maybeRead =<< getLine where check bet | bet < 0 = prompt | bet > 100 = putStrLn "HOUSE LIMIT $100" >> prompt | otherwise = return bet
Playing the game shows the instructions and starts playing. After every pull of the lever, the current balance is shown. Quitting the game (by betting $0) prints the final balance.
main :: IO () main = instructions >> loop 0 where instructions = putStrLn "WELCOME TO THE CASINO\n\ \BET IN INCREMENTS OF $1 FROM $1 TO $100\n\ \BET $0 WHEN YOU ARE FINISHED" loop purse = prompt >>= \bet -> if bet == 0 then quit purse else fmap (+ purse) (pull bet) >>= \n -> status n >> loop n status n | n > 0 = printf "YOU HAVE $%d\n" n | n < 0 = printf "YOU OWE $%d\n" (-n) | otherwise = putStrLn "YOU ARE EVEN" quit total | total > 0 = printf "COLLECT $%d FROM THE CASHIER\n" total | total < 0 = printf "PLACE $%d ON THE KEYBOARD\n" (-total) | otherwise = putStrLn "YOU BROKE EVEN"
Here’s a sample game:
WELCOME TO THE CASINO BET IN INCREMENTS OF $1 FROM $1 TO $100 BET $0 WHEN YOU ARE FINISHED ENTER YOUR BET: 100 LEMON BELL BELL ***DOUBLE*** YOU WIN $300 YOU HAVE $300 ENTER YOUR BET: 100 BAR ORANGE PLUM YOU LOSE $100 YOU HAVE $200 ENTER YOUR BET: 100 BELL PLUM BELL ***DOUBLE*** YOU WIN $300 YOU HAVE $500 ENTER YOUR BET: 100 BAR CHERRY BAR ***DOUBLE BAR*** YOU WIN $600 YOU HAVE $1100 ENTER YOUR BET: 0 COLLECT $1100 FROM THE CASHIER
If only real slot machines were this profitable :)