# Slot Machine in Python

I have made this little program which allows you to play a slot machine:

import random
import time
import os
print()
print('''Welcome to the Slot Machine
Answer with yes/no. you can also use y/n
There is no case sensitivity, type it however you like!
To win you must get one of the following combinations:
BAR\tBAR\tBAR\t\tpays\t£250
BELL\tBELL\tBELL/BAR\tpays\t£20
PLUM\tPLUM\tPLUM/BAR\tpays\t£14
ORANGE\tORANGE\tORANGE/BAR\tpays\t£10
CHERRY\tCHERRY\tCHERRY\t\tpays\t£7
CHERRY\tCHERRY\t  -\t\tpays\t£5
CHERRY\t  -\t  -\t\tpays\t£2
7\t  7\t  7\t\tpays\t The Jackpot!
''')
time.sleep(10)
#Constants:
INIT_STAKE = 50
INIT_BALANCE = 1000
ITEMS = ["CHERRY", "LEMON", "ORANGE", "PLUM", "BELL", "BAR", "7"]

firstWheel = None
secondWheel = None
thirdWheel = None
stake = INIT_STAKE
balance = INIT_BALANCE

def play():
global stake, firstWheel, secondWheel, thirdWheel
while(stake != 0 and playQuestion == True):
firstWheel = spinWheel()
secondWheel = spinWheel()
thirdWheel = spinWheel()
printScore()

'''
Asks the player if he wants to play again.
expecting from the user to answer with yes, y, no or n
No case sensitivity in the answer. yes, YeS, y, y, nO . . . all works
'''
global stake
global balance
while(True):
os.system('cls' if os.name == 'nt' else 'clear')
if (balance <=1):
print ("Machine balance reset.")
balance = 1000

print ("The Jackpot is currently: £" + str(balance) + ".")
answer = input("Would you like to play? Or check your money? ")
return True
print("You ended the game with £" + str(stake) + " in your hand. Great job!")
time.sleep(5)
return False
print ("You currently have £" + str(stake) + ".")
else:
print("Whoops! Didn't get that.")

def spinWheel():
'''
returns a random item from the wheel
'''
randomNumber = random.randint(0, 5)
return ITEMS[randomNumber]

def printScore():
'''
prints the current score
'''
global stake, firstWheel, secondWheel, thirdWheel, balance
if((firstWheel == "CHERRY") and (secondWheel != "CHERRY")):
win = 2
balance = balance - 2
elif((firstWheel == "CHERRY") and (secondWheel == "CHERRY") and (thirdWheel != "CHERRY")):
win = 5
balance = balance - 5
elif((firstWheel == "CHERRY") and (secondWheel == "CHERRY") and (thirdWheel == "CHERRY")):
win = 7
balance = balance - 7
elif((firstWheel == "ORANGE") and (secondWheel == "ORANGE") and ((thirdWheel == "ORANGE") or (thirdWheel == "BAR"))):
win = 10
balance = balance - 10
elif((firstWheel == "PLUM") and (secondWheel == "PLUM") and ((thirdWheel == "PLUM") or (thirdWheel == "BAR"))):
win = 14
balance = balance - 14
elif((firstWheel == "BELL") and (secondWheel == "BELL") and ((thirdWheel == "BELL") or (thirdWheel == "BAR"))):
win = 20
balance = balance - 20
elif((firstWheel == "BAR") and (secondWheel == "BAR") and (thirdWheel == "BAR")):
win = 250
balance = balance - 250
elif((firstWheel == "7") and (secondWheel == "7") and (thridWheel == "7")):
win = balance
balance = balance - win
else:
win = -1
balance = balance + 1

stake += win
if win == balance:
print ("You won the JACKPOT!!")
if(win > 0):
print(firstWheel + '\t' + secondWheel + '\t' + thirdWheel + ' -- You win £' + str(win))
time.sleep(3)
os.system('cls' if os.name == 'nt' else 'clear')
else:
print(firstWheel + '\t' + secondWheel + '\t' + thirdWheel + ' -- You lose')
time.sleep(2)
os.system('cls' if os.name == 'nt' else 'clear')

play()

• Avoid time.sleep Jul 22, 2015 at 12:46

I'd say you should encapsulate as much of your code as possible into functions and classes, limiting the global state when possible. This serves two purposes - the first is that it improves debugging (by limiting the odds that something unintentionally alters global state) and readability (by making it easier to understand what everything does).

## Encapsulate functionality in a class

I'd create a class called SlotMachine that holds the global state. It should store constants as class-level variables, and other values as instance-variables (or better yet properties). Then all of your methods should belong to that class.

## Keep related constants in an Enum

You have a bunch of constants related to what the slot reel is showing - these can be better described as an Enum

class Reel(Enum):
CHERRY = 1
LEMON = 2
ORANGE = 3
PLUM = 4
BELL = 5
BAR = 6
SEVEN = 7


and then use Reel.CHERRY, for example, in the future. This also helps avoid magic numbers. If you don't have Python 3.4 or later you'll have to make your own homegrown Enum class, or use something like

def enum(*sequential, **named):
enums = dict(zip(sequential, range(1, len(sequential) + 1)), **named)
return type('Enum', (), enums)

Reel = enum("CHERRY", "LEMON", "ORANGE", "PLUM", "BELL", "BAR", "SEVEN")


or use the enum34 library which is a backport of 3.4's version of Enum.

## Simplify boolean expressions

You don't need parentheses around your boolean expressions - they make it more confusing. Instead of something like answer == "yes" or answer == "y" you can do answer in ["yes", "y"].

## Be clever with properties

Now that we're using a class, we can use a property to encapsulate behavior that you want. For example,

@property
def keep_playing(self):
while(True):
os.system('cls' if os.name == 'nt' else 'clear')
if self.current_jackpot <= 1:
print("Machine balance reset.")
balance = 1000

print("The Jackpot is currently: £{}.".format(self.current_jackpot))
answer = input("Would you like to play? Or check your money? ").lower()
return True
print("You ended the game with £{} in your hand. Great job!".format(self.current_stake))
return False
print("You currently have £{}.".format(stake))
else:
print("Whoops! Didn't get that.")


now any time you want to find out if they want to keep playing, just use

if self.keep_playing:
...


## Use dictionaries to simplify payout logic

Instead of all of those if statements, do something like this

payout = {
Reel.CHERRY: 7,
Reel.ORANGE: 10,
Reel.PLUM: 14,
Reel.BELL: 20,
Reel.BAR: 250,
Reel.SEVEN: 'jackpot'
}

if first == SlotMachine.Reel.CHERRY:
if second == SlotMachine.Reel.CHERRY:
win = 7 if third == SlotMachine.Reel.CHERRY else 5
else:
win = 2
else:
if first == second == third:
win = SlotMachine.payout[first]
win = self.current_jackpot if win == 'jackpot' else win
else:
win = -1

if win == self.current_jackpot:
print("You won the JACKPOT!!")
else:
print('\t'.join(map(lambda x: x.name.center(6), (first, second, third))))
print("You {} £{}".format("won" if win > 0 else "lost", win)
self.current_stake += win
self.current_jackpot -= win


Note - your payout in the instructions isn't consistent with your logic, but I just kept it as your logic is. You can adjust this function and the dictionary to have more complicated arrangements and expand the payouts. Also, you're missing payouts for Lemons.

## Altogether

import random
import time
import os
from enum import Enum

class SlotMachine:
INITIAL_STAKE = 50
INITIAL_JACKPOT = 1000

class Reel(Enum):
CHERRY = 1
LEMON = 2
ORANGE = 3
PLUM = 4
BELL = 5
BAR = 6
SEVEN = 7

_values = list(Reel)
payout = {
Reel.CHERRY: 7,
Reel.ORANGE: 10,
Reel.PLUM: 14,
Reel.BELL: 20,
Reel.BAR: 250,
Reel.SEVEN: 'jackpot'
}

def __init__(self, stake=INITIAL_STAKE, jackpot=INITIAL_JACKPOT):
self.current_stake = stake
self.current_jackpot = jackpot

@property
def keep_playing(self):
while(True):
os.system('cls' if os.name == 'nt' else 'clear')
if self.current_jackpot <= 1:
print("Machine balance reset.")
self.current_jackpot = SlotMachine.INITIAL_JACKPOT

print("The Jackpot is currently: £{}.".format(self.current_jackpot))
answer = input("Would you like to play? Or check your money? ").lower()
return True
print("You ended the game with £{} in your hand. Great job!".format(self.current_stake)
return False
print("You currently have £{}.".format(stake))
else:
print("Whoops! Didn't get that.")

def _play_round(self):
first, second, third = random.choice(SlotMachine._values), random.choice(SlotMachine._values), random.choice(SlotMachine._values)

if first == SlotMachine.Reel.CHERRY:
if second == SlotMachine.Reel.CHERRY:
win = 7 if third == SlotMachine.Reel.CHERRY else 5
else:
win = 2
else:
if first == second == third:
win = SlotMachine.payout[first]
win = self.current_jackpot if win == 'jackpot' else win
else:
win = -1

if win == self.current_jackpot:
print("You won the JACKPOT!!")
else:
print('\t'.join(map(lambda x: x.name.center(6), (first, second, third))))
print("You {} £{}".format("won" if win > 0 else "lost", win))
self.current_stake += win
self.current_jackpot -= win

def play(self):
while self.current_stake and self.keep_playing:
self._play_round()

if __name__ == '__main__':
print('''
Welcome to the Slot Machine
Answer with yes/no. you can also use y/n
There is no case sensitivity, type it however you like!
To win you must get one of the following combinations:
BAR\tBAR\tBAR\t\tpays\t£250
BELL\tBELL\tBELL/BAR\tpays\t£20
PLUM\tPLUM\tPLUM/BAR\tpays\t£14
ORANGE\tORANGE\tORANGE/BAR\tpays\t£10
CHERRY\tCHERRY\tCHERRY\t\tpays\t£7
CHERRY\tCHERRY\t  -\t\tpays\t£5
CHERRY\t  -\t  -\t\tpays\t£2
7\t  7\t  7\t\tpays\t The Jackpot!
''')
SlotMachine().play()

• Jul 25, 2015 at 14:48

There are 6 global variables in your file. Considering a simple app that is 10x the lines of code of this, you would have written 60 global variables. Each global variable by definition can be modified from anywhere in the code. This is impossible to keep track of. Each function should be as pure as possible, taking input and giving output not caring of the state of the world.

Use boolean expressions directly, no need to have condition == True