0

I'm trying to develop a simple BlackJack game with Python.I'm at the stage where I want to deal a single card to the dealer's hand (a list in the dealer class) and the player's hand(a list in the player's class). When I deal to the dealer there is no problem however I have the players that are in a list called playerSet, I use a for loop to pop a card from the deck and append it to each player's hand. The problem is that each time I try to append to one player's hand the cards are duplicated to each player's hand.

This is some of the relevant code:

def DealCards():
    global BlackJackDeck
    Dealer1.addToHand(BlackJackDeck.drawCard())
    #Would love to know why same card is ent to both decks
    for i in range(0,len(playerSet)):
        playerSet[i].addToHand(BlackJackDeck.drawCard())
        break

This is the draw method located in the deck class

def drawCard(self):
        #may need to change this method
        return self.Deck.pop()

In terms of the player's class this is how the hand is declared as a list

class player(object):
    name = None
    Token = int(500)
    score = 0
    bet = 0
    hand = []

    def __init__(self,name):
        self.name = name

This is the method used to add a card to a player's hand - A list in the player class

def addToHand(self,card):
        if isinstance(card,Card):
                self.hand.append(card)
        else: 
            print("This is not a Card..")

The Blackjack deck is just an instance of the deck class which I will attach below

BlackJackdeck =Deck()


from Card import Card
import random

class Deck():
    Deck=[]
    def __init__(self):
         self.Deck =[]
         self.build()

    def build(self):

        for s in ["Hearts", "Spades", "Diamonds","Clubs"]:
            for v in range(1,14):
                if v>10:
                    for royalty in ["Jack","Queen", "King"]:
                        self.Deck.append(Card("{} of {}".format(royalty,s),s,10))
                    break
                else:
                    self.Deck.append(Card("{} of {}".format(v,s),s,v))

    def view(self):
        for view in self.Deck:
            #view.printer()
            #print("{} of {} ".format(view.value, view.suit))
            print("{}".format(view.name))

    def drawCard(self):
        #may need to change this method
        return self.Deck.pop()


    def shuffle(self):
        random.shuffle(self.Deck)


    def returnHand(self,playerHand=[]):
        if len(self.Deck)>52:
            print(f"Player hand couldn't be added there are too many cards in the deck {playerHand}")
        elif len(self.Deck)+len(playerHand)<=52:
            self.Deck.append(playerHand)

I also think that for for some reason all of the instantiated player objects either have the same hand or they are having the same card objects to their hand respectively and I can't figure out why.

  • Note that code fences require backticks, not normal quotes. – Carcigenicate Apr 15 '20 at 20:39
  • This sounds to me like a common pitfall: you populated a list with references to the same object. So if you print out the deck - they're all the same card? If so, https://stackoverflow.com/q/1132941/7915759 You'll probably have to change your code to ensure each card in a list is a unique object reference. – Todd Apr 15 '20 at 20:40
  • Or.. another way it could happen.. each player's list is actually a reference to the same list... Did you do something like this in the Player's init: `__init__(self, hand=[])` ? – Todd Apr 15 '20 at 20:46

1 Answers1

0

Maybe you can show more code? Specifically, how the BlackJackDeck is initialized. Also, how are the players' hands initialized? I'll update this answer once we get more information. For now, it's hard to say what's going on without seeing more.

Here's an unrelated thing that caught my attention, however: list.pop takes an optional integer parameter which it treats as the index from which to pop. The way your code is written, it seems that you are under the impression that this number represents the number of items you wish to pop, which is incorrect. Therefore, when you say BlackJackDeck.drawCard(1), you are popping and returning the card at index 1 (the second card). If you say BlackJackDeck.drawCard(5), you are not popping five cards from the deck, you are popping a single card - the card at index 5 (the sixth card).

EDIT - Thanks for posting more of your code. The major problem that sticks out right away is the fact that each player's hand is not an instance variable, it's a (static) class variable. Take a look at this snippet, which is meant to simulate the structure your code has right now:

class Player:
    hand = []

    def __init__(self, name):
        self.name = name

    def add_card_to_hand(self, card):
        self.hand.append(card)


player_1 = Player("Bob")
player_2 = Player("Tom")

player_1.add_card_to_hand("Ace of Spades")
player_2.add_card_to_hand("Queen of Hearts")

print(f"{player_1.name}'s hand: {player_1.hand}")
print(f"{player_2.name}'s hand: {player_2.hand}")

Output:

Bob's hand: ['Ace of Spades', 'Queen of Hearts']
Tom's hand: ['Ace of Spades', 'Queen of Hearts']
>>> 

hand is a single list in memory that's shared across all Player instances, because it's a class variable. Therefore, if you invoke add_card_to_hand, regardless of what player object you're referring to, you end up appending to the same list. What you really want is a separate list for each player, so hand should be an instance variable, like this:

class Player:

    def __init__(self, name):
        self.hand = []
        self.name = name

    def add_card_to_hand(self, card):
        self.hand.append(card)


player_1 = Player("Bob")
player_2 = Player("Tom")

player_1.add_card_to_hand("Ace of Spades")
player_2.add_card_to_hand("Queen of Hearts")

print(f"{player_1.name}'s hand: {player_1.hand}")
print(f"{player_2.name}'s hand: {player_2.hand}")

Output:

Bob's hand: ['Ace of Spades']
Tom's hand: ['Queen of Hearts']
>>> 

I'll look at the rest of the code you posted in bit. If I see anything else I'll update this post.

Paul M.
  • 10,481
  • 2
  • 9
  • 15
  • in terms of the player's hand this is how it is initialized in the abstract class – Gregboy_242 Apr 16 '20 at 02:45
  • I thought about that. I had added the index 1 when I was tinkering with it to figure out why each player hand kept getting the same result but it didn't help at all, maybe even made it worse. I appreciate any help, thanks! – Gregboy_242 Apr 16 '20 at 02:56