import random
# We use a class to represent game state instead of globals.
# There's a variety of reasons to do this, it:
# - isolates state, so you can write more functional code
# - keeps the Game State out of the global scope, thus maintaining separation of concerns
# - allows for multiple games to be played, or multiple different players
# - makes for easy serialization (saving) of the game state, if wanted
# - makes it easier to extend
# - etc.
class GameState:
wins = 0
losses = 0
cash = 100
# This constructor allows for GameStates to be created in memory with an arbitrary number of wins, losses and cash.
# For example, you can use this with serialization to save a game state and load it later
# You could also add a difficulty selection to start with less or more money
def __init__(self, wins=0, losses=0, cash=100):
self.wins = wins
self.losses = losses
self.cash = cash
# I'm not sure if this is stylistically best practice in Python, or if it would be preferred to have a top-level
# factory function. This function just creates a new game with defaults.
# It can be argued this is unnecessary given GameState's default constructor, but I feel it adds legibility.
@staticmethod
def create_default():
return GameState()
# The following has been removed and moved to Game State.
# x = 0 - renamed to wins. You should try and always have descriptive variable names
# y = 0 - renamed to losses.
# cash = 100
def gamba_game(game_state, stake):
# The following lines were removed. You should generally avoid managing state like this.
# Instead, consider these as inputs, and pass them as function parameters. Where possible, parameterize everything.
# In this case, we expect a GameState which contains these variables
# global x
# global y
# global cash
game_roll = random.randint(1,100)
print(f"You bet ${stake}")
if game_roll > 51:
print("Yes!")
game_state.wins = game_state.wins + 1
game_state.cash = game_state.cash + stake # I modified the hard-coded value of 10 to be `stake` instead, this way you can play higher or lower stake games
print(f"You won ${stake}, \nyour balance is ${game_state.cash}")
# gamba_sesh() ; removed because this causes unbounded recursion
else:
print("No")
game_state.losses = game_state.losses + 1
game_state.cash = game_state.cash - stake
print(f"You lost ${stake}, \nyour balance is ${game_state.cash}")
# gamba_sesh() ; removed because this causes unbounded recursion
def gamba_start(game_state):
print("Welcome to the casino! \n")
stake = 10
while True:
player_input = input(f"You have ${game_state.cash}, \nbets are ${stake}. \nWould you like to play? [Y]es/[N]o: ")
# Validates the input, before if someone input capital Y or N it would quit
player_input = player_input.lower()
# Use a match statement when comparing input to a known, limited set of options.
match player_input:
case "y" | "yes":
gamba_game(game_state, stake)
case "n" | "no":
print("That's prbably a good idea")
break
case _:
print("Unrecognized Input.")
# Changed to be smaller than or equal to 0
# In normal cases, you wouldn't go below zero,
# But if in the future you allow the player to change the stake,
# There could come a circumstance where the player attempts to bet more money than they have
# and they can continue playing with negative cash
# Generally, it's important to think about whether or not you want EXACTLY 0,
# Or 0 or less.
if game_state.cash <= 0:
print("Dude I just lost it all")
print(f"wins {game_state.wins}")
print(f"losses {game_state.losses}")
break
print()
print(f"{game_state.wins} wins / {game_state.losses} losses")
# if player_input in ["yes","y"]:
# return gamba_game()
# else:
# print("That's prbably a good idea")
# break
# All of the following is removed as unecessary
# def gamba_sesh(game_state):
# # global x
# # global y
# # global cash
# while True:
#
# if cash == 0:
# print("Dude I just lost it all")
# print(f"wins {x}")
# print(f"losses {y}")
# break
# else:
# play_again = input("Play again (yes/no): ")
#
# if play_again in ["yes","y"]:
# gamba_game()
# break
# else:
# print("One more and I'm out!")
# gamba_game()
# break
game_state_singleton = GameState.create_default()
gamba_start(game_state_singleton)