import Control.Monad
import Data.List
import System.Random
import Text.Printf
import Text.Read.HT
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)
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
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"
My Python solution. Like the Haskell above, I factored out the _win
procedure. I'm not terribly happy with the maze of ifs and elifs my code grew
into, but it'll do.
#!/usr/bin/env python
from random import randrange
WHEEL = ["BAR", "BELL", "ORANGE", "LEMON", "PLUM", "CHERRY"]
def display_instructions():
print "WELCOME TO THE CASINO"
print "BET IN INCREMENTS OF $1 FROM $1 TO $100"
print "BET $0 WHEN YOU ARE FINISHED"
return
def pull(n):
def _win(msg, d):
print "***{0}***".format(msg)
print "YOU WIN ${0}".format(n * d)
return n * d
x, y, z = randrange(6), randrange(6), randrange(6)
print WHEEL[x], WHEEL[y], WHEEL[z]
if x == y == z == 0:
return _win("JACKPOT", 101)
elif x == y == z:
return _win("TOP DOLLAR", 11)
elif x == y == 0 or x == z == 0 or y == z == 0:
return _win("DOUBLE BAR", 6)
elif x == y or x == z or y == z:
return _win("DOUBLE", 3)
else:
print "YOU LOSE ${0}".format(n)
return -n
def play():
display_instructions()
bet, purse = 1, 0
while bet != 0:
bet = raw_input("ENTER YOUR BET:\t")
try:
bet = int(bet)
except ValueError:
continue
if bet > 100:
print "HOUSE LIMIT $100"
continue
elif 1 <= bet <= 100:
purse += pull(bet)
if purse > 0:
print "YOU HAVE ${0}".format(purse)
elif purse < 0:
print "YOU OWE ${0}".format(-purse)
else:
print "YOU ARE EVEN"
if purse < 0:
print "PLACE ${0} ON THE KEYBOARD".format(-purse)
elif purse > 0:
print "COLLECT ${0} FROM THE CASHIER".format(purse)
else:
print "YOU BROKE EVEN"
return
Waddling through old code is fun, but I feel this exercise isn’t all it could have been. Slot machines are based on interesting statistical models that keep the game addictive while ensuring the House wins. In that vein, I modified the original task and created a weighted slot machine. I know it doesn’t earn me brownie points, but I hope someone finds it interesting or fun.
I also took the betting out of it so I can just hit the spin key mindlessly, like on a real machine :)
[…] today’s Programming Praxis exercise, our goal is to create a game that simulates a slot machine. […]
My Haskell solution (see http://bonsaicode.wordpress.com/2011/01/14/programming-praxis-slots/ for a version with comments):
My Python solution. Like the Haskell above, I factored out the
_win
procedure. I'm not terribly happy with the maze of ifs and elifs my code grew
into, but it'll do.
#!/usr/bin/env python
from random import randrange
WHEEL = ["BAR", "BELL", "ORANGE", "LEMON", "PLUM", "CHERRY"]
def display_instructions():
print "WELCOME TO THE CASINO"
print "BET IN INCREMENTS OF $1 FROM $1 TO $100"
print "BET $0 WHEN YOU ARE FINISHED"
return
def pull(n):
def _win(msg, d):
print "***{0}***".format(msg)
print "YOU WIN ${0}".format(n * d)
return n * d
x, y, z = randrange(6), randrange(6), randrange(6)
print WHEEL[x], WHEEL[y], WHEEL[z]
if x == y == z == 0:
return _win("JACKPOT", 101)
elif x == y == z:
return _win("TOP DOLLAR", 11)
elif x == y == 0 or x == z == 0 or y == z == 0:
return _win("DOUBLE BAR", 6)
elif x == y or x == z or y == z:
return _win("DOUBLE", 3)
else:
print "YOU LOSE ${0}".format(n)
return -n
def play():
display_instructions()
bet, purse = 1, 0
while bet != 0:
bet = raw_input("ENTER YOUR BET:\t")
try:
bet = int(bet)
except ValueError:
continue
if bet > 100:
print "HOUSE LIMIT $100"
continue
elif 1 <= bet <= 100:
purse += pull(bet)
if purse > 0:
print "YOU HAVE ${0}".format(purse)
elif purse < 0:
print "YOU OWE ${0}".format(-purse)
else:
print "YOU ARE EVEN"
if purse < 0:
print "PLACE ${0} ON THE KEYBOARD".format(-purse)
elif purse > 0:
print "COLLECT ${0} FROM THE CASHIER".format(purse)
else:
print "YOU BROKE EVEN"
return
if __name__ == "__main__":
play()
Oh no! I had a couple typos (messed up closing the code tag, and extra ” in ) in the comment above. Apologies!
Waddling through old code is fun, but I feel this exercise isn’t all it could have been. Slot machines are based on interesting statistical models that keep the game addictive while ensuring the House wins. In that vein, I modified the original task and created a weighted slot machine. I know it doesn’t earn me brownie points, but I hope someone finds it interesting or fun.
I also took the betting out of it so I can just hit the spin key mindlessly, like on a real machine :)
http://paste.lisp.org/display/119226
… incidentally, selecting a random wheel stop is a variant of the algorithm for selecting fortunes from the exercise #192.