Python Text-based Slot Machine Project
I completed this project as part of my Codecademy Python 3 course. I was tasked with researching, brainstorming and building an interactive terminal program.
Summary
This project allowed me to practise loops, functions, logic, conditional statements and variables. It is a text-based Python Slot Machine with a user balance and randomly generated outcomes on each spin. To win, the result must be three of the same letter on one line. There is a continuous loop providing the opportunity to spin again, ensuring replay value for the user.
Outline of Program Functionalities
Repository
Project Demo
Code Walkthrough
1. Collecting User Input - Deposits & Lines
Deposit Function
Firstly I created the function def deposit, responsible for collecting user input, using a while loop to continually prompt the user to insert a valid amount. I ensured the value is an integer through the .isdigit method, also checking that the value inputted is greater than 0 to continue.
Lines Function
I established global constants to include in the get_number_of_lines function, ensuring the program remains dynamic.
The function get_number_of_lines collects users' input to determine how many lines to bet on. There is a prompt for the user to input a number between 1-3 to the terminal, with MAX_LINES (3) added to the string. I also included an IF statement to ensure user input is <= 1 and <= MAX_LINES (3) to continue with the program.
# User Input Function - Deposit
def deposit():
while True:
amount = input("What would you like to deposit? £")
if amount.isdigit():
amount = int(amount)
if amount > 0:
break
else:
print("Amount must be greater than £0.")
else:
print("Please enter a number.")
return amount
# User Input Function - Betting
def get_number_of_lines():
while True:
lines = input("Enter the number of lines to bet on (1-" + str(MAX_LINES) + ")? ")
if lines.isdigit():
lines = int(lines)
if 1 <= lines <= MAX_LINES:
break
else:
print("Enter a valid number of lines")
else:
print("Please enter a number.")
return lines
2. Collect User Input - Get Bet
Bet Function
The get_bet function collects integer input from the user, where they can decide how much they wish to bet. I utilised the global constants established at the beginning of the program to implement another conditional statement, ensuring the MIN_BET and MAX_BET is applied to user input. Further to this, I added an f string when printing an error message to the terminal, providing further instruction to the user.
Main Function
Following this, I added an f string to the main function, embedding {bet} amount with {lines} to print to the terminal. In addition, I included a while loop in the main function to implement total_bet variable, bet multiplied by the number of lines user inputted. If total bet > balance, a string is printed to terminal to inform the user of the current balance.
# Get Bet Function:
def get_bet():
while True:
amount = input("What would you like to bet on each line? £")
if amount.isdigit():
amount = int(amount)
if MIN_BET <= amount <= MAX_BET:
break
else:
print(f"Amount must be between ${MIN_BET} - ${MAX_BET}.")
else:
print("Please enter a number.")
return amount
# Addition to Main Function:
total_bet = bet * lines
if total_bet > balance:
print(f"You do not have enough to bet that amount, your current balance is: ${balance}")
else:
break
3. Slot Machine Functionality
Constants and Modules
I imported the random module and added it to the program, this was used to randomly generate slot machine values. In addition, I included more global constants to the program – ROWS (3) COLS (3), ensuring further dynamicity to the program, and established the quantity for each string value, A-D.
Slot Machine Spin Function
Using three parameters - rows, cols, symbols, I generated what symbols will be in each column based on the frequency of symbols established in symbol_count.
I then defined the all_symbols list and create a for loop. The .items method provides the dictionary's key-value pairs (symbol) and (symbol_count), avoiding manually referencing the values. I then created an additional loop to loop through the symbol count, adding to the all_symbols list.
Column Values
Following the creation of the all_symbols list, the next step was establishing what values will be added to each column:
# Slot Machine Functions - Generating Spins
def get_slot_machine_spin(rows, cols, symbols):
all_symbols = []
for symbol, symbol_count in symbols.items():
for _ in range(symbol_count):
all_symbols.append(symbol)
columns = []
for _ in range(cols):
column = []
current_symbols = all_symbols[:]
for _ in range(rows):
value = random.choice(current_symbols)
current_symbols.remove(value)
column.append(value)
columns.append(column)
return columns
4. Printing Machine to Console
I needed to determine the number of rows to have based on the number of columns. The number of rows that I have is the number of elements in each of the columns. Created a for loop, where columns[0], assuming we always have a minimum of one column. I then created a second for loop through the items in all my columns, only printing the first value in the current row.
I utilised the "|" operator to add separation between the values when printing to the terminal. Created IF statement to ensure the operator is not printed after the final value on each column. The enumerate method gives us the index and the column whilst it loops through, allowing me to add i != len(columns) – 1. This is the maximum index we can access an element inside the columns list, therefore only printing the "|" operator when it meets the condition. Added end parameter to print statement to start a new line.
# Printing Slot Machine
def print_slot_machine(columns):
for row in range(len(columns[0])):
for i, column in enumerate(columns):
if i != len(columns) - 1:
print(column[row], end=" | ")
else:
print(column[row], end="")
print()
# Example Outcome
B | A | D
B | C | B
C | B | D
5. Check Winnings Function
Symbol Values
Added symbol_value constant to determine the multipliers for the bet return, the rarer the symbol, the higher the return.
Check Winnings
I created the check_winnings function, using columns, lines, bet, values as parameters. The rows determine the winnings the user has placed a bet on. In the for loop, I check that every symbol in the line is the same. For else loop created, checking every column for symbol, breaking from the loop if symbol != symbol_to_check; otherwise, the user has won, therefore value[symbol] * bet. The bet is the bet on each line, not the total bet.
# Symbol Values
symbol_value = {
"A": 5,
"B": 4,
"C": 3,
"D": 2
}
# Check Winnings Function
def check_winnings(columns, lines, bet, values):
winnings = 0
winning_lines = []
for line in range(lines):
symbol = columns[0][line]
for column in columns:
symbol_to_check = column[line]
if symbol != symbol_to_check:
break
else:
winnings += values[symbol] * bet
winning_lines.append(line + 1)
return winnings, winning_lines
6. Spin Function and Main Function
Spin Function
The spin() function executes a single game: displaying user balance, stating the bet total, getting the result and printing the result onto the terminal, winning_lines – total_bet.
Main Function
I added a while loop to the main function, displaying the current balance on the terminal through an f string and giving the user an input prompt to either press Enter to continue playing and rerun the program or exit the game.
# Spin Function
def spin(balance):
lines = get_number_of_lines()
while True:
bet = get_bet()
total_bet = bet * lines
if total_bet > balance:
print(
f"You do not have enough to bet that amount, your current balance is: ${balance}")
else:
break
# Main Function - Loop to keep playing
def main():
balance = deposit()
while True:
print(f"Current balance is ${balance}")
answer = input("Press enter to play (q to quit).")
if answer == "q":
break
balance += spin(balance)
print(f"You left with ${balance}")
main()