## Programming Praxis – Slots

In today’s Programming Praxis exercise, our goal is to create a game that simulates a slot machine. Let’s get started, shall we?

Some imports:

```import Control.Monad
import Data.List
import System.Random
import Text.Printf
```

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
LEMON BELL BELL
***DOUBLE***
YOU WIN \$300
YOU HAVE \$300
BAR ORANGE PLUM
YOU LOSE \$100
YOU HAVE \$200
BELL PLUM BELL
***DOUBLE***
YOU WIN \$300
YOU HAVE \$500