Ok, so I'm experiencing a weird error, and unfortunately, I don't know that I can show both examples here.
Take a look at the following code (apologies for the length):
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}
class Card():
def __init__(self,suit,rank):
self.suit = suit
self.rank = rank
## Attributes listed in the __init__ statement do not have to
## correlate to called objects (ie: suit,rank)
self.value = values[rank]
## Values represents the integer value of each card as compared
## to it's string (word) based rank
def __str__(self):
return self.rank + " of " + self.suit
## Allows for printing in the form of X of Y, or Two of Hearts as an example
# Deck will be a compilation of all card objects to a single list
# that can then be shuffled, dealt from, etc.
class Deck():
def __init__(self):
## All cards starts off with a blank list
self.all_cards = []
## For each suit in suits
for suit in suits:
### For each rank in ranks
for rank in ranks:
#### Create the Card object equal to the suit and rank of the card
#### ie: Two of spades, three of clubs, etc.
created_card = Card(suit,rank)
#### Then append each card created to the self.all_cards list.
self.all_cards.append(created_card)
def shuffle(self):
## Method call to randomize the self.all_cards list internally
random.shuffle(self.all_cards)
def deal_one(self):
return self.all_cards.pop()
game_deck = Deck()
game_deck.shuffle()
## Checking to make sure the deck is full before continuing
print(len(game_deck.all_cards))
## Attempt without watching tutorial
class Player():
def __init__(self,name):
self.name = name
self.player_hand = []
self.balance = 100
self.bet = 0
def deposit(self,dep_amt):
self.balance += dep_amt
print(f'{dep_amt} added to balance. New balance is: ${self.balance}')
def withdraw(self,wit_amt):
self.balance -= wit_amt
print(f'{wit_amt} subtracted from balance. New balance is: ${self.balance}')
def player_bet(self,bet_amt = 0):
while True:
bet_amt = int(input("How much would you like to bet? \n"))
if bet_amt > self.balance:
print("Sorry, you don't have enough money, try again.")
elif bet_amt < 1:
print('Sorry, you must bet at least $1')
else:
print(f'Thanks, your bet is ${bet_amt}')
self.balance -= bet_amt
print(f'Your remaining balance is ${self.balance}')
break
## May need to be adjusted to clear the hand entirely, unsure
def remove_one(self):
return self.player_hand.pop(0)
# NOTE: The most cards a player can hold without busting is 11
def add_cards(self,new_cards):
### Single card object
self.player_hand.append(new_cards)
def __str__(self):
return f'{self.name} has a balance of ${self.balance}.'
## Attempt without watching tutorial
class Dealer():
def __init__(self,name):
self.name = name
self.player_hand = []
self.balance = 500
def deposit(self,dep_amt):
self.balance += dep_amt
print(f'{dep_amt} added to balance. New balance is: ${self.balance}')
def withdraw(self,wit_amt):
self.balance -= wit_amt
print(f'{wit_amt} subtracted from balance. New balance is: ${self.balance}')
def remove_one(self):
return self.player_hand.pop(0)
def add_cards(self,new_cards):
### Single card object
self.player_hand.append(new_cards)
def __str__(self):
return f'{self.name} has a balance of ${self.balance}.'
## Full Game Code
game_on = True
playing = False
while game_on == True:
game_check = input('Would you like to play Black Jack, Y/N? ').lower()
if game_check == 'y':
round_counter = 0
dealer_name = 'Klaus the Dealer'
dealer = Dealer(dealer_name)
player_name = input("Player One, what is your name? ")
player_one = Player(player_name)
print(f"Nice to meet you {player_name}, you'll be playing against {dealer_name}\n")
print(player_one)
print(dealer)
print("Let's play Black Jack!\n")
playing = True
else:
print('Ok, have a nice day')
game_on = False
break
while playing == True:
round_counter +=1
for x in range(2):
player_one.add_cards(game_deck.deal_one())
dealer.add_cards(game_deck.deal_one())
So when I run this code all at once, at the very last 2 lines, I get an index error when the code hits the player_one.add_cards(game_deck.deal_one())
stating IndexError: pop from empty list
The thing is, if I run this code in separate lines in a Jupiter notebook, and separate out the class calls from the rest of the game code, the player_one.add_cards(game_deck.deal_one())
works just fine.
Can anyone tell me what is causing this error?
Ok, so thanks to Jeff H for pointing out that the call for the card deal was inside an infinite loop, even though I couldn't fix the problem by breaking the loop itself, I did figure out how to start off the initial deal by absorbing it into the game_check
statement above, like so:
while game_on == True:
game_check = input('Would you like to play Black Jack, Y/N? ').lower()
if game_check == 'y':
round_counter = 0
dealer_name = 'Klaus the Dealer'
dealer = Dealer(dealer_name)
player_name = input("Player One, what is your name? ")
player_one = Player(player_name)
print(f"Nice to meet you {player_name}, you'll be playing against {dealer_name}\n")
print(player_one)
print(dealer)
print("Let's play Black Jack!\n")
playing = True
for x in range(2):
player_one.add_cards(game_deck.deal_one())
dealer.add_cards(game_deck.deal_one())
This won't account for having to deal cards into the hand later while in another while
loop, but it will fix the first issue.