Slots
January 14, 2011
We begin by defining the images on the wheels of the slot machines and displaying instructions to the user:
(define wheel #("BAR" "BELL" "ORANGE" "LEMON" "PLUM" "CHERRY"))
(define (display-instructions)
(display "WELCOME TO THE CASINO") (newline)
(display "BET IN INCREMENTS OF $1 FROM $1 TO $100") (newline)
(display "BET $0 WHEN YOU ARE FINISHED") (newline))
Pull
emulates a single pull on the handle, with a bet of n dollars. The three wheels are spun and displayed, then the five possible outcomes are tested, a message is displayed to the user, and the gain or loss on the pull is returned:
(define (pull n)
(let ((x (randint 6)) (y (randint 6)) (z (randint 6)))
(display (vector-ref wheel x)) (display " ")
(display (vector-ref wheel y)) (display " ")
(display (vector-ref wheel z)) (newline)
(cond ((= x y z 0)
(let ((d (* 101 n)))
(display "***JACKPOT***") (newline)
(display "YOU WIN $") (display d) (newline) d))
((= x y z)
(let ((d (* 11 n)))
(display "***TOP DOLLAR***") (newline)
(display "YOU WIN $") (display d) (newline) d))
((or (= x y 0) (= x z 0) (= y z 0))
(let ((d (* 6 n)))
(display "***DOUBLE BAR***") (newline)
(display "YOU WIN $") (display d) (newline) d))
((or (= x y) (= x z) (= y z))
(let ((d (* 3 n)))
(display "***DOUBLE***") (newline)
(display "YOU WIN $") (display d) (newline) d))
(else (display "YOU LOSE $") (display n) (newline) (- n)))))
Play
manages a game. It displays instructions, then repeatedly gets a bet, error-checks the input, pulls the handle, and reports status. When the user places a $o bet it displays the final status:
(define (play)
(display-instructions)
(display "ENTER YOUR BET: ")
(let loop ((bet (read)) (purse 0))
(cond ((or (not (integer? bet)) (negative? bet))
(display "ENTER YOUR BET: ")
(loop (read) purse))
((< 100 bet)
(display "HOUSE LIMIT $100") (newline)
(display "ENTER YOUR BET: ") (loop (read) purse))
((<= 1 bet 100)
(let* ((p (pull bet)) (purse (+ p purse)))
(cond ((positive? purse)
(display "YOU HAVE $") (display purse))
((negative? purse)
(display "YOU OWE $") (display (- purse)))
(else (display "YOU ARE EVEN")))
(newline) (display "ENTER YOUR BET: ")
(loop (read) purse)))
((negative? purse)
(display "PLACE $") (display (- purse))
(display " ON THE KEYBOARD") (newline))
((positive? purse)
(display "COLLECT $") (display purse)
(display " FROM THE CASHIER") (newline))
(else (display "YOU BROKE EVEN") (newline)))))
Here’s a sample game:
> (play)
WELCOME TO THE CASINO
BET IN INCREMENTS OF $1 FROM $1 TO $10
BET $0 WHEN YOU ARE FINISHED
ENTER YOUR BET: 10
BAR PLUM LEMON
YOU LOSE $10
YOU OWE $10
ENTER YOUR BET: 10
BELL ORANGE ORANGE
***DOUBLE***
YOU WIN $30
YOU HAVE $20
ENTER YOUR BET: 10
BAR BAR CHERRY
***DOUBLE BAR***
YOU WIN $60
YOU HAVE $80
ENTER YOUR BET: 10
ORANGE ORANGE BAR
***DOUBLE***
YOU WIN $30
YOU HAVE $110
ENTER YOUR BET: 10
LEMON PLUM ORANGE
YOU LOSE $10
YOU HAVE $100
ENTER YOUR BET: 10
BELL LEMON BELL
***DOUBLE***
YOU WIN $30
YOU HAVE $130
ENTER YOUR BET: 10
CHERRY LEMON PLUM
YOU LOSE $10
YOU HAVE $120
ENTER YOUR BET: 0
COLLECT $120 FROM THE CASHIER
We used randint
from the Standard Prelude. You can run the program at http://programmingpraxis.codepad.org/A8iRnYpJ.
[…] 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.