How to end this kind of loop(while) in python3 - python

I cannot figure it out how to end this loop :(
import random
class Enemy:
life = 300
print ('Player 1 your life is ' + str(life) + ' hp' )
def bonusdmg(self):
bondmg=random.randrange(40,51)
print('congratz u made ' + str(bondmg)+' bonus dmg')
self.life-=bondmg
def attack(self):
ad1=random.randrange(50,81)
print(str(ad1) + 'dmg')
print('ouch')
self.life -=ad1
def attack2(self):
ad2=random.randrange(60,90)
print(str(ad2) + 'dmg')
print('arghhh')
self.life -=ad2
def attack3(self):
ad3=random.randrange(100,111)
print(str(ad3) + 'dmg')
print('tsshaaah')
self.life -=ad3
def heal(self):
hp=random.randrange(40,51)
print ('No more potions')
self.life +=hp
print(str(hp) + ' hp have been restored')
def checkLife(self):
if self.life <=0:
print('Your enemy is dead')
else:
print(str(self.life) + "hp life left")
class Enemy2:
life = 300
print ('Player 2 your life is ' + str(life) + ' hp' )
def bonusdmg(self):
bondmg=random.randrange(40,51)
print('congratz u made ' + str(bondmg)+' bonus dmg')
self.life-=bondmg
def attack(self):
ad1=random.randrange(50,81)
print(str(ad1) + 'dmg')
print('ouch')
self.life -=ad1
def attack2(self):
ad2=random.randrange(60,90)
print(str(ad2) + 'dmg')
print('arghhh')
self.life -=ad2
def attack3(self):
ad3=random.randrange(100,111)
print(str(ad3) + 'dmg')
print('tsshaaah')
self.life -=ad3
def heal(self):
hp=random.randrange(40,51)
print ('No more potions')
self.life +=hp
print(str(hp) + ' hp have been restored')
def checkLife(self):
if self.life <=0:
print('Your enemy is dead')
else:
print(str(self.life) + "hp life left")
enemy2 = Enemy2()
enemy1 = Enemy()
while 1:
turn = 1
if turn ==1:
while 1:
print('Player 1 is your turn !')
bonus=str(random.randrange(1,6))
player_move=input('Player1 choose your attack !')
if player_move =='a':
enemy1.attack()
enemy1.checkLife()
turn +=1
break
if player_move =='s':
enemy1.attack2()
enemy1.checkLife()
turn +=1
break
if player_move == 'd':
enemy1.attack3()
enemy1.checkLife()
turn +=1
break
if enemy1.life <=0:
break
if bonus=='2':
enemy1.bonusdmg()
if turn ==2:
while 1:
print('Player 2 is your turn !')
bonus=str(random.randrange(1,6))
player_move=input('Player2 choose your attack !')
if player_move =='a':
enemy1.attack()
enemy1.checkLife()
turn -=1
break
if player_move =='s':
enemy1.attack2()
enemy1.checkLife()
turn -= 1
break
if player_move == 'd':
enemy1.attack3()
enemy1.checkLife()
turn -=1
break
if enemy1.life <=0:
break
if bonus=='2':
enemy1.bonusdmg()

You can try breaking the loop once a certain condition is satisfied. For example, try it like this:
# in while loop
if condition_is_true:
break
Otherwise, you'll need to specify a condition within the declaration of your while loop. I suggest this technique because it does not close your program. It can execute the code below your loop as well, if you have any.
while condition_is_true:

I cleaned up a lot of this, some notes at bottom.
import random
class Player:
def __init__(self, num):
self.num = num
self.life = 300
print('%s your life is %d hp' % (self, self.life))
self.enemy = None
def __str__(self):
return "Player %d" % self.num
def bonusdmg(self):
bondmg=random.randrange(40,51)
print('congratz u made %d bonus dmg' % bondmg)
self.deal_damage(bondmg)
def attack(self):
ad1=random.randrange(50,81)
print('You attack for %d dmg -- ouch' % ad1)
self.deal_damage(ad1)
def attack2(self):
ad2=random.randrange(60,90)
print('You attack for %d dmg -- arghhh' % ad2)
self.deal_damage(ad2)
def attack3(self):
ad3=random.randrange(100,111)
print('You attack for %d dmg -- tsshaaah' % ad3)
self.deal_damage(ad3)
def heal(self):
hp=random.randrange(40,51)
print ('No more potions')
self.life += hp
print('%d hp have been restored' % hp)
def checkEnemyLife(self):
if self.enemy.life <=0:
return "%s is dead" % self.enemy
else:
return "%s has %d hp left" % (self.enemy, self.enemy.life)
# New
def take_damage(self, amt):
print('%s takes %d dmg' % (self, amt))
self.life -= amt
# New
def deal_damage(self, amt):
self.enemy.take_damage(amt)
print(self.checkEnemyLife())
# New
def handle_action(self, player_move):
if player_move =='a': self.attack()
if player_move =='s': self.attack2()
if player_move == 'd': self.attack3()
bonus=str(random.randrange(1,6))
if bonus==2: # Fixed this
self.bonusdmg()
# New
def turn(self):
print("")
player_move = raw_input("%s it's your turn! Choose your attack! " % self)
self.handle_action(player_move)
# New
def won(self):
return (self.enemy.life <= 0)
player1 = Player(1)
player2 = Player(2)
player1.enemy = player2
player2.enemy = player1
# Enemy class
# life as attribute
# raw_input
# string formatting
turn = 1 # Moved this
run_game = True
while run_game:
if turn == 1:
player1.turn()
if player1.won():
print("Player 1 wins")
run_game = False
break
turn += 1
elif turn == 2:
player2.turn()
if player2.won():
print("Player 2 wins")
run_game = False
break
turn -= 1
Made both Enemy classes a single Player class, player1 and player2 are instances of the same class.
Gave each Player instance a reference to their enemy, so they don't deal damage to themselves anymore.
Created a bunch of methods that help stream line your main game loop
Improved printing using string formatting (%) operator.
Changed input to the safer raw_input
life is now an instance attribute instead of a class attribute
A of other, smaller changes

Although your code has many mistakes,I think the infinite loop you are referring is in the inner loop
turn = 1
if turn ==1:
while 1: #this cause a problem, how are you going to exit this loop?
#rest of the code
You never change turn = 2 therefore the if statement turn == 1 is always True. You need to find a place to make turn = 2 so the second player can move. This however will not solve all your issues.

Related

TypeErr: Object "int" is not callable

I tried to make a "typing game" and at first, it worked out pretty nice. But when I translated my code to English (variable names, class names, function names etc.) it gave me the warning "Object int is not callable". How can I solve this?
Here's my code:
import time
import random
import sys
class Player():
def __init__(self, name, health = 5, energy = 10):
self.name = name
self.health = health
self.energy = energy
self.hit = 0
def inf(self):
print("Health: ", self.health, "\nEnergy: ", self.energy, "\nName: ", self.name)
def attack(self, opponent):
print("Attacking")
time.sleep(.300)
for i in range(3):
print(".", end=" ", flush=True)
x = self.randomAttack()
if x == 0:
print("Nobody attacks.")
elif x == 1:
print("{} hits {} !".format(name, opponentName))
self.hit(opponent)
opponent.health -= 1
elif x == 2:
print("{} hits {}!".format(opponentName, name))
opponent.hit(self)
self.health -= 1
def randomAttack(self):
return random.randint(0, 2)
def hit(self, hit):
hit.hitVariable += 1
hit.energy -= 1
if (hit.hitVariable % 5) == 0:
hit.health -= 1
if hit.health < 1:
hit.energy = 0
print('{} won the game!'.format(self.name))
self.exit()
#classmethod
def exit(cls):
sys.exit()
def run(self):
print("Running...")
time.sleep(.300)
print("Opponent catch you!")
#######################################################
print("Welcome!\n----------")
name = input("What's your name?\n>>>")
opponentName = input("What's your opponent's name?\n>>>")
you = Player(name)
opponent = Player(opponentName)
print("Commands: \nAttack: a\nRun: r\nInformation: i\nExit: e")
while True:
x = input(">>>")
if x == "a":
you.attack(opponent)
elif x == "r":
you.run()
elif x == "i":
you.inf()
elif x == "e":
Player.exit()
break
else:
print("Command not found!")
continue
It gives me the error at line 24 (self.hit(opponent)).
Your hit function is the problem. You have member and a function with the same name. Change one of them.
Also rename the hit argument of the hit(). You call it via self.hit(opponent) so I would rename it to def hit(self, opponent):.
def __init__(self, name, health = 5, energy = 10):
self.hit = 0
def hit(self, hit):
hit.hitVariable += 1
hit.energy -= 1
if (hit.hitVariable % 5) == 0:
hit.health -= 1
if hit.health < 1:
hit.energy = 0
print('{} won the game!'.format(self.name))
self.exit()

Working on my first real game in Python, But I've Ran into a few problems

While coding my game, I've ran into problems when running it. For example, the zombie attack doesn't come out correctly, when using the store the gold value and health value do not update. When running the battle part, the first time the zombie has less health, then more health, and more damage. I don't know what I've messed up on. Any help/tips?
import time
import sys
import random
cls = ("\n"*100)
class Mage:
def __init__(self):
self.maxhp = 50
self.attack = 3.33
self.name = "Mage"
class Warrior:
def __init__(self):
self.maxhp = 70
self.attack = 2.5
self.name = "Warrior"
class Thief:
def __init__(self):
self.maxhp = 35
self.attack = 5
self.name = "Thief"
class Zombie:
def __init__(self):
self.maxhp = 10
self.attack = 1
self.name = "Zombie"
def heal(character_health):
if character_health < character_health:
character_health += 5
print("Healed. Health is now " + character_health + " +5.")
time.sleep(2)
else:
print("No healing available.")
time.sleep(2)
def battle(character_health, character_attack, monster_health, monster_attack, gold):
while True:
character_health_max = character_health
monster_name = "Zombie"
choice1 = input("\nPress 1 to Attack: ")
if choice1 == "1":
monster_health -= character_attack
print("\n" + str(monster_name) + "'s health is now " + str(monster_health))
time.sleep(1)
character_health -= monster_attack
print("\nThe hero's health is now " + str(character_health))
time.sleep(1)
if character_health <= 0:
print("\nThe hero is dead.")
sys.exit("\nThe End")
if monster_health <= 0:
print("\nThe monster is dead.")
time.sleep(2)
print("Your gold has increased by: 5")
gold += 5
monster_health = 10
character_health = character_health_max
time.sleep(2)
menu_list(character_health, character_attack, monster_health, monster_attack, gold)
def store(gold, character_health):
print("\nWelcome to my shop of wonders! My name is Hanz, what can I aid you with today? We have...\nPotions: [1.] EEK")
buy = input("\nWhat will it be? ")
if gold < 5:
print("Sorry, you don't have any gold!")
time.sleep(2)
if buy == "1" and gold >= 5:
print("\nYou now own the Potion EEK! Health increased by 5!")
character_health += 5
gold -= 5
time.sleep(2)
def menu_list(character_health, character_attack, monster_health, monster_attack, gold):
while True:
print(cls)
menu = input("---> Fight [1.] \n---> Heal [2.] \n---> Store [3.] \n---> Quit [4.] \n---> Gold: " + str(gold) + " \n---> ")
if menu == "4":
sys.exit()
if menu == "2":
heal(character_health)
if menu == "1":
battle(character_health, character_attack, monster_attack, monster_health, gold)
if menu == "3":
store(gold, character_attack)
if menu == "Gold":
print("\nNot valid hackerman.")
time.sleep(1)
class Main:
print(cls)
name = input("What is your name: ")
character = input("\nChoose your class: \n----------------- \nMage [1.] \nWarrior [2.] \nThief [3.] \n---> ")
if character == "1":
character_health = Mage().maxhp
print("\nHealth " + str(character_health))
character_attack = Mage().attack
print("\nAttack " + str(character_attack))
character_name = Mage().name
print("\nClass " + str(character_name))
time.sleep(3)
monster_health = Zombie().maxhp
monster_attack = Zombie().attack
gold = 0
menu_list(character_health, character_attack, monster_health, monster_attack, gold)
if character == "2":
character_health = Warrior().maxhp
print("\nHealth " + str(character_health))
character_attack = Warrior().attack
print("\nAttack " + str(character_attack))
character_name = Warrior().name
print("\nClass " + str(character_name))
time.sleep(3)
monster_health = Zombie().maxhp
monster_attack = Zombie().attack
gold = 0
menu_list(character_health, character_attack, monster_health, monster_attack, gold)
if character == "3":
character_health = Thief().maxhp
print("\nHealth " + str(character_health))
character_attack = Thief().attack
print("\nAttack " + str(character_attack))
character_name = Thief().name
print("\nClass " + str(character_name))
time.sleep(3)
monster_health = Zombie().maxhp
monster_attack = Zombie().attack
gold = 0
menu_list(character_health, character_attack, monster_health, monster_attack, gold)
if __name__ == '__main__':
Main()
I think this is a good time to go over what happens when you pass variables to functions in Python.
Firstly, everything in Python is an object! Primitives too (numbers are wrapped as an object in Python). Every class of objects inherit from the object class in Python.
Now, what happens when you pass a primitive to a function and change the value?
To illustrate:
def foo(a):
a = 5
b = 1
foo(b)
print(b) # b is still 1! Some objects in Python are immutable including integers, strings, and booleans.
Now I suspect your gold and health values aren't changing because you're passing in immutable objects which cannot be changed!
How to resolve?
You want to pass in a mutable object! Instead of passing an integer object (which is immutable) for a character's health, pass in the character object (which is mutable). You can set the new health of that character object.
To illustrate:
class Warrior:
def __init__(self):
self.maxhp = 70
self.attack = 2.5
self.name = "Warrior"
self.currenthp = 55 # arbitrary number but you may want to have something like this
def heal(warrior):
warrior.currenthp += 5
# somewhere in your Main function
warrior1 = Warrior()
heal(warrior1) # currenthp of this warrior should be 60!
It's important that you implement OOP correctly when you are creating your game. Similarly try debugging your other issues paying attention to how you implement OOP.

Passing Objects Between functions?

I am new to programming in python and, I started writing a simple text based adventure game. I came across a problem when passing an object from one function to another. Here is my code:
import random
import time
num = random.randint(0,2)
xp1 = random.randint(1,2)
class player:
def __init__ (self, name, health, strength, defense, potion, xp, level):
self.__health = health
self.__strength = strength
self.__defense = defense
self.__name = name
self.__potion = potion
self.__xp = xp
self.__level = level
def getName(self):
return self.__name
def getHealth(self):
return self.__health
def getStrength(self):
return self.__strength
def getDefense(self):
return self.__defense
def getPotion(self):
return self.__potion
def getXP(self):
return self.__xp
def getLevel(self):
return self.__level
def setHealth(self):
self.__health = 10
def setLevel(self):
self.__level = 1
def subHealth(self, num):
self.__health -= num
def subPotion(self):
self.__potion -= 1
return self.__health
def addPotion(self, num1):
self.__potion += num1
def addHealth(self):
self.__health +=2
def addStrength(self):
self.__strength += 1
def addDefense(self):
self.__defense += 1
def addXP(self):
self.__xp += xp1
def addLevel(self):
self.__level += 1
self.__addHealth += 1
self.__defense += 1
self.__strength += 1
def battle(enemy, player1, name1):
player1 = player(name1, player1.getHealth(), player1.getStrength(), player1.getDefense(), player1.getPotion(), player1.getXP(), player1.getLevel())
enemy = player('Dongus', enemy.getHealth(), enemy.getStrength(), enemy.getDefense(), enemy.getPotion(), enemy.getXP(), enemy.getLevel())
s = 0
while s == 0:
time.sleep(1)
attack =int(input("Type 1 to attack, type 2 to use a potion."))
if attack == 1:
time.sleep(1)
print("Dongus's health is", enemy.subHealth(num))
print("Dongus hit you and your health is now at", player1.subHealth(num-player1.getDefense()))
elif attack == 2:
time.sleep(1)
print("You used a potion.")
player1.addHealth(), player1.subPotion()
if player1.getHealth() > 10:
player1.setHealth()
print("Dongus hit you and your health is now at", player1.subHealth(num-player1.getDefense()))
if enemy.getHealth()<=0:
print("Congratulations, you won! You recieved", xp1, "xp!")
player.addXP()
s = 2
def main():
name1 = input("What would you like your name to be?")
time.sleep(1)
print("Hello,", name1, "you are on a quest to save otis from the evil Dongus. You must slay him, or Otis will poop.")
time.sleep(2)
player1 = player(name1, 10, 2, 1, 0, 0, 1)
enemy = player('Dongus', 8, 4, 0, 0, 0, 0)
print("Your stats are, health:", player1.getHealth(), "strength:", player1.getStrength(), "and defense:", player1.getDefense())
time.sleep(2)
print("Fight!")
pick = input("You found a health potion! Press 'p' to pick it up.")
p = 0
while p == 0:
if pick == "p":
print("You added a potion to your inventory.")
player1.addPotion(1)
p = 2
else:
print("You have no potions, you should probably pick this one up.")
player1.addPotion(1)
p = 2
battle(enemy, player1, name1)
if self.__getXP() == 1:
print("You leveled up. You are now level 2.")
player1.addLevel()
print("Your stats are, health:", player1.getHealth(), "strength:", player1.getStrength(), "and defense:", player.getDefense())
loot1 = int(input("Type ''1'' to loot the enemy chest."))
if loot1 == 1:
print("You recieved two potions!")
player1.__addPotion(2)
enemy.setHealth(10)
battle(enemy, player1, name1)
main()
Now the problem is when I run the game, I get to a point where I type "1" to attack the enemy, but it says, for some reason, that after attacking the enemy, the enemies health is at "None". This is the same case when the enemy attacks player1, it says player1's health is at "None". I assume that "None" is the default value in python 3.4.1, so my thinking is that the player1's object from def main() are not being transferred over to def battle() and I cannot see the reason why this is happening. I most likely am missing something here, or it is something I do not already know about Python that is causing the issue. Does anybody know what I can do to fix this, and why it is doing this?
BTW some of the terms I am using may be wrong, so please correct me if they are... I have only been coding for 2 weeks :p.
Thanks!!!
First, received not recieved
2nd yes, If you have a Python function that does not return a value, the result is None
# dummy will return "Positive" or None
def dummy(x):
if X > 0:
return "Positive"
So, you probably want to change
def subHealth(self, num):
self.__health -= num
to
def subHealth(self, num):
self.__health -= num
return self.__health
Your question re: the "player" classes from def main() are not being transferred over to def battle() does not really make sense to me.
But, I see that in the first 2 lines of battle, you are replacing the formal parameters player1 and enemy with local variables, this seems like odd usage in your program.

TypeError: list indices must be integers, not list

def take_turn(Nplayers, hands, player, pile, turn):
while finished(hands) is not True:
pile.append(hands[player][0]) # this line
hands[player].pop(0)
while pile[-1] <= 10:
print(turn, ':', '\nPile:', pile, '\nHands\n', '\n'.join(map(str, hands)), '\n')
check_players(Nplayers, hands, player, pile, turn)
turn += 1
player = (player + 1) % Nplayers
if len(hands[player]) == 0:
hands.pop(player)
Nplayers -= 1
player = player % Nplayers
pile.append(hands[player][0])
hands[player].pop(0)
if table[-1] > 10:
break
penalty_card(Nplayers, hands, player, pile, turn)
return turn
The line marked by the (# this line) returns the error as stated in the title, in my programme I have set player to initially equal 0, so there should be no problems right?
Edit: hands is a list of lists, player is an integer
It would be a lot easier to help if a working code sample were provided. It looks like there's a number of functions with side effects. Perhaps you could include some minimal mocks and a sample call like below to make a contained, runnable demonstration of the problem?
def finished(hands):
if len(hands) == 0:
return True
return False
def check_players(*args, **kwargs):
pass
def penalty_card(*args, **kwargs):
pass
table = [9]
def take_turn(Nplayers, hands, player, pile, turn):
while finished(hands) is not True:
pile.append(hands[player][0]) # this line
hands[player].pop(0)
while pile[-1] <= 10:
print(turn, ':', '\nPile:', pile, '\nHands\n', '\n'.join(map(str, hands)), '\n')
check_players(Nplayers, hands, player, pile, turn)
turn += 1
player = (player + 1) % Nplayers
if len(hands[player]) == 0:
hands.pop(player)
Nplayers -= 1
player = player % Nplayers
pile.append(hands[player][0])
hands[player].pop(0)
if table[-1] > 10:
break
penalty_card(Nplayers, hands, player, pile, turn)
return turn
take_turn(Nplayers=1, hands=[[1,1,1], [1,1], [1]], player=0, pile=[5, 5], turn=3)

Trouble with method inside of class in python

We are having trouble getting the gettot() method to work in side of our game class. When it is called inside of our game as a whole it comes back with an error saying that we dont have the correct amount of inputs for the function to operate correctly. Currently the first iteration of the functions is commented out so we could get further in the project without it stopping our game every time that it runs.
this is the gettot method we are having issues with:
The purpose of this method is to get the total of the cards that a player or dealer has in their hand, if there is an ace, it decides whether or not it should be a 1 or an 11 depending on which gets it closer to 21 total points without going over.
def gettot(self,hand):
total=0
for x in self.hand:
if x==Card('H','A'):
b=total+x
if b>21:
total+=1
else:
total+=11
if x==Card('D','A'):
b=total+x
if b>21:
total+=1
else:
total+=11
if x==Card('S','A'):
b=total+x
if b>21:
total+=1
else:
total+=11
if x==Card('C','A'):
b=total+x #changed
if b>21:
total+=1
else:
total+=11
else:
total+=x
return(total)
from random import*
#do we need to address anywhere that all face cards are worth 10?
class Card(object):
def __init__(self,suit,number):
self.number=number
self.suit=suit
def __str__(self):
return '%s %s'%(self.number,self.suit)
class DeckofCards(object):
def __init__(self,deck):
self.deck=deck
self.shuffledeck=self.shuffle()
def shuffle(self):
b=[]
count=0
while count<len(self.deck):
a=randrange(0,len(self.deck))
if a not in b:
b.append(self.deck[a])
count+=1
return(b)
def deal(self):
if len(self.shuffledeck)>0:
return(self.shuffledeck.pop(0))
else:
shuffle(self.deck) #need to refill deck
return(self.shuffledeck.pop(0))
class Player(object):
def __init__(self,name,hand,inout,money,score,bid):
self.name=name
self.hand=hand
self.inout=inout
self.money=money
self.score=score
self.bid=bid
def __str__(self):
x = self.name + ":\t"
x += "Card(s):"
for y in range(len(self.hand)):
x +=self.hand[y].face + self.hand[y].suit + " "
if (self.name != "dealer"):
x += "\t Money: $" + str(self.money)
return(x)
class Game(object):
def __init__(self,deck, player):
self.player=Player(player,[],True,100,0,0)
self.dealer=Player("Dealer",[],True,100,0,0)
self.deck=DeckofCards(deck)
self.blackjack= False
def blackjacksearch(self):
if Game.gettot(self.player.hand)==21:#changed
return True
else:
return False
def firstround(self):
#self.player.inout=True#do we need this since this is above
#self.player.hand=[]#do wee need this....
#self.dealer.hand=[]#do we need this ....
self.player.hand.append(DeckofCards.deal(self.deck))
for card in self.player.hand:
a=card
print(self.player.name + ' ,you were dealt a '+str(a))
self.dealer.hand.append(DeckofCards.deal(self.deck))
for card in self.dealer.hand:
a=card
print('The Dealer has '+str(a))
playerbid=int(input(self.player.name + ' how much would you like to bet? '))
self.player.money-=playerbid
self.player.bid=playerbid
def playturn(self): #should this be changed to inout instead of hit.....we never use inout
#for player in self.player:
# a=player
#print(str(a))
hit=input('Would you like to hit? ') #should input be in loop?
while self.player.inout==True: #and self.blackjack!=True:#changed
#print(self.player.name + ' , your hand has:' + str(self.player.hand)) #do we want to make this gettot? so it prints out the players total instead of a list....if we want it in a list we should print it with out brakets
self.player.hand.append(DeckofCards.deal(self.deck))
for card in self.player.hand:
a=card
print('The card that you just drew is: ' + str(a))
print(self.player.name + ' , your hand has:' + str([str(card) for card in self.player.hand]))
#print(Game.gettot(self.player.hand))
hit=input('Would you like to hit? ')
if hit=='yes':
(self.player.hand.append(DeckofCards.deal(self.deck)))#changed
self.player.inout==True#
else:
(self.player.hand) #changed
self.player.inout==False #changed
if self.player.blackjack==True:
print(self.player.name + " has blackjack ")
if hit=='no':
print (self.player.hand.gettot())
def playdealer(self):
while Game.gettot(self.dealer.hand)<17:#changed
self.dealer.hand.append(DeckofCards.deal(self.deck))
dealerhand=Game.gettot(self.dealer.hand) #changed
print(dealerhand)
if Game.gettot(self.dealer.hand)==21:#changed
self.dealer.blackhjack=True
dealerhand1=Game.gettot(self.dealer.hand)#changed
print(dealerhand1)
def gettot(self,hand):
total=0
for x in self.hand:
if x==Card('H','A'):
b=total+x
if b>21:
total+=1
else:
total+=11
if x==Card('D','A'):
b=total+x
if b>21:
total+=1
else:
total+=11
if x==Card('S','A'):
b=total+x
if b>21:
total+=1
else:
total+=11
if x==Card('C','A'):
b=total+x #changed
if b>21:
total+=1
else:
total+=11
else:
total+=x
return(total)
def playgame(self):
play = "yes"
while (play.lower() == "yes"):
self.firstround()
self.playturn()
if self.player.blackjack == True:
print(self.player.name + " got BLACKJACK! ")
self.player.money += self.player.bid * 1.5
print (self.player.name + " now has " + str(self.player.money))
print("\n")
self.player.inout = False
if self.player.score > 21:
print(self.player.name + " lost with a tot of " + str(self.player.score))
self.player.money -= self.player.bid
print (self.player.name + " now has " + str(self.player.money))
print ("\n\n")
self.player.inout = False
self.playdealer()
if self.dealer.blackjack == True:
print("Dealer got blackjack, dealer wins\n")
self.player.money -= self.player.bid
print("Round\n")
print("\t",self.dealer)
print("\t",self.player)
print("\t Dealer has " + str(self.dealer.score) + ", " + self.player.name + " has " + str(self.player.score))
elif self.player.inout == True:
print("Round\n")
print("\t",self.dealer)
print("\t",self.player)
print("\n\t Dealer has " + str(self.dealer.score) + ", " + self.player.name + " has " + str(self.player.score))
if self.dealer.score > 21:
print("\t Dealer lost with a total of " + str(self.dealer.score))
self.player.money += self.player.bid
print(self.player.name + " now has " + str(self.player.money))
elif self.player.score > self.dealer.score:
print("\t" +self.player.name + " won with a total of " + str(self.player.score))
self.player.money += self.player.bid
print("\t"+self.player.name + " now has " + str(self.player.money))
else:
print("\t Dealer won with a total of " + str(self.dealer.score))
self.player.money -= self.player.bid
print("\t"+self.player.name + " now has " + str(self.player.money))
else:
print("Round")
print("\t",self.dealer)
print("\t",self.player)
if self.player.blackjack == False:
print("\t "+ self.player.name + " lost" )
else:
print("\t "+self.player.name + " Won!")
if self.player.money <= 0:
print(self.player.name + " out of money - out of game ")
play = "no"
else:
play = input("\nAnother round? ")
print("\n\n")
print("\nGame over. ")
print(self.player.name + " ended with " + str(self.player.money) + " dollars.\n")
print("Thanks for playing. Come back soon!")
ls= [Card('H','A'),Card('H','2'),Card('H','3'),Card('H','4'),Card('H','5'),Card('H','6'),Card('H','7'),Card('H','8'),Card('H','9'),Card('H','10'),
Card('H','J'),Card('H','Q'),Card('H','K'),
Card('S','A'),Card('S','2'),Card('S','3'),Card('S','4'),Card('S','5'),
Card('S','6'),Card('S','7'),Card('S','8'),Card('S','9'),Card('S','10'),
Card('S','J'),Card('S','Q'),Card('S','K'),
Card('C','A'),Card('C','2'),Card('C','3'),Card('C','4'),Card('C','5'),
Card('C','6'),Card('C','7'),Card('C','8'),Card('C','9'),Card('C','10'),
Card('C','J'),Card('C','Q'),Card('C','K'),
Card('D','A'),Card('D','2'),Card('D','3'),Card('D','4'),Card('D','5'),
Card('D','6'),Card('D','7'),Card('D','8'),Card('D','9'),Card('D','10'),
Card('D','J'),Card('D','Q'),Card('D','K')]
def main():
x = input("Player's name? ")
blackjack = Game(ls,x)
blackjack.playgame()
main()
TL;DR but one thing I noticed is this: x==Card('H','A').
This won’t work unless you define your Card type to handle equality comparisons in a useful way. By default it will check if they are both the same objects, and as you create a new card, it won’t be the same object as x.
class Card(object):
# ...
def __eq__ (self, other):
return self.number == other.number and self.suit == other.suit
Also, this: b=total+x. If x is a Card object, how do you imagine it being added to a number? You have to define this, or do b = total + x.number instead.
Another thing is that you define gettot to take a hand parameter, but in the function, you iterate over self.hand. So any other hand you pass to the function is quietly ignored and self.hand is used instead.
Also this:
def blackjacksearch(self):
if Game.gettot(self.player.hand)==21:
# ...
This method belongs to the Game type; and it’s an instance method (taking a self parameter). But you actually call it as a static method from the Game type not an instance. It should be something like self.gettot() instead (you can leave out the parameter as per above).
You do the same at some other places too, trying to call instance methods by using TypeName.method. You need to have objects you call them on.
I think you can make your gettot method a lot shorter too:
def gettot(self,hand):
total=0
for x in self.hand:
if x.number == 'A':
if total + 11 > 21:
total += 1
else:
total += 11
elif x.number == 'J' or x.number == 'Q' or x.number == 'K':
pass # what to do with these?
else:
total += x.number
return(total)
Rewriting some parts of your code:
class Card (object):
def __init__ (self, suit, number):
self.suit = suit
self.number = number
def getValue (self):
if self.number in ('J', 'Q', 'K'):
return 10
elif self.number == 'A':
return 11
else
return int(self.number)
def isAce (self):
return self.number == 'A'
def __eq__ (self, other):
return self.suit == other.suit and self.number == other.number
def __str__ (self):
return '%s %s' % (self.number,self.suit)
class DeckOfCards (object):
def __init__ (self, deck):
self.fullDeck = deck
self.shuffle()
def shuffle (self):
self.deck = self.fullDeck[:] # copy the full deck
random.shuffle(self.deck)
def deal (self):
if not len(self.deck): # need to refill deck
self.shuffle()
return self.deck.pop(0)
ls = []
for suit in ('H', 'S', 'C', 'D'):
for number in ('A', '2', '3', '4', '5', '6', '7', '8', '9', '10', 'J', 'Q', 'K'):
ls.append(Card(suit, number))
Your gettot method should belong to a player, and would look like this:
def gettot(self):
total = 0
for card in self.hand:
if card.isAce() and total > 10:
total += 1
else:
total += card.getValue()
return total
You define gettot() to take two arguments: self, and hand. Then you never use hand, and when you call the function you only pass one argument (self.dealer.hand).
Eliminate the self argument (which makes no sense anyway, since it's a function defined outside of a class), and replace the for x in self.hand line with for x in hand. Even better, make the function a method of the Player object.
There are numerous problems
I would add a function to Card that asks if it is an Ace. That will work better then constructing a bunch and seeing if they are equal.
You are using == instead of = for some of your assignments. == is for comparison. = is for assignment.
don't say inout == True just say inout (since inout is a bool already)
you keep poping off the deck. When you run out you shuffle it again, but at this point it has nothing in it.
at the top of gettot you are referencing self.hand, but self doesnt have a hand it should just be hand as it is passed into gettot.
player.blackjack is never defined but I would add a check there for if gettot == 21, and move gettot to a modual function for now
self.player.hand.gettot() should be gettot(self.player.hand)
you are total+=x where total is an int and x is a Card, you cant add those unless you define how to add an int to a Card. I would just add to Card a get_value function for now to get the face value. (you could handle face cards being value of 10 here too) then use total += x.get_value()
you also want to adjust for aces at the end of gettot, otherwise you don't know if you are going to be over 21. ie. what happends if the first card in your hand is an ace?
example:
class Card(object):
def __init__(self,suit,number):
self.number=number
self.suit=suit
def __str__(self):
return '%s %s'%(self.number,self.suit)
def get_value(self):
if self.number == 'A':
return 11
if self.number in 'JQK':
return 10
return int(self.number)
def is_ace(self):
return self.number == 'A'
def gettot(hand):
total = 0
aces = 0
for x in hand:
if x.is_ace():
aces += 1
total += x.get_value()
while aces and total > 21:
aces -= 1
total -= 10
return total
That should get you started, just keep debugging

Categories

Resources