I am practicing in Python and I decided to create a simple roulette simulation with colors only for now. However, I also wanted to make it possible to bet on color. But it seems like I did something wrong, since for some reason I can't use the global variable 'balance' in one of the function. Also, I didn't come up with the idea of how to make bet a global variable. I tried to take it out so that it become the global variable with input function, however in this case it has the same issue as with balance variable.
import random
balance = 100
# user decides how much they will bet
def start():
print("Place your bet:")
bet = int(input(">"))
if bet > balance:
insufficient_funds()
else:
simulate()
# if user placed too much
def insufficient_funds():
print("Oops, your don't have enough funds to place a bet")
start()
# color choose and roulette simulation
def simulate():
print("Choose Red or for Black:")
answer = input("> ")
result = random.randint(1, 2)
if result == 1 and answer == "Red":
print("You won")
balance += bet
print(f"Your balance now {balance}")
start()
elif result == 2 and answer == "Black":
print("You won")
balance += bet
print(f"Your balance now {balance}")
start()
else:
print("You lost!")
balance -= bet
print(f"Your balance now {balance}")
start()
start()
I know it is super basic, but for now I try to make it as simple as possible to practice with python's fundamental things w/o using a lot of modules. I'd extremely appreciate if you could help me out with it.
Your code is awesome. The way python works, you have to explicitly tell it that you're going to use a global variable by using the global keyword. If you don't, it will create a new local variable within the function. Try:
import random
balance = 100
# user decides how much they will bet
def start():
global balance
print("Place your bet: ")
bet = int(input(">"))
if bet > balance:
insufficient_funds()
else:
simulate(bet)
# if user placed too much
def insufficient_funds():
print("Oops, your don't have enough funds to place a bet")
start()
# color choose and roulette simulation
def simulate(bet_amount):
global balance
print("Choose Red or for Black:")
answer = input("> ")
result = random.randint(1, 2)
if result == 1 and answer == "Red":
print("You won")
balance += bet_amount
print(f"Your balance now {balance}")
start()
elif result == 2 and answer == "Black":
print("You won")
balance += bet_amount
print(f"Your balance now {balance}")
start()
else:
print("You lost!")
balance -= bet_amount
print(f"Your balance now {balance}")
start()
start()
This is how you let Python know you're calling a global variable. To avoid variable shadowing, we can use bet in the start function, and then when we call it in the simulate function, we'll tell it that we need a bet_amount.
Your functions should isolate levels of concerns that are semantically meaningful. This would make the code easier to understand and maintain. The process can be decomposed into:
A betting phase where the user selects a pocket and bet amount
A rolling phase where the ball is rolled and falls in a random pocket
A game loop to repeatedly go through the phases and update wins & losses.
Each function should be standalone and perform its work without affecting data outside of it (i.e. no global variable). This will allow testing the "phase" functions independently before putting them together in the main loop. If you find any issue while testing these functions, you will know that there is no dependencies from external states so the problem is in the limited scope of the function itself.
Here's an example:
Rolling Phase...
from random import choice
from time import sleep
# CONSTANTS
pockets = ["00"]+[str(n) for n in range(37)]
groups = ["Red","Black","Even","Odd","Low","High"]
reds = [1,3,5,7,9,12,14,16,18,19,21,23,25,27,30,32,34,36]
def roll():
print("Rolling! ... ", end="")
sleep(2)
number = choice(pockets)
N = int(number)
color = "" if N<1 else "Red" if N in reds else "Black"
oddEven = "" if N<1 else "Odd" if N%2 else "Even"
lowHigh = "" if N<1 else "Low" if N<=18 else "High"
print(number, color)
return number,color,oddEven,lowHigh
Betting Phase...
def placeBet(maxAmount):
while True:
playerChoice = input("Pocket number or group: ")
if playerChoice not in pockets + groups:
print("must chose a number (00,0,1..36)")
print("or group (Red, Black, Odd, Even, Low, High)")
else: break
while True:
betValue = input("Amount to bet: ")
try:
betValue = int(betValue)
if betValue <= maxAmount: break
print("Not enough funds")
except ValueError:
print("invalid number")
return playerChoice, betValue
Main game loop...
def playRoulette(balance=100):
while balance:
pocket, amount = placeBet(balance)
if pocket in roll():
print("You win!")
balance += amount # or balance += payBack(pocket,amount)
else:
print("You lose!")
balance -= amount
print(f"Your balance is now {balance}")
print("Game Over!")
Winning payback could be computed in a separate function if you want to make it dependent on the odds of the selected pocket (e.g. a specific number is 35 to 1; Red, Even, ... are 1 to 1 bets)
Testing
roll()
Rolling! ... 6 Black
('6', 'Black', 'Even', 'Low')
roll()
Rolling! ... 33 Black
('33', 'Black', 'Odd', 'High')
placeBet(50)
Pocket number or group: green
must chose a number (00,0,1..36)
or group (Red, Black, Odd, Even, Low, High)
Pocket number or group: 99
must chose a number (00,0,1..36)
or group (Red, Black, Odd, Even, Low, High)
Pocket number or group: Red
Amount to bet: xxx
invalid number
Amount to bet: 65
Not enough funds
Amount to bet: 24
('Red', 24)
Sample run
playRoulette()
Pocket number or group: Red
Amount to bet: 10
Rolling! ... 2 Black
You lose!
Your balance is now 90
Pocket number or group: Black
Amount to bet: 25
Rolling! ... 12 Black
You win!
Your balance is now 115
Pocket number or group: 00
Amount to bet: 120
Not enough funds
Amount to bet: 115
Rolling! ... 9 Red
You lose!
Your balance is now 0
Game Over!
Related
I'm practicing with a simple roulette program. At this moment, I have a problem with balance input(), if I put it outside the function, the function betting() doesn't recognize it. But, if I put it inside, the function, the program asks me again to input the amount of money and it overwrites the amount of money after the bet.
How to avoid that, so the program asks me only once for input? This is my code:
import random
def betting():
balance = float(input("How much money do you have? $"))
your_number = int(input("Choose the number between 0 and 36, including these: "))
if your_number < 0 or your_number > 36:
print("Wrong input, try again!")
betting()
else:
bet = float(input("Place your bet: "))
while balance > 0:
if bet > balance:
print("You don't have enough money! Place your bet again!")
betting()
else:
number = random.randint(0,36)
print(f"Your number is {your_number} and roulette's number is {number}.")
if number == your_number:
balance = balance + bet*37
print(f"You won! Now you have ${balance}!")
else:
balance = balance - bet
print(f"You lost! Now you have ${balance}!")
betting()
else:
print("You don't have more money! Goodbye!")
quit()
def choice():
choice = str(input("Y/N "))
if choice.lower() == "y":
betting()
elif choice.lower() == "n":
print("Goodbye!")
quit()
else:
print("Wrong input, try again!")
choice()
print("Welcome to the Grand Casino! Do you want to play roulette?")
choice()
Pass the balance as a function parameter to betting(). Then ask once in the choice() function
import random
def betting(balance):
your_number = int(input("Choose the number between 0 and 36, including these: "))
if your_number < 0 or your_number > 36:
print("Wrong input, try again!")
return your_number
else:
bet = float(input("Place your bet: "))
while balance > 0:
if bet > balance:
print("You don't have enough money! Place your bet again!")
betting(balance)
else:
number = random.randint(0,36)
print(f"Your number is {your_number} and roulette's number is {number}.")
if number == your_number:
balance = balance + bet*37
print(f"You won! Now you have ${balance}!")
else:
balance = balance - bet
print(f"You lost! Now you have ${balance}!")
betting(balance)
else:
print("You don't have more money! Goodbye!")
quit()
def choice():
choice = str(input("Y/N "))
if choice.lower() == "y":
balance = float(input("How much money do you have? $"))
betting(balance)
elif choice.lower() == "n":
print("Goodbye!")
quit()
else:
print("Wrong input, try again!")
choice()
print("Welcome to the Grand Casino! Do you want to play roulette?")
choice()
You can ask for both at the same time and split the given string:
inp = input("State how much money you have and a number between 0 and 36 inclusive, separated by space: ")
bal, num = inp.split()
Python allocate a variable in the closest namespace.
This mean that balance is allocated in 'betting' namespace and will not be known outside 'betting'.
What you need is a global variable.
'global' mean that the variable must be allocated in the embracing namespace.
def betting():
global balance
print( balance)
def choice():
global balance
sel = input( ...)
if sel.lower() == 'y':
balance = int( input(">"))
betting()
choice()
Please note that you used 'choice' for 2 purposes. It's a function but it is also a variable. While it is possible, it is considered a bad habit.
The condition is that the program will end:
-if the balance is less than or equal to zero.
-if the balance is greather than or equal to 200.
But the problem is that it ends after I input 1 or 2 (1 for heads and 2 for tails) and you need to run it again and the balance is not saved.
Here is my code:
import random
def Guess_Check(guess,balance): #function for guess check
coin_flip = int( random.choice([1,2]))
if coin_flip == 1:
print("It's heads!!")
else:
print("It's tail!")
if guess == coin_flip: #if guess is correct
print("Congrats you guessed right, You won $9.")
balance = balance+9
else: #if guess is wrong
print("Sorry your guess was wrong, You loss $10.")
balance = balance-10
print("Avalilable balanace is :", balance)
return (balance)
def Balance_Check(Balance): #Balance Check
if Balance <= 10: #we can't play the game if balance is below $10
print("Sorry!! You run out of money.")
return(1)
if Balance >=200:
print("Congrats!! You reached your Target $200.")
return(1)
balance = 100 #beginning amount
while True:
bal = Balance_Check(balance) #check the available balance
if bal==1:
break
print("Guess heads by entering 1 or tails by entering 2 for this coin flip.") #Asking the player to guess
guess = int(input())
Balance = Guess_Check(guess,balance)
You messed up a few of the things like which balance to take at the right time when to stop the loop etc.
Here's the code if you want to take the user input once and then check the guess:
import random
def Guess_Check(guess,balance): #function for guess check
coin_flip = random.choice([1,2])
if coin_flip == 1:
print("It's heads!!")
else:
print("It's tail!")
if guess == coin_flip: #if guess is correct
print("Congrats you guessed right, You won $9.")
balance = balance+9
else: #if guess is wrong
print("Sorry your guess was wrong, You loss $10.")
balance = balance-10
print("Avalilable balanace is :", balance)
return (balance)
def Balance_Check(Balance): #Balance Check
if Balance <= 10: #we can't play the game if balance is below $10
print("Sorry!! You run out of money.")
return 0
elif Balance >=200:
print("Congrats!! You reached your Target $200.")
return 1
balance = 100 #beginning amount
print("Guess heads by entering 1 or tails by entering 2 for this coin flip.") #Asking the player to guess
guess = int(input())
while Balance_Check(balance) not in [0,1]: # You need to run the loop till balance becomes 0 or 200
balance = Guess_Check(guess,balance)
But if you want to take user input on every chance use:
import random
def Guess_Check(guess,balance): #function for guess check
coin_flip = random.choice([1,2])
if coin_flip == 1:
print("It's heads!!")
else:
print("It's tail!")
if guess == coin_flip: #if guess is correct
print("Congrats you guessed right, You won $9.")
balance = balance+9
else: #if guess is wrong
print("Sorry your guess was wrong, You loss $10.")
balance = balance-10
print("Avalilable balanace is :", balance)
return (balance)
def Balance_Check(Balance): #Balance Check
if Balance <= 10: #we can't play the game if balance is below $10
print("Sorry!! You run out of money.")
return 0
elif Balance >=200:
print("Congrats!! You reached your Target $200.")
return 1
balance = 100 #beginning amount
while Balance_Check(balance) not in [0,1]: # You need to run the loop till balance becomes 0 or 200
guess = int(input("Guess heads by entering 1 or tails by entering 2 for this coin flip."))
balance = Guess_Check(guess,balance)
Sample output: (Not complete output as it was long)
Congrats you guessed right, You won $9.
Avalilable balanace is : 206
Congrats!! You reached your Target $200.
So I ran into trouble with this code again with output. Basically, there are some key features I need it to print, but whenever I manage to get it to print one thing it completely messes up the rest of the printing. So for example, I need it to print Roll # 1 (1 - 3) was (whatever number) not Roll (whatever number) if that makes sense. But I also need it to only max out to 3 rolls. This is where my second issue comes in; whenever I try to code it to subtract the bet from the bank when a user doesn't match any rolls, it counts my subtraction as a fourth roll and screws up the math. So instead of Roll #1 through #3 its now up to Roll #4
My third problem is, I need to the program to continue looping until the user enters 0 (zero) to end the script or the bank amount reaches 0 (zero).
You should redesign your program. First of all, you are generating new results for each condition check at
if guess == rollDice():
bank = bet * 2
elif guess == rollDice():
bank += bet * .5
elif guess == rollDice():
bank = bank
Your code is not properly indented.
[...]
elif guess == rollDice():
bank += bet * .5
elif guess == rollDice():
bank = bank
else:
guess != rollDice()
bank = bank - bet
print(f'You have ${bank} in your bank.')
print(f'Thanks for playing!')
And so on...
Have a function that simulates a single dice roll, like:
def roll():
return random.randint(1, 6)
And handle the rest in your main function like:
prog_info()
while True: #main loop
rolls = list() #redefines after each loop
score = 2
for i in range(3): #3 dice roll
bank, bet = total_bank(bank)
guess = get_guess()
if not guess: #exit condition
break
rolls.append(roll())
if sum(rolls) == guess:
bank = bet * score
break #break on match
score = score - 0.5 #after each roll we have less money to win
print(f'You have ${bank} in your bank.')
print(f'Thanks for playing!')
A couple changes get the result you want
Pass the roll count to the rollDice function
Add an else to the bottom of the if block to check 0 bank
Here is the updated code:
import random
def rollDice(cnt):
die1 = random.randint(1,6)
die2 = random.randint(1,6)
x = int(die1 + die2)
print('Roll #', cnt, 'was', x)
return x
def prog_info():
print("My Dice Game .v02")
print("You have three rolls of the dice to match a number you select.")
print("Good Luck!!")
print("---------------------------------------------------------------")
print(f'You will win 2 times your wager if you guess on the 1st roll.')
print(f'You will win 1 1/2 times your wager if you guess on the 2nd roll.')
print(f'You can win your wager if you guess on the 3rd roll.')
print("---------------------------------------------------------------")
def total_bank(bank):
bet = 0
while bet <= 0 or bet > min([500,bank]):
print(f'You have ${bank} in your bank.')
get_bet = input('Enter your bet (or 0 to quit): ')
if get_bet == '0':
print('Thanks for playing!')
exit()
bet = int(get_bet)
return bank,bet
def get_guess():
guess = 0
while (guess < 2 or guess > 12):
try:
guess = int(input('Choose a number between 2 and 12: '))
except ValueError:
guess = 0
return guess
prog_info()
bank = 500
guess = get_guess
while True:
rcnt = 0
bank,bet = total_bank(bank)
guess = get_guess()
if guess == rollDice(rcnt+1):
bank += bet * 2
elif guess == rollDice(rcnt+2):
bank += bet * .5
elif guess == rollDice(rcnt+3):
bank = bank
else:
bank = bank - bet # no match
if bank == 0:
print('You have no money left. Thanks for playing!')
exit()
Output
You have $500 in your bank.
Enter your bet (or 0 to quit): 500
Choose a number between 2 and 12: 4
Roll # 1 was 11
Roll # 2 was 6
Roll # 3 was 7
You have no money left. Thanks for playing!
This question already has answers here:
How to test multiple variables for equality against a single value?
(31 answers)
Closed 4 years ago.
I've been driving myself insane trying to troubleshoot and fix this. I cerated this dice rolling game with bets. I'm pretty new to coding, so I'm sure it's a simple error that I just keep overlooking.
The only issue is that it will not end the game if the user inputs "no".
The function doesn't return any errors. It runs and even prints GAME OVER before it returns the values used to find out if the player wants to play another round.
What happens is that it prints the game over, and then loops the diceRoll function without stopping it.
Picture uploaded to show what I mean.
And the code:
#pylint:disable=W0312
#python 3.6
from random import randint
import math
# Static Variables
START_BALANCE = 2500
# Game messages
BAD_GUESS = "ERROR! You can only enter a number between 1 and 6.\n- Your input was '{}'.\n"
BAD_BET = "ERROR! You can not bet less than 0 or more than your current balance {}$.\n"
userName = input("What is your name, player?\n").title()
print("Hello, {}! Welcome to the dice rolling game v.2!\n".format(userName))
def get_guess():
try:
guess = input("Enter a guess from 1 to 6, {}\n".format(userName))
guess = int(guess)
while (guess <= 0 or guess > 6):
print(BAD_GUESS.format(guess))
return get_guess()
except ValueError:
print(BAD_GUESS.format(guess))
return get_guess()
else:
print("Your guess is: {}.".format(guess))
return guess
def get_bet(balance):
try:
bet = input("\nHow much do you want to bet? Your balance is: {}$\n".format(balance))
bet = int(bet)
while (balance < bet) or (bet < 0):
print(BAD_BET.format(balance))
return get_bet(balance)
except ValueError:
print(BAD_BET.format(balance))
return get_bet(balance)
else:
print("You have bet {}$!\n- Your remaining balance is: {}$".format(bet, balance - bet))
return bet
#### FUNC START ####
def diceRoll(balance):
bet = get_bet(balance)
guess = get_guess()
balance -= bet
roll = randint(1,6)
if (roll == guess):
prize = bet * float(3.75)
prize = math.ceil(prize)
balance += prize
print("\nYOU WIN {}$!".format(prize))
print("You guessed: {} - The roll was {}!\n".format(guess, roll))
print("-- Your balance is now {}$ -- \n".format(balance))
elif (roll != guess):
print("\nYOU LOSE {}$".format(bet))
print("The roll was: {} - You guessed: {}.".format(roll,guess))
print("-- Your balance is now {}$ --\n".format(balance))
#
choice = input("Would you like to try again? Y/N\n").upper()
#
if (balance <= 0 or choice == "YES" or "Y"):
print("New round! Your balance is {}$".format(balance))
return [True, balance]
else:
print("GAME OVER! \n Balance: {}$".format(balance))
return [False, balance]
# Initialize game_state, which is a variable that keeps track of your rounds and balance.
game_state = [True, START_BALANCE]
# game_state[0] contains True if the user wants to play again, False if not.
# So if it's false, while (game_state[0]) will evaluate to false and stop the while loop.
while game_state[0]:
game_state = diceRoll(game_state[1])
# TODO: Build a while loop that executes any time the first item in game_state is True (i.e., while the
# user still wants to play a new round. Note that I initialized game_state[0] to True, assuming that
# if they started the program, they want to play the first round.
Inside diceRoll() function this should be changed from:
if (balance <= 0 or choice == "YES" or "Y")
to
if (balance <= 0 or choice == "YES" or choice == "Y")
to properly compare with the choice value.
In your case to make it clearer you are having 3 condition:
balance <= 0
choice == "YES"
"Y"
with the third one being always True. It doesn't check if choice has Y value but if the string provided "Y" in your case is equal to None or not and obviously it's not so it's always True.
In addition to the answers given, I recommend a list of positive choice strings and check if choice is in it.
acceptables = ["yes", "y", "yup", "yeah", "sure", "absolutely", "1", "roger"]
if (balance <= 0 or choice.lower() in acceptables)
.lower() converts the input string into lower case, so you don't have to bother about that. If you want to allow more than the examples in the above case, you can always add them as you wish. Same for, "no", "nope", "no way", "never", "0", ...
The code:
import math
import time
import os
from random import *
def intro():
print("Welcome to battle. This is a game where you battle monsters.")
print("You will try to get the highest score you can.")
print("You start with 100HP. You will need to survive.")
print("You get a max revive every 10 battles.")
print("PS: This game is still in early alpha.")
print("Bugs are expected.")
game()
def game():
health = 100
revive = 0
print("You are greeted by a monster...")
print("1 = Fight")
print("2 = Take a chance at running")
choice = input("")
if choice == 1:
damage = randint(1,100)
health = health - damage
print("You killed the monster!")
print("But you took "+damage+" damage")
print("Your new health is: "+health)
if choice == 2:
print("You tried to run but failed.")
damage = randint(70,100)
health = health - damage
print("Your new health is: "+health)
else:
print("Wrong choice. You died.")
intro()
intro()
The problem: If you use 1 for choice it leads to else. Same with 2. Thanks to anyone that helps! PS: I am using Python 3. I don't know if that's important, I just need to fill out these lines.
Convert your input to int.
Ex:
choice = int(input())
and then replace
if choice == 2:
with
elif choice == 2:
Edit as per comments
def game():
health = 100
revive = 0
print("You are greeted by a monster...")
print("1 = Fight")
print("2 = Take a chance at running")
choice = int(input(""))
if choice == 1:
damage = randint(1,100)
health = health - damage
print("You killed the monster!")
print("But you took "+str(damage)+" damage") #-->Convert int to str before concatenation
print("Your new health is: "+str(health)) #-->Convert int to str before concatenation
elif choice == 2:
print("You tried to run but failed.")
damage = randint(70,100)
health = health - damage
print("Your new health is: "+str(health)) #-->Convert int to str before concatenation
else:
print("Wrong choice. You died.")
You firstly need to cast your input to an int by using int(input(""))
Then:
You need to use elif choice == 2: instead of if choice == 2:.