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
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 :)

About these ads

Tags: , , , , , , ,

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s


Follow

Get every new post delivered to your Inbox.

Join 35 other followers

%d bloggers like this: