I would like to add Debt to my blackjack game - python

this is a simple blackjack game. I want to add debt and user will have bank account as;
bank=1000
Program will ask to user: "How much do you debt? $" and his money in the bank will increase or decrease then if user has 0 dollar in the bank game will over. The issue is whenever I input "y" for cont, the bank becomes 1000 again.I declared debt in the main function and the condition was below the "while cmp_sc!=0 and cmp_sc<17" when I tried to do that.
import os
import random
cards=[11,2,3,4,5,6,7,8,9,10,10,10,10]
def rand_card(card):
r_card=random.choice(card)
return r_card
def result_card(card):
sum_card=sum(card)
if sum_card == 21 and len(card)==2:
return 0
if 11 in card and sum(card)==21:
card.remove(11)
card.append(1)
return sum(card)
def comparing(result1,result2):
if result1>result2 and result1<=21:
return "You win"
elif result1==result2:
return "Draw"
elif result2>result1 and result2<=21:
return "You lose"
elif result1>21 and result2>21:
return "You are flying, you lose"
elif result1==0:
return "Blackjaack, You win!"
elif result2==0:
return "Computer Blackjaack, You lose!"
elif result1 > 21:
return "You went over. You lose"
elif result2 > 21:
return "Opponent went over. You win"
def main():
user=[]
computer=[]
flag=False
for i in range(2):
user.append(rand_card(cards))
computer.append(rand_card(cards))
while not flag:
usr_sc = result_card(user)
cmp_sc = result_card(computer)
print(f" Your cards: {user}, current score: {usr_sc}")
print(f" Computer's first card: {computer[0]}")
if usr_sc==0 or cmp_sc==0 or usr_sc>21:
flag=True
else:
cont = input("Type 'y' to get another card, type 'n' to pass: ").lower()
if cont=='y':
user.append(rand_card(cards))
else:
flag=True
while cmp_sc!=0 and cmp_sc<17:
computer.append(rand_card(cards))
cmp_sc=result_card(computer)
print(f" Your final hand: {user}, final score: {usr_sc}")
print(f" Computer's final hand: {computer}, final score: {cmp_sc}")
print(comparing(usr_sc, cmp_sc))
while input("Do you want to play a game of Blackjack? Type 'y' or 'n': ") == "y":
clearConsole = lambda: os.system('cls' if os.name in ('nt', 'dos') else 'clear')
clearConsole()
main()

The typical use of main() would be as a way to start your program, not as something that would be called each round. So, let's change that up a bit and call your current main() something like play_game(). Then we can reimplement main() more like:
def main():
balance = 1000
while input(f"You have {balance}. Do you want to play a game of Blackjack? Type 'y' or 'n': ") == "y":
clearConsole()
bet = 100
balance -= bet
balance += play_game(bet)
print(f"Final Balance: {balance}")
if __name__ == "__main__":
main()
So now we have a balance and each round we have a bet and what we bet will initially decrease our balance but with luck it will increase as a result of play_game()
The changes we will make to play_game(bet) will be to accept a "bet amount" and then return winnings based on how our hand compares to the computers hand. This will require a small change to comparing() to return not only a message but an indication of a win/draw/loss so we can figure out what to give back.
At the end of play_game(bet) rather than:
print(comparing(usr_sc, cmp_sc))
We will:
win_multiplier, message = comparing(usr_sc, cmp_sc)
print(message)
return win_multiplier * bet
Finally, the return values of comparing() need to include the absolute indication of a win/draw/loss that we will use as a multiplier against bet.
def comparing(result1,result2):
if result1>result2 and result1<=21:
return (2, "You win")
elif result1==result2:
return (1, "Draw")
elif result2>result1 and result2<=21:
return (0, "You lose")
elif result1>21 and result2>21:
return (0, "You are flying, you lose")
elif result1==0:
return (2, "Blackjaack, You win!")
elif result2==0:
return (0, "Computer Blackjaack, You lose!")
elif result1 > 21:
return (0, "You went over. You lose")
elif result2 > 21:
return (2, "Opponent went over. You win")

If you really want to have it persisted, you need to store it somewhere outside the process memory e.g in some file on disk. The easiest way could be with something like that:
try:
with open("bank.txt", "r") as f:
# assing bank to content of your file
bank = int(f.read())
except FileNotFoundError:
# if file not exist, it's first game of user, we set bank to 1000 then
bank = 1000
print(bank)
bet = int(input("What is your bet?"))
# at the end of program
bank = bank + bet if user_won else bank - bet
with open("bank.txt", "w+") as f:
f.write(str(bank))
Now the actual bank of player will be stored in bank.txt file. You can set its content manually before run to modify user bank

Related

Text-based game stats

I'm working on a mini-project I'm doing for fun to practice python skills and I am stuck on a problem I can't seem to figure out. I have a function that gives me the default stats for every class in the game and I want it to change depending on what class/weapon I choose in the beginning. I am still trying to learn functions so any input will be valuable. So gameStat() is the default stats while gameStat() is the changed one.
import time
import random
inventory = []
def intro():
print("Hello for playing my game. It is a text based game that I am working on. \n")
print("I hope you enjoy playing it \n")
def chooseClass():
print("Please choose a class you would like to play as. Each class has a different background story to them")
print("-----------------------------------------------------------")
print("Please use the number given below to select them")
print("1: Priest\n" "2: Warrior\n" "3: Thief\n" "4: Ninja\n" "5: Pirate\n")
def classChosen(starterClass):
if starterClass == 1:
print("You have chosen Priest")
return "Priest"
elif starterClass == 2:
print("You have chosen Warrior")
return "Warrior"
elif starterClass ==3:
print("You have chosen Thief")
return "Thief"
elif starterClass ==4:
print("You have chosen Ninja")
return "Ninja"
elif starterClass ==5:
print("You have chosen Pirate")
return "Pirate"
else:
return None
def gameStat():
health = 100
mana = 100
strength = 5
magic = 5
exp = 0
baseStats(health,mana,strength,magic,exp)
def ChosenPriest(var):
if var == "Priest":
selectAns=""
selectAns=input("Would you like to know the backstory? \n:Please type 1 :Yes or 2 :No\n:")
if selectAns == 1:
print("INC")
#print("Since a child, you have been serving under the Church of Agathor.\n")
#print("You didn't have much of a choice because you had nowhere else to go.\n")
#print("You don't know who your parents are and the only thing the church would tell you that you suddenly appeared in front of the chruch with a gold cross.\n")
#print("You still have that cross til this day.\n")
#print("At the age of 16, everyone who serves for the lord will get their own holy weapon.\n")
#print("The weapon is used to fight off The Shadows. The Shadows are creatures created by the Shadow Lord, Gilmah.\n")
#print("Since the very beginning, Gilmah would rummaged through the land destorying and pillaging everything he sees.\n")
#print("One priest was able to seal him for thousands of years but he is soon to be awaken and he'll become stronger than ever.\n")
else:
print("Alright!")
def Weapons(weapon):
if weapon == 1:
print("You have chosen Magical Book!")
inventory.append("Magical Book")
return "Magical Book"
elif weapon == 2:
print("You have choosen a staff")
inventory.append("Staff")
return "Staff"
def baseStats(character,weapon):
if character == "Priest":
if weapon == "Magical Book":
mana=100
mana = mana + 50
return mana
elif weapon == "Staff":
magic=5
magic = magic + 5
return magic
#intro()
chooseClass()
userClass=None
while True:
try:
x=input("What class would you like to play?\n:")
if x>5 or x<1:
continue
else:
userClass=classChosen(x)
break
except NameError:
continue
character=ChosenPriest(userClass)
weapon=Weapons(input("What kind of holy weapon would you like to take? \n 1: Magical Book \n 2: Staff \n Use 1 or 2 to select your weapon! :"))
print(baseStats(character,weapon))
Thank you so much.
When you take any input it will be in string format to compare it with an integer you need to convert it to integer using int() function
I modified the code and it returns the value of "mana" or "magic" correctly
import time
import random
inventory = []
def intro():
print("Hello for playing my game. It is a text based game that I am working on. \n")
print("I hope you enjoy playing it \n")
def chooseClass():
print("Please choose a class you would like to play as. Each class has a different background story to them")
print("-----------------------------------------------------------")
print("Please use the number given below to select them")
print("1: Priest\n" "2: Warrior\n" "3: Thief\n" "4: Ninja\n" "5: Pirate\n")
def classChosen(starterClass):
if starterClass == 1:
print("You have chosen Priest")
return "Priest"
elif starterClass == 2:
print("You have chosen Warrior")
return "Warrior"
elif starterClass ==3:
print("You have chosen Thief")
return "Thief"
elif starterClass ==4:
print("You have chosen Ninja")
return "Ninja"
elif starterClass ==5:
print("You have chosen Pirate")
return "Pirate"
else:
return None
def gameStat():
health = 100
mana = 100
strength = 5
magic = 5
exp = 0
baseStats(health,mana,strength,magic,exp)
def ChosenPriest(var):
if var == "Priest":
selectAns=""
selectAns=int(input("Would you like to know the backstory? \n:Please type 1 :Yes or 2 :No\n:"))
if selectAns == 1:
print("INC")
#print("Since a child, you have been serving under the Church of Agathor.\n")
#print("You didn't have much of a choice because you had nowhere else to go.\n")
#print("You don't know who your parents are and the only thing the church would tell you that you suddenly appeared in front of the chruch with a gold cross.\n")
#print("You still have that cross til this day.\n")
#print("At the age of 16, everyone who serves for the lord will get their own holy weapon.\n")
#print("The weapon is used to fight off The Shadows. The Shadows are creatures created by the Shadow Lord, Gilmah.\n")
#print("Since the very beginning, Gilmah would rummaged through the land destorying and pillaging everything he sees.\n")
#print("One priest was able to seal him for thousands of years but he is soon to be awaken and he'll become stronger than ever.\n")
else:
print("Alright!")
def Weapons(weapon):
if weapon == 1:
print("You have chosen Magical Book!")
inventory.append("Magical Book")
return "Magical Book"
elif weapon == 2:
print("You have choosen a staff")
inventory.append("Staff")
return "Staff"
def baseStats(character,weapon):
if character == "Priest":
if weapon == "Magical Book":
mana=100
mana = mana + 50
return mana
elif weapon == "Staff":
magic=5
magic = magic + 5
return magic
#intro()
chooseClass()
userClass=None
while True:
try:
x=int(input("What class would you like to play?\n:"))
if x>5 or x<1:
continue
else:
userClass=classChosen(x)
break
except NameError:
continue
character=ChosenPriest(userClass)
weapon=Weapons(int(input("What kind of holy weapon would you like to take? \n 1: Magical Book \n 2: Staff \n Use 1 or 2 to select your weapon! :")))
print(baseStats(userClass,weapon))
In the gameState() function the baseStats takes 5 argument but when you defined baseStats it only takes two arguments character and weapon which is confusing.

Running try and except in a function and re-running results in a NoneType return. How do I fix this?

I'm working on a simple program that allows the user to bet some virtual currency on a coin toss. Everything works fine, except for when the user inputs something incorrectly. For example: if a question asks for y/n response and the user puts 'd' or something as the response, the program will use the except ValueError and rerun the function. However, when the function is rerun and the user finally inputs something correctly, it will result in a further error.
Error:
> AttributeError: 'NoneType' object has no attribute 'lower'
Code:
import time
import random
money = 5000
last_interest_time = time.time()
def interest():
global money, last_interest_time
if time.time() - last_interest_time > 5:
prev_money = money
money *= 0.1
last_interest_time = time.time()
print("You now have " + str(money) + " monies (+" + str(money - prev_money) + ") from interest")
def game():
global money, last_interest_time
print("You have " + str(money) + " monies.")
choice = get_choice("Want to bet on a coin toss?", 'y','n')
if choice.lower() == 'y':
print("That's great!")
choice = get_choice("What side do you want to bet on?", 'h', 't')
bet_amount = get_bet()
print('Flipping the coin...')
time.sleep(1)
side = random.choice(['h', 't'])
if side == 'h':
print("The coin landed heads!")
elif side == 't':
print('The coin landed tails!')
if side == choice:
print("You won and received " + str(bet_amount) + " monies!")
money += bet_amount
else:
print("You lost the bet and " + str(bet_amount) + " monies!")
money -= bet_amount
game()
elif choice.lower() == 'n':
input('Oh well. Just type something if you want to bet again. ')
game()
def get_choice(question, response_1, response_2):
choice = input(question+" ("+response_1+'/'+response_2+'): ')
if choice != response_1 and choice != response_2:
print('Input is invalid. Must be '+response_1+'/'+response_2)
get_choice(question, response_1, response_2)
else:
return choice
def get_bet():
bet_amount = input("What amount do you want to bet?: ")
try:
if int(bet_amount) > money:
print("You don't have enough money!")
get_bet()
else:
return int(bet_amount)
except ValueError:
print('Invalid input. Must be a number')
get_bet()
game()
Debugging tip:
Print choice every time so you can see why it's crashing! You can take the print statement out later.
What I found was this:
get_choice() returned None.
In get_choice, if the input is invalid, it doesn't actually return anything. Oh no! So you're returning None, and calling .lower() on None throws the exception.
Solution:
You are on the right track when you run get_choice a second time if the input is invalid. One small tweak: instead of just running get_choice, return get_choice.
There is a similar bug in get_bet(), just a heads up, and you can solve it the same way.
Overall, great game.
.lower() runs on strings only and defining a variable with input() makes it not register as a string. Instead try something like this.
def set_choice():
choice = input("Want to bet on a coin toss?", 'y','n')
def choice():
choice = set_choice()
return choice
choice = choice.lower()

Unable to verify user input in game

I am creating a rock, paper, scissors game. I want it to be best of 3 matches and to be able to verify user input. I keep running into issues with the user input. I have tried multiple variations but I can't seem to figure it out. I know my code is probably messy, so any input on how to clean it up would be greatly appreciated. Thank you so much for your time.
import random
import sys
import time
print("Hello and welcome to the Rock, Paper, Scissors tournament.\n"
"The tournament will be the best of 3 wins.\n"
"It will be you against our highly intelligent computer opponent.\n"
"Good luck!")
# Create a function for the game
def play_game():
user_count = 0
comp_count = 0
tie_game = 0
while comp_count < 2 and user_count < 2:
user_choice = (int(input("-------------------------------------------"
"\nEnter choice by typing 1 2 or 3: \n 1. Rock \n 2. paper \n 3. scissor \n"
"-------------------------------------------\n")))
if user_choice == 1:
user_choice_name = 'Rock'
elif user_choice == 2:
user_choice_name = 'Paper'
elif user_choice == 3:
user_choice_name = 'Scissor'
else:
print("Please pick a valid number")
print(f"\nYou have chosen: {user_choice_name}")
print("\nNow it's the computer's turn to pick......")
time.sleep(3)
comp_choice = random.randint(1, 3)
if comp_choice == 1:
comp_choice_name = 'Rock'
elif comp_choice == 2:
comp_choice_name = 'Paper'
else:
comp_choice_name = 'Scissor'
print(f"\nComputer has chosen: {comp_choice_name}\n")
if user_choice == 1 and comp_choice == 2:
comp_count += 1
print("Computer wins this round with Paper! "
f"\n Computer: {comp_count}"
f"\n You: {user_count} \n\n")
elif user_choice == 1 and comp_choice == 3:
user_count += 1
print("You win this round with Rock!"
f"\n Computer: {comp_count}"
f"\n You: {user_count} \n\n")
elif user_choice == 2 and comp_choice == 1:
user_count += 1
print("You win this round with Paper!"
f"\n Computer: {comp_count}"
f"\n You: {user_count} \n\n")
elif user_choice == 2 and comp_choice == 3:
comp_count += 1
print("Computer wins this round with Scissor!"
f"\n Computer: {comp_count}"
f"\n You: {user_count} \n\n")
elif user_choice == 3 and comp_choice == 2:
user_count += 1
print("You win this round with Scissor!"
f"\n Computer: {comp_count}"
f"\n You: {user_count} \n\n")
elif user_choice == 3 and comp_choice == 1:
user_count += 1
print("Computer wins this round with Rock!"
f"\n Computer: {comp_count}"
f"\n You: {user_count} \n\n")
else:
if user_choice == comp_choice:
tie_game += 1
print(f"This round was a tie! Both choosing {user_choice_name}, try again!"
f"\n Computer: {comp_count}"
f"\n You: {user_count} \n\n")
else:
print(f'The game is now over with a score of: \n You:{user_count} \n to \n Computer:{comp_count}')
again = str(input("Do you want to play again, type 'yes' or 'no' \n"))
if again.lower() == "no":
print('Thank you for playing!')
sys.exit()
else:
play_game()
play_game()
Since I had a few minutes to kill with a cup of coffee, here's a rewrite of your program with a bunch of improvements, the validation you asked about and some tips on coding style:
import random
import time
print("Hello and welcome to the Rock, Paper, Scissors tournament.\n"
"The tournament will be the best of 3 wins.\n"
"It will be you against our highly intelligent computer opponent.\n"
"Good luck!")
# to avoid repeating these values over and over and changing numbers in to string,
# just defining them here. Name in capitals because it's global (generally bad)
# an even nicer solution would be to write a Game() class and put everything in
# there, but it would be a bit more advanced
RSP_OPTIONS = {
1: 'Rock',
2: 'Scissor',
3: 'Paper'
}
def get_user_choice():
# keep asking until a valid value is returned
while True:
# this is a bit fancy, but let's say you want to reuse the game for similar games
# with different options from rock, scissor, paper, you'd want this code to still work
# get a list of string versions of the numbers
numbers = list(map(str, RSP_OPTIONS.keys()))
# join them together like you presented them: 1, 2 or 3
options = ', '.join(numbers[:-1]) + ' or ' + numbers[-1] + ':\n'
# add the descriptions
options = options + ''.join(f'{n}: {name}\n' for n, name in RSP_OPTIONS.items())
try:
user_choice = (int(input("-------------------------------------------\n"
f"Enter choice by typing {options}"
"-------------------------------------------\n")))
except ValueError:
# any invalid option
user_choice = -1
# check if it's one of the valid options
if user_choice in RSP_OPTIONS:
return user_choice
else:
# it makes sense to generate a new line where you want it, instead of having
# to put new line characters at the start of other strings
print("Please pick a valid number\n")
def beats(choice1, choice2):
# choice1 beats choice2 if it's one greater, except when choice2 == 3 and choice1 == 1
# but to make it even nicer and have it work for other similar games, you could say
# "except when choice1 == the max choice and choice2 == the min choice"
return (choice2 - choice1 == 1 or
(choice1 == max(RSP_OPTIONS.keys()) and choice2 == min(RSP_OPTIONS.keys())))
# Create a function for the game
def play_game():
user_count = 0
comp_count = 0
tie_game = 0
# this is what you really want, best out of three, ties not counted?
while comp_count + user_count < 3:
user_choice = get_user_choice()
print(f"You have chosen: {RSP_OPTIONS[user_choice]}\n")
print("Now it's the computer's turn to pick......\n")
# this wait is not very nice, the user might try to hit enter or something
# you could consider printing the countdown, or telling the user to please wait
# even then, it's kind of silly to pretend the computer has to work hard here
time.sleep(3)
# this choice is always valid, so no problem
comp_choice = random.randint(1, 3)
# note that you don't need the name, you can just look it up whenever in RSP_OPTIONS
print(f"\nComputer has chosen: {RSP_OPTIONS[comp_choice]}\n")
# getting rid of some repetition, note how the code really reads like what is intended
if beats(comp_choice, user_choice):
comp_count += 1
# nice to also say what really beat them
print(f"Computer wins this round with {RSP_OPTIONS[comp_choice]} over {RSP_OPTIONS[user_choice]}!\n")
elif beats(user_choice, comp_choice):
user_count += 1
print(f"You win this round with {RSP_OPTIONS[user_choice]} over {RSP_OPTIONS[comp_choice]}!\n")
else:
# you can only get here on a tie
tie_game += 1
print(f"This round was a tie! Both choosing {RSP_OPTIONS[user_choice]}, try again!\n")
# you always print this, so just do it after the options:
print(f"Computer: {comp_count}\n"
f"You: {user_count}\n\n")
else:
print(f'The game is now over with a score of:\n You:{user_count}\n to\n Computer:{comp_count}\n')
again = str(input("Do you want to play again, type 'yes' or 'no' \n"))
# let's quit on anything starting with n
if again.lower()[0] == "n":
print('Thank you for playing!\n')
# instead of exiting hard, maybe just return, telling the caller we don't want to play again
return False
else:
# you were calling play_game again, but that causes the game to get more and more calls
# on top of each other, ultimately reaching an error state
# by returning first and then calling again, you avoid that problem
return True
# the function returns whether it should play again
while play_game():
pass
# once it leaves the loop, the game stops automatically here, no more code
There's still a lot of room for improvement though; try implementing some more advanced forms of RSP, or make the computer more intelligent than just playing random, but have it use some kind of strategy, perhaps with a bit of randomness mixed in.
And code-wise, try separating the game from the way it is presented on the screen; what if you decided to do this on the web instead of on a console, or in a graphics window? You could also consider putting all the code in a nice class, getting rid of global variables and allowing you to create more copies of the game as needed.

Everything is leading to an else instead of it reading the input

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:.

input being ignored, function looping at for statement

I was just introduced to python less than a week ago and I'm trying to make a simple game of blackjack. I've written out the core of the program and it seems that it's ignoring the raw input, and just continually looping through the for conditional. It doesn't matter if what I type, hit, stay, whatever. Here's the code:
def main_game():
number = random.randint(1,13)
card_type_number = random.randint(1,4)
total = 0
dealer = random.randint(1,21)
input = raw_input("Would you like to Hit or Stay? \n")
if input == "hit" or "Hit":
card_number = numberConverter(number)
card_type = typeConverter(card_type_number)
new_amount = number
print "You got a %s of %s. You currently have %s. \n" % (card_number, card_type, number)
total += number
number = random.randint(1,13)
card_type_number = random.randint(1,5)
main_game()
elif input == ("Stay" or "stay") and total == 21:
print "Holy Cow! A perfect hand!"
main_game()
elif input == ("Stay" or "stay") and total < dealer:
print "Sorry, the dealer had %s" % (dealer)
maingame()
elif input == ("Stay" or "stay") and total > 21:
print "Sorry, you have more than 21"
main_game()
else:
print "Could you say again?"
main_game()
I'm at a loss and would appreciate any help.
Thanks!
if input == "hit" or "Hit":
That means if (input == "hit") or ("Hit"), which is always true.
Try
if input == "hit" or input == "Hit":
Or
if input in ("hit", "Hit"):
Or, even better:
if input.lower() == "hit"
(same for all the other elifs)

Categories

Resources