2

I am trying to write a program that deals cards and I have the problem that when I deal a card object to one player, all players receive the object in their class attribute “hand.”

The code is below, any help is appreciated! My apologies if I didn't follow the stackoverflow indenting format correctly. This is my first time posting a question.

    import random

    class Player(object):
        def __init__(self,name,balance=100,hand=[]):
            self.name = name
            self.balance = balance
            self.hand = hand

        def reveal_all(self):
            '''
            This method prints out a player's hand.
            '''
            reveal = []
            for x in self.hand:
                reveal = reveal + [x.name]
            print(reveal)

    class Card(object):
        def __init__(self,name,val):
            self.name = name
            self.val = val

    card_ob1 = Card('2 of Hearts',2)
    card_ob2 = Card('3 of Hearts',3)
    card_ob3 = Card('4 of Hearts',4)
    card_ob4 = Card('5 of Hearts',5)
    card_ob5 = Card('6 of Hearts',6)
    card_ob6 = Card('7 of Hearts',7)
    card_ob7 = Card('8 of Hearts',8)
    card_ob8 = Card('9 of Hearts',9)

    deck = [card_ob1,card_ob2,card_ob3,card_ob4,card_ob5,card_ob6,card_ob7,card_ob8]

    def plyr1_geta_card():
        card = random.choice(deck)
        player1obj.hand += [card]
        deck.remove(card)

    def dealer_geta_card():
        card = random.choice(deck)
        dealerobj.hand.append(card)
        deck.remove(card)

    player1obj = Player('Me',100)
    dealerobj = Player('The House')

    # Player 1 gets a card
    plyr1_geta_card()

    # The card is added to both the dealer and player hand attribute for some reason!
    dealerobj.reveal_all()

    player1obj.reveal_all()
zondo
  • 19,901
  • 8
  • 44
  • 83

1 Answers1

1

The problem comes from your __init__ of the Player object, in your way, hand will be shared among all instances of Player : as can be seen in Section 9.3.5. Class and Instance Variables https://docs.python.org/3/tutorial/classes.html. A quick fix should be

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

By the way, it's not a good practice to write function to add cards to player like what you do, instead it should be a function to receive player object like :

 def plyr_geta_card(player):
     card = random.choice(deck)
     player.hand.append(card)
     deck.remove(card)
minhhn2910
  • 488
  • 4
  • 18
  • Thank you minhhn2910. That solved my problem and I will read the tutorial link. And thanks for improving my plyr1_geta_card function. The way I was doing it would require a separate function for each player object. Your way is much cleaner. – black_lab_fan Jul 27 '17 at 14:01
  • @black_lab_fan please consider upvote or mark it as the correct answer if possible :) – minhhn2910 Jul 27 '17 at 14:03
  • I did up vote you. I was notified that it was recorded, but not posted publicly because I have less that 15 contributions on stackoverflow. I missed the check box though... clicking it now. – black_lab_fan Jul 27 '17 at 14:12
  • Thanks and welcome to StackOverflow – minhhn2910 Jul 27 '17 at 14:16