looping error causing and endless scroll in blackjack game - python

I'm currently working on a blackjack game for my class and I think I've just about wrapped it up but for some reason I get stuck in an endless loop that keeps restarting the game. Can you help me find it?
import random as r
class Card:
def __init__(self, rank, suit, value):
self.rank = rank
self.suit = suit
self.value = value
def __str__(self):
return self.rank + ' of ' + self.suit
class Deck:
def __init__(self):
self.cards = []
self.shuffle()
def shuffle(self):
suits = ['Clubs', 'Diamonds', 'Hearts', 'Spades']
ranks = ['Ace', 'Two', 'Three', 'Four', 'Five', 'Six', 'Seven', 'Eight', 'Nine', 'Ten', 'Jack', 'Queen', 'King']
for suit in suits:
for rank in ranks:
value = ranks.index(rank) + 1
if value > 10: value = 10
if value == 1: value = 11
card = Card(rank, suit, value)
self.cards.append(card)
def deal(self):
if len(self.cards) < 1: self.shuffle()
index = r.randint(0, len(self.cards) - 1)
return self.cards.pop(index)
class Hand:
def __init__(self):
self.cards = []
def deal(self, card):
self.cards.append(card)
return self.value()
def value(self):
score = 0
aces = 0
for card in self.cards:
score += card.value
if card.value == 11: aces += 1
while score > 21 and aces > 1:
score -= 10
aces -= 1
return score
class Game:
def __init__(self):
self.deck = Deck()
self.player = Hand()
self.dealer = Hand()
self.wins = 0
self.losses = 0
self.exit = False
while not self.exit:
self.play()
def play(self):
self.deal()
if self.playerphase():
if self.dealerphase():
if self.player.value() > self.dealer.value():
self.outcome('player')
elif self.player.value() < self.dealer.value():
self.outcome('dealer')
else: self.outcome('pushback')
else: self.outcome('player', bust = True)
else: self.outcome('dealer', bust = True)
def deal(self):
self.player = Hand()
self.dealer = Hand()
for x in range(2):
self.player.deal(self.deck.deal())
self.dealer.deal(self.deck.deal())
def playerphase(self):
stand = False
options = ['hit', 'stand']
prompts = ["Enter 'hit or 'stand':"]
while not stand:
call = self.display(options, prompts)
if call == 'hit':
self.player.deal(self.deck.deal())
if self.player.value() > 21:
stand = True
else: stand = True
if self.player.value() > 21: return False
else: return True
def dealerphase(self):
while self.dealer.value() < 17:
self.dealer.deal(self.deal.deal())
if self.dealer.value() > 21: return False
else: return True
def display(self, options, prompts, show=False):
user = ''
while user not in options:
for x in range(30): print()
print('Wins: ' + str(self.wins))
print('Losses: ' + str(self.losses))
print('\nDealer: ')
if show: print(self.dealer.cards[0])
else: print('Face-Down Card')
for x in range (1, len(self.dealer.cards)):
print(self.dealer.cards[x])
print('\nPlayer:')
for card in self.player.cards:
print(card)
for prompt in prompts: print(prompt)
user = ''
return user
def outcome(winner, bust = False):
prompts = []
options = ['play', 'exit']
if winner == 'player':
prompts.append('player wins!')
if bust: prompts.append('dealer busts')
self.wins += 1
elif winner == 'dealer':
prompts.append('Dealer wins :(')
if bust: prompts.append('player busts')
self.losses += 1
else: prompts.append('Pushback!')
call = self.display(options, prompts, show = True)
if call == 'exit': self.exit = True
game = Game()

Related

Creating the war(card) game using OOP in Python

I am trying to create the war card game where 2 players draw a card each on the table, and the player whose card has max value gets both the cards, if the card values are equal(called war condition) each player draws 5 cards, and the value of the last card among these 5 cards are compared and works similarly as above. A player wins when either the other player runs out of cards or if in war condition the other player has less than 5 cards.
My questions:
When I am running the game logic sometimes it runs but sometimes it gets stuck in an infinite loop. Why?
I can notice that when the total number of cards for both players at all times should be 52, but here it is decreasing. Why? (I can see that the cards are getting lost every time the game goes into war condition, but I am not able to understand why that is happening, since I am adding all the 10 cards to the player whose card has a greater value.)
I have tried another method where I assume that players are always at war and then approach it, which works. But I want to understand why, if I break it into steps which I am trying to do here, is it not working?
Code:
import random
suits = ['Hearts','Clubs','Spades','Diamonds']
ranks = ['Two','Three','Four','Five','Six','Seven','Eight','Nine','Ten','Jack','Queen','King','Ace']
values = {'Two': 2, 'Three': 3, 'Four': 4, 'Five': 5, 'Six' : 6 , 'Seven' :7, 'Eight': 8,'Nine':9,
'Ten':10,'Jack':11, 'Queen': 12,'King': 13,'Ace':14 }
classes:
class Card():
def __init__(self,suit,rank):
self.suit = suit
self.rank = rank
self.value = values[rank]
#string method
def __str__(self):
return self.rank + ' of ' + self.suit
class Deck():
def __init__(self):
self.all_cards = [] #list of objects
for suit in suits:
for rank in ranks:
#create card object
created_card = Card(suit,rank)
self.all_cards.append(created_card)
def shuffle(self): #method to shuffle the card
random.shuffle(self.all_cards)
def deal_one(self):
return self.all_cards.pop() #we want the last card from deck
class Player():
def __init__(self,name):
self.name = name
self.all_cards = []
def remove_one(self):
return self.all_cards.pop(0) #to remove card from beginning of the list
def add_cards(self,new_cards):
if type(new_cards) == type([]):
self.all_cards.extend(new_cards)
else:
self.all_cards.append(new_cards)
def __str__(self):
return f'Player {self.name} has {len(self.all_cards)} cards.'
And below is the final game logic:
#create 2 new instances of the player class
player1_name = input('Enter the name of Player1: ')
player2_name = input('Enter the name of Player2: ')
player1 = Player(player1_name)
player2 = Player(player2_name)
newdeck = Deck()
newdeck.shuffle()
#splitting the deck among the two players - alternate card from deck goes to each player respectively
for i in range(0,len(newdeck.all_cards)-1,2):
player1.add_cards(newdeck.all_cards[i])
player2.add_cards(newdeck.all_cards[i+1])
#for x in range(26):
# player1.add_cards(newdeck.deal_one())
#player2.add_cards(newdeck.deal_one())
print(player1)
print(player2)
game_status = True
round_num = 0
while game_status == True:
round_num +=1
print(f"Round {round_num}")
if len(player1.all_cards) == 0:
print('Player 1 out of cards'+ player2.name + 'Wins!')
game_status = False
break
if len(player2.all_cards) == 0:
print('Player 2 out of cards' + player1.name + 'Wins!')
game_status = False
break
else:
player_cards = []
player1_card = player1.remove_one()
player2_card = player2.remove_one()
player_cards.append(player1_card)
player_cards.append(player2_card)
print('player1_card_value: ',player1_card.value)
print('')
print('player2_card_value: ',player2_card.value)
print('')
print(player1)
print('')
print(player2)
at_war = True
if player1_card.value == player2_card.value:
while at_war == True:
player1_list = []
player2_list = []
card_list = []
if len(player1.all_cards) < 5:
print('Player 2 won')
game_status = False
at_war = False
break
elif len(player2.all_cards) <5:
print('Player 1 won')
game_status = False
at_war = False
break
if len(player1.all_cards) >= 5 and len(player2.all_cards) >= 5:
for i in range(5):
player1_list.append(player1.remove_one())
player2_list.append(player2.remove_one())
card_list.extend(player1_list)
card_list.extend(player2_list)
print("CARD LIST LEN", len(card_list))
if player1_list[0].value > player2_list[0].value:
player1.add_cards(card_list)
at_war = False
break
elif player1_list[0].value < player2_list[0].value:
player2.add_cards(card_list)
#player2.add_cards(player1_list)
at_war = False
break
else:
at_war = True
elif player1_card.value > player2_card.value:
player1.add_cards(player_cards)
#player1.add_cards(player2_cards)
#print('p1>p2', player1)
elif player2_card.value > player1_card.value:
player2.add_cards(player_cards)
print(player1)
print(player2)
if len(player1.all_cards) == 0:
print('Player 2 won')
elif len(player2.all_cards) == 0:
print('Player 1 won')
Output: When it was stuck in an infinite loop:(You can see the total number of cards is now 34 instead of 52.)

Simple Blackjack game: deck list becomes NoneType [duplicate]

This question already has answers here:
Why does random.shuffle return None?
(5 answers)
Closed 3 years ago.
I tired to make a simple blackjack game in Python. When executing the code, list of cards in deck (self.deck) creates problems - becomes NoneType, when it should be a list.
'''
This is a blackjack game for the project 2
'''
import random
cardsuits = ['Hearts', 'Diamonds', 'Spades', 'Clubs']
cardrank = ['Two','Three','Four','Five','Six','Seven','Eight','Nine','Ten','Jack','Queen','King','Ace']
cardvalues = {'Two':2, 'Three':3, 'Four':4, 'Five':5, 'Six':6, 'Seven':7, 'Eight':8, 'Nine':9, 'Ten':10, 'Jack':10, 'Queen':10, 'King':10, 'Ace':11}
class Card:
#class card has two attributes: suit and rank. asking for string will result in rank of suit response. There is a value calcluated, using cardvalues dictionary.
def __init__(self,suit,rank):
self.suit = suit
self.rank = rank
def __str__(self):
return self.rank + ' of ' + self.suit
#def value(self):
# self.value = cardvalues[self.rank]
# #think about ace here; it can be worth 10 or 1 depending on hand
class Deck:
def __init__(self):
self.deck = []
for suit in cardsuits:
for rank in cardrank:
self.deck.append(Card(suit,rank))
def __str__(self):
deck_comp = ""
for card in self.deck:
deck_comp = deck_comp + "\n" + card.__str__()
return "Deck contains " + deck_comp
def reroll(self):
self.deck = random.shuffle(self.deck)
def take_a_card(self):
single_card = self.deck.pop()
return single_card
class Hand:
def __init__(self):
self.cards = []
self.value = 0
self.aces = 0
def add_card(self, card):
self.cards.append(card)
self.value = self.value + cardvalues[card.rank]
if card.rank == "Ace":
self.aces = self.aces + 1
def ace_adjust(self):
if self.value > 21 and self.aces > 0:
self.value = self.value - 10
self.aces = self.aces -1
class Funds:
def __init__(self):
self.balance= 0
self.bet = 0
def winbet(self):
self.balance = self.balance + self.bet * 2
def losebet(self):
self.bet = 0
def draw(self):
self.balance = self.balance + self.bet
self.bet = 0
def Place_a_Bet():
while True:
placebetamount = int(input(print('Select amount you want to bet.')))
if isinstance(placebetamount, int) == False:
print('Invalid bet type. You have to input a digit.')
continue
elif placebetamount > PlayerFunds.balance:
print('You tried to bet more money than you have available. You cannot bet more than: ' + PlayerFunds.balance)
continue
elif placebetamount <= 0:
print('Invaild Bet. You have to bet a positive number.')
continue
else:
PlayerFunds.balance = PlayerFunds.balance - placebetamount
PlayerFunds.bet = placebetamount
break
def hit(deck,hand):
hand.add_card(CurrentGameDeck.take_a_card())
hand.ace_adjust()
def hit_or_stand(deck, hand):
global playing # to control an upcoming while loop
Decision = input(str(print('Your Turn. Type "Hit" to get another card. Type "Stand" to move onto Dealers move')))
while True:
if Decision == "Hit":
hit(deck,hand)
elif Decision == "Stand":
playing = False
else:
print('just Hit or Stand. Other inputs are invalid')
continue
break
def CardStateGame(PlayerHand, DealerHand):
print('Dealer Shows : ' + DealerHand.cards[0] + ' out of ' + len(DealerHand.cards))
print('Dealer score is :' + DealerHand.value)
print('Your cards are ')
for card in PlayerHand.cards:
print(card)
print('and their value is: ' + PlayerHand.value)
def CardStateEndgame(PlayerHand, DealerHand):
print('Dealer value is ' + DealerHand.value + ' and his cards are: ')
for card in DealerHand.cards:
print(card)
print('Your cards are ')
for card in PlayerHand.cards:
print(card)
print('and their value is: ' + PlayerHand.value)
#end conditions
def player_bust(PlayerHand, PlayerFunds):
print('Value of your cards (' + PlayerHand.value +') exceeds 21. You lose.')
PlayerFunds.losebet()
def player_wins(PlayerFunds):
print('You won.')
PlayerFunds.winbet()
def dealer_bust(DealerHand, PlayerFunds):
print('Dealer loses, because value of his cards (' + DealerHand.value +') exceeds 21')
PlayerFunds.winbet()
def dealer_wins(PlayerFunds):
print('Dealer won.')
PlayerFunds.losebet()
def draw(PlayerFunds):
print('Both participants have same values. Its a draw')
PlayerFunds.draw()
#gameplay
print('This is a game of blackjack. You and the dealer (AI) will try to reach card value of 21, or just higher than your opponent. Scores higher than 21 will lose')
PlayerFunds = Funds()
while True:
startamount = int(input(print('Select the amount of money you enter the game with. Try to keep it plausible')))
if startamount <= 0 or isinstance(startamount, int) == False:
print('You cant play with that amount of money. try again')
continue
else:
PlayerFunds.balance = startamount
break
playing = True
while True:
CurrentGameDeck = Deck()
CurrentGameDeck.reroll()
Place_a_Bet()
DealerHand = Hand()
PlayerHand = Hand()
DealerHand.add_card(CurrentGameDeck.take_a_card())
PlayerHand.add_card(CurrentGameDeck.take_a_card())
DealerHand.add_card(CurrentGameDeck.take_a_card())
PlayerHand.add_card(CurrentGameDeck.take_a_card())
CardStateGame(PlayerHand, DealerHand)
while playing == True:
hit_or_stand(CurrentGameDeck,PlayerHand)
CardStateGame(PlayerHand, DealerHand)
if PlayerHand.value >21:
player_bust(PlayerHand, PlayerFunds)
break
if PlayerHand.value <= 21:
while DealerHand.value <17:
hit(CurrentGameDeck, DealerHand)
CardStateEndgame
if DealerHand.value > 21:
dealer_bust()
elif DealerHand.value > PlayerHand.value:
dealer_wins()
elif PlayerHand.value > DealerHand.value:
player_wins()
elif PlayerHand.value == DealerHand.value:
draw()
newgame = 0
newgame = input(print('Do you want to play again? Type Y or N'))
if newgame.lower() == 'Y' and PlayerFunds.balance >=0:
playing = True
continue
elif newgame.lower() == 'Y' and PlayerFunds.balance < 0:
print('no more funds. GG')
break
else:
print('thanks for playing')
break
I tried to use only
cardsuits = ['Hearts', 'Diamonds', 'Spades', 'Clubs']
cardrank = ['Two','Three','Four','Five','Six','Seven','Eight','Nine','Ten','Jack','Queen','King','Ace']
cardvalues = {'Two':2, 'Three':3, 'Four':4, 'Five':5, 'Six':6, 'Seven':7, 'Eight':8, 'Nine':9, 'Ten':10, 'Jack':10, 'Queen':10, 'King':10, 'Ace':11}
class Card:
#class card has two attributes: suit and rank. asking for string will result in rank of suit response. There is a value calcluated, using cardvalues dictionary.
def __init__(self,suit,rank):
self.suit = suit
self.rank = rank
def __str__(self):
return self.rank + ' of ' + self.suit
#def value(self):
# self.value = cardvalues[self.rank]
# #think about ace here; it can be worth 10 or 1 depending on hand
class Deck:
def __init__(self):
self.deck = []
for suit in cardsuits:
for rank in cardrank:
self.deck.append(Card(suit,rank))
def __str__(self):
deck_comp = ""
for card in self.deck:
deck_comp = deck_comp + "\n" + card.__str__()
return "Deck contains " + deck_comp
def reroll(self):
self.deck = random.shuffle(self.deck)
def take_a_card(self):
single_card = self.deck.pop()
return single_card
and then
test = Deck()
allows me to shuffle the deck, and pop a single card out of it - so other parts of the code may be a problem, but I have no idea which, where and why.
In the future you should try to slim your code down to pinpoint the problem. Since the issue was surrounding the deck you only really needed to post that class. The error you are getting is because of this function below:
def reroll(self):
self.deck = random.shuffle(self.deck)
If you take a look at the docs you will see that this function shuffles in place. Change the function to be this instead:
def reroll(self):
random.shuffle(self.deck)

How do I swap which function runs at the beginning of my while loop?

I have just starting learning Python and I am writing a rudimentary Blackjack game. I have got the basic stuff working but I want to add a little bit of finesse here and there. I am looking for a way in which my introduction function at the beginning of my while loop is substituted for my new_round function.
My idea was that I could have a round counter running at the top which would dictate which function would run through and if/elif statement.
Suffice it to say, it doesn't work. Firstly, I would like to know why it doesn't and secondly would like a way to do it!
import random
suits = ('Hearts', 'Diamonds', 'Spades', 'Clubs')
ranks = ('Two', 'Three', 'Four', 'Five', 'Six', 'Seven', 'Eight', 'Nine', 'Ten', 'Jack', 'Queen', 'King', 'Ace')
values = {'Two':2, 'Three':3, 'Four':4, 'Five':5, 'Six':6, 'Seven':7, 'Eight':8, 'Nine':9, 'Ten':10, 'Jack':10, 'Queen':10, 'King':10, 'Ace':11}
player_name = ''
playing = True
class Card:
def __init__(self,suit,rank):
self.suit = suit
self.rank = rank
def __str__(self):
return f'{self.rank} of {self.suit}'
class Deck:
def __init__(self):
self.deck = []
for suit in suits:
for rank in ranks:
self.deck.append(Card(suit,rank))
def __str__(self):
deck_comp = ''
for card in self.deck:
deck_comp += '\n '+card.__str__()
return 'The deck has:' + deck_comp
def shuffle(self):
random.shuffle(self.deck)
def deal(self):
single_card = self.deck.pop()
return single_card
class Hand:
def __init__(self):
self.cards = []
self.value = 0
self.aces = 0
def add_card(self,card):
self.cards.append(card)
self.value += values[card.rank]
if card.rank == 'Ace':
self.aces += 1
def adjust_for_ace(self):
#if value of players hand is over 21 and includes an ace then the player will automatically have the ace value reduced to 1
#also track ace counter will revert to 0
while self.value > 21 and self.aces > 0:
self.value -= 10
self.aces -= 1
class Chips:
def __init__(self,total):
self.total = total
self.bet = 0
def win_bet(self):
self.total += self.bet
def lose_bet(self):
self.total -= self.bet
def take_bet(chips):
while True:
try:
player_chips.bet = int(input('How many chips would you like to bet?: '))
except ValueError:
print('\nSorry, the number of chips must be a number!')
else:
if player_chips.bet > player_chips.total:
print(f"\nSorry guy, your bet can't exceed {player_chips.total} chips.")
else:
print(f"\nYour bet of {player_chips.bet} chips has been accepted - good luck!")
break
def introduction():
global player_name
print("\nWelcome to BlackJack! Get as close to 21 as you can without busting.\n\nThe Dealer will hit up to 17, Face cards count as 10 and Aces are 1/11.")
player_name=input("The first round is about to begin, what is your name friend?: ")
def next_round():
global player_name
print("Hey ho, let's go another round!")
def chip_count():
global player_name
print(f"{player_name}, your current chip count stands at {player_chips.total}")
def play_again():
global player_name
global playing
while True:
replay = input(f"{player_name}, would you like to play another round?: ").upper()
if replay[0] == 'Y':
return True
elif replay[0] == 'N':
print(f"\nThanks for playing - you leave the table with {player_chips.total} chips.")
break
else:
print("Sorry, I don't understand what you are saying, do you want to play the next round, or not? Y or N!: ")
continue
def total():
global player_name
while True:
try:
total = int(input(f'Hello {player_name}, how many chips will you be using this game?: '))
except ValueError:
print('\nSorry, the number of chips must be a number!')
else:
return total
print(f"\nWelcome to the table - you currently have {total} chips to play with.")
def hit(deck,hand):
#run the add card function within the Hand Class with the card argument being generated by the deal function within the Deck Class.
hand.add_card(deck.deal())
hand.adjust_for_ace()
def hit_or_stand(deck,hand):
global player_name
global playing
while True:
response = input(f"{player_name}, Would you like to hit or stand?: ")
if response[0].upper() == 'H':
hit(deck,hand)
elif response[0].upper() == 'S':
print(f"{player_name} stands. It is the Dealer's turn")
playing = False
else:
print("\nI can't understand what you are saying - are you hitting or standing?!")
continue
break
def show_some(player,dealer):
print("\nDealer's Hand:")
print("<card hidden>")
print(dealer.cards[1])
print("\nPlayer's Hand: ",*player.cards, sep='\n')
print("Value of your cards: ",player.value)
def show_all(player,dealer):
print("\nDealer's Hand: ",*dealer.cards, sep='\n')
print("Dealer's Hand = ",dealer.value)
print("\nPlayer's Hand: ",*player.cards, sep='\n')
print("Player's Hand = ",player.value)
def player_busts(player,dealer,chips):
global player_name
print(f"{player_name} busts!")
chips.lose_bet()
def player_wins(player,dealer,chips):
global player_name
print(f"{player_name} wins the round!")
chips.win_bet()
def dealer_busts(player,dealer,chips):
print("Dealer busts!")
chips.win_bet()
def dealer_wins(player,dealer,chips):
print("Dealer wins!")
chips.lose_bet()
def push(player,dealer,chips):
print("You have tied with the Dealer! It's a push, your chips have been refunded.")
############################################################################################################################################################
while True:
counter = 0
if counter > 0:
next_round()
elif counter == 0:
introduction()
#Create & shuffle the deck, deal 2 cards to each player.
deck = Deck()
deck.shuffle()
player_hand = Hand()
player_hand.add_card(deck.deal())
player_hand.add_card(deck.deal())
dealer_hand = Hand()
dealer_hand.add_card(deck.deal())
dealer_hand.add_card(deck.deal())
#Set up Player's chips
player_chips = Chips(total())
#Prompt the Player for their bet
take_bet(player_chips)
#Show cards (keep one dealer card hidden)
show_some(player_hand,dealer_hand)
while playing == True:
#Prompt for player hit or stand
hit_or_stand(deck,player_hand)
#show cards (keep one dealer card hidden)
show_some(player_hand,dealer_hand)
#if player's hand exceeds 21, player busts - break loop
if player_hand.value > 21:
player_busts(player_hand,dealer_hand,player_chips)
break
#if player hasn't bust, play dealer's hand until dealer reaches 17 or busts.
if player_hand.value <= 21:
while dealer_hand.value < 17:
hit(deck,dealer_hand)
#show all cards
show_all(player_hand,dealer_hand)
#run different winning scenarios
if dealer_hand.value > 21:
dealer_busts(player_hand,dealer_hand,player_chips)
elif dealer_hand.value > player_hand.value:
dealer_wins(player_hand,dealer_hand,player_chips)
elif dealer_hand.value < player_hand.value:
player_wins(player_hand,dealer_hand,player_chips)
else:
push(player_hand,dealer_hand,player_chips)
#inform player of their current chip count.
chip_count()
counter += 1
#play another round?
if play_again() == True:
continue
else:
break
You are resetting counter to 0 at the start of every loop.
You probably meant to set it to 0 before the loop started, then have it increase every loop.
Instead of:
while True:
counter = 0
if counter > 0:
try:
counter = 0
while True:
if counter > 0:
The issue in your code is that each time you loop through your While True: loop, you are setting the variable counter back to zero.... So even though you increment counter at the end of your loop, it is then immediately set back to zero as the loop restarts.
A different way to accomplish what you are looking for would be to run your introduction() function just before your While True: loop, and then edit the final lines of your code to call the next_round() function, as such:
if play_again() == True:
next_round()
continue

__str__ python method issue

I am making a python blackjack game. I have an error in this code which I can't figure out. In the end when I test out the hit function and print the hand, it does not show me the list. Instead, it says [<main.Card object at 0x02F9F5F0>].
Here is my code.
#Blackjack
import random
suits = ['Clubs', 'Spades', 'Diamonds', 'Hearts']
ranks = ['Two', 'Three', 'Four', 'Five', 'Six', 'Seven', 'Eight', 'Nine', 'Ten', 'Jack', 'Queen', 'King', 'Ace']
values = {'Two': 2, 'Three': 3, 'Four': 4, 'Five': 5, 'Six': 6, 'Seven': 7, 'Eight': 8, 'Nine': 9, 'Ten': 10, 'Jack': 10, 'Queen': 10, 'King': 10, 'Ace': 11}
game_on = True
class Card:
def __init__(self, suit, rank):
self.suit = suit
self.rank = rank
def __str__(self):
return(f'{self.rank} of {self.suit}')
class Deck:
def __init__(self):
self.deck = []
for suit in suits:
for rank in ranks:
self.deck.append(Card(suit, rank))
def __str__(self):
deck_comp = ''
for card in self.deck:
deck_comp += '\n ' + card.__str__()
return deck_comp
def shuffle(self):
random.shuffle(self.deck)
def deal(self):
single_card = self.deck.pop()
return single_card
class Hand:
def __init__(self):
self.cards = [] # start with an empty list as we did in the Deck class
self.value = 0 # start with zero value
self.aces = 0 # add an attribute to keep track of aces
def add_card(self, card):
self.cards.append(card)
self.value += values[card.rank]
if card.rank == 'Ace':
self.aces += 1 # add to self.aces
def adjust_for_ace(self):
while self.value > 21 and self.aces:
self.value -= 10
self.aces -= 1
class Chips:
def __init__(self):
self.total = 100
self.bet = 0
def win_bet(self):
self.chips += self.bet
def lose_bet(self):
self.chips -= self.bet
def go_for_bet(chips):
while True:
try:
chips.bet = int(input('Please enter a betting amount: '))
except TypeError:
print('Please enter an integer')
continue
else:
if chips.bet > chips.total:
print(f'You do not have enough chips to bet {chips.bet}')
else:
break
def hit(deck, hand):
hand.add_card(deck.deal())
hand.adjust_for_ace()
def hit_or_stand(deck, hand):
while True:
x = input('Would you like to hit or stand? Say \'h\' or \'s\'')
if x[0].lower() == 'h':
hit(deck, hand)
elif x[0].lower() == 's':
print('You stand.')
else:
print('Try again please')
continue
break
deck = Deck()
hand = Hand()
hit(deck, hand)
print(hand.cards)
Either:
class Card:
def __repr__(self):
return self.__str__()
Or convert your Card objects to string first:
print([str(x) for x in hand.cards])
Just to make the difference between __repr__ and __str__ extra clear (:
class Repr:
def __repr__(self):
return 'Here I am with __repr__'
class Str:
def __str__(self):
return 'Here I am with __str__'
print('Plain:')
print(Repr(), Str())
print('In list:')
print([Repr(), Str()])
>
Plain:
Here I am with __repr__ Here I am with __str__
In list:
[Here I am with __repr__, <__main__.Str object at 0x00000216BC2940F0>]
it's a class list and only have one item in it. you can print items like:
for i in hand.cards:
print(i)

Why doesn't the main while loop finish executing? It just hangs up somewhere

We are making this Black Jack program to test card counting methods. We are trying to get the auto play function working, and it does, but when we run it in a while loop the loop never finishes and exits.
"""
Eli Byers
Josh Rondash
Black_Jack.py
"""
import random
#---------- CLASSES -----------------------------------------------------------
class Card(object):
def __init__(self, rank, suit):
self.rank = rank
self.suit = suit
self.value = 0
if self.rank is "Ace":
self.value = 11
if self.rank.isdigit():
self.value = int(self.rank)
if self.rank in ["Jack", "Queen", "King"]:
self.value = 10
def __str__(self):
return "["+str(self.rank)+" "+str(self.suit)+"]"
class Deck(object):
def __init__(self, numofdecks):
self.deck = []
self.suit = [" Clubs", " Hearts", " Spades", " Diamonds"]
self.rank = ["Ace", "2", "3", "4", "5", "6", "7", "8", "9", "10", "Jack", "Queen", "King"]
self.numofdecks = numofdecks
for i in range(self.numofdecks):
for r in self.rank:
for s in self.suit:
self.deck.append(Card(r,s))
def __str__(self):
deck_str = ""
for card in self.deck:
deck_str += str(card)+" "
deck_str = deck_str[:-1]
return deck_str
def __len__(self):
return len(self.deck)
def __getitem__(self,i):
return self.deck[i]
def __delitem__(self, i):
del self.deck[i]
def draw(self):
top_card = self.deck[0]
del self.deck[0]
return top_card
def addcard(self,card):
self.deck.append(card)
def shuffle(self): #Random shuffle function
a = len(self.deck)
b = a-1
for d in range(b,0,-1):
e = random.randint(0,d)
if e == d:
continue
self.deck[d],self.deck[e] = self.deck[e],self.deck[d]
return self.deck
class Player(object):
def __init__(self, bankroll):
self.hand = []
self.bankroll = bankroll
self.score = 0
self.bet = 0
self.count = 0
self.aces = 0
self.dealer_hand = []
def __str__(self):
hand = ""
for card in self.hand:
hand += str(card)+" "
return "Hand: "+hand+" Bank: "+str(self.bankroll)+" Bet: "+str(self.bet)+" Ct: "+str(self.count)+" A: "+str(self.aces)
def __getitem__(self, i):
return self.hand[i]
def getcard(self,Card):
self.hand.append(Card)
self.score = 0
ace = 0
for card in self.hand:
if card.rank == "Ace":
ace += 1
self.score += 1
else:
self.score += card.value
for a in range(ace):
if (self.score + 10) <= 21:
self.score += 10
self.updateCount(Card,"P")
def placebet(self, b=0):
if b != 0:
self.bankroll -= b
self.bet += b
else:
self.bet += input("Bankroll: "+str(self.bankroll)+" Ct: "+str(self.count)+" A: "+str(self.aces)+" Place bet: ")
self.bankroll -= self.bet
def updateCount(self, card, player):
if card.value in range(2,6):
self.count += 1
elif card.value is 10:
self.count -= 1
elif card.rank is "Ace":
self.aces += 1
if player == "D":
self.dealer_hand.append(card)
def makeBet(self):
bet = 0.1*self.bankroll
if self.count > 3:
c = 0
for i in range(self.count):
c += 1
if c == 3:
bet += 0.5 * bet
c = 0
elif self.count < -3:
bet -= 0.5 * bet
return bet
def Play(self):
if self.score < 17:
choice = 1 #hit
else:
choice = 2 #stand
return choice
class Dealer(object):
def __init__(self, Deck, discardpile, Player):
self.deck = Deck
self.discardpile = discardpile
self.player = Player
self.hand = []
self.score = 0
def __str__(self):
hand = ""
for card in self.hand:
hand += str(card)+" "
return "Dealer Hand: "+hand
def __getitem__(self, i):
return self.deck[i]
def draw(self):
cardval = self.deck.draw()
self.hand.append(cardval)
self.score = 0
ace = 0
for card in self.hand:
if card.rank == "Ace":
ace += 1
self.score += 1
else:
self.score += card.value
for a in range(ace):
if (self.score + 10) <= 21:
self.score += 10
player.updateCount(cardval,"D")
def deal(self, Player):
for i in range(2):
self.player.getcard(self.deck.draw())
self.draw()
def burn(self):
self.discardpile.addcard(self.deck.draw())
def blackjack(self):
if self.score == 21:
return True
else:
return False
class Table(Dealer, Player):
def __init__(self, Dealer, Player, Deck , discardpile):
self.dealer = Dealer
self.player = Player
self.deck = Deck
self.discardpile = discardpile
self.betplaced = 0
def initGame(self):
self.clearTable()
Deck.shuffle(self.deck)
self.dealer.burn()
def clearTable(self):
for card in self.player.hand:
self.discardpile.addcard(card)
for card in self.dealer.hand:
self.discardpile.addcard(card)
self.player.hand = []
self.dealer.hand = []
def playGame(self):
self.betplaced = self.player.placebet()
self.dealer.deal(self.player)
print self.player
print self.dealer
if self.dealer.blackjack():
print("Dealer Black Jack!")
elif self.player.score <= 21:
stand = 0
while self.player.score < 21 and stand == 0:
print("Use number Keys> Hit: 1 Stand: 2")
choice = input()
if choice == 1: # Hit
self.player.getcard(self.deck.draw())
elif choice == 2: # Stand
stand = 1
print self.player
print ("Your score is "+str(self.player.score))
while self.dealer.score <= 17 and self.player.score <= 21:
if self.dealer.score == 17:
for card in self.dealer.hand:
if card.rank == "Ace":
self.dealer.draw()
else:
self.dealer.draw()
print self.dealer
print ("Dealer score is "+str(self.dealer.score))
if self.dealer.score <= 21:
if (self.player.score > self.dealer.score) and (self.player.score <= 21) :
if self.player.score == 21:
self.player.bankroll += self.player.bet*2.5
else:
self.player.bankroll += self.player.bet*2
print ("Win")
elif self.player.score == self.dealer.score:
self.player.bankroll += self.player.bet
print("Push")
else:
print("You Lose")
elif (self.dealer.score > 21) and (self.player.score <= 21):
if self.player.score == 21:
self.player.bankroll += self.player.bet*2.5
else:
self.player.bankroll += self.player.bet*2
print ("Win")
else:
print("You Lose.")
self.player.bet = 0
self.player.dealer_hand = []
print
def autoPlay(self):
self.betplaced = self.player.placebet(int(self.player.makeBet()))
self.dealer.deal(self.player)
if (self.dealer.blackjack() == False) and (self.player.score <= 21):
stand = 0
while self.player.score < 21 and stand == 0:
choice = player.Play()
if choice == 1: # Hit
self.player.getcard(self.deck.draw())
elif choice == 2: # Stand
stand = 1
while self.dealer.score <= 17 and self.player.score <= 21:
if self.dealer.score == 17:
for card in self.dealer.hand:
if card.rank == "Ace":
self.dealer.draw()
else:
self.dealer.draw()
if self.dealer.score <= 21:
if (self.player.score > self.dealer.score) and (self.player.score <= 21):
if self.player.score == 21:
self.player.bankroll += self.player.bet*2.5
else:
self.player.bankroll += self.player.bet*2
print ("Win")
elif self.player.score == self.dealer.score:
self.player.bankroll += self.player.bet
print("Push")
else:
print("Lose")
elif (self.dealer.score > 21) and (self.player.score <= 21):
if self.player.score == 21:
self.player.bankroll += self.player.bet*2.5
else:
self.player.bankroll += self.player.bet*2
print ("Win")
else:
print("Lose")
self.player.bet = 0
self.player.dealer_hand = []
print self.player.bankroll
#----------- MAIN -----------------------------------
deck = Deck(6)
player = Player(500)
discardpile = Deck(0)
dealer = Dealer(deck, discardpile, player)
table = Table(dealer, player, deck, discardpile)
table.initGame()
while (player.bankroll > 0) and (player.bankroll < 1000):
table.autoPlay()
table.clearTable()
print "Game Over."
Just add some debug statements. You have multiple while loops in your methods. I'm sure a simple print statement will catch the errors in your logic.
DUDE, I found the infinite loop within 1 minute. lucky i had python installed on my box.
LINE 251
if (self.dealer.blackjack() == False) and (self.player.score <= 21):
stand = 0
while self.player.score < 21 and stand == 0:
print "in player score"
choice = player.Play()
if choice == 1: # Hit
self.player.getcard(self.deck.draw())
elif choice == 2: # Stand
stand = 1
while self.dealer.score <= 17 and self.player.score <= 21:
print "in dealer score"
print self.dealer.score
if self.dealer.score == 17:
for card in self.dealer.hand:
if card.rank == "Ace":
self.dealer.draw()
else:
self.dealer.draw()

Categories