pythonclassappendblackjack

.append function writes to all players variables even though it should only write to one players variables


Im making a blackjack sorta thing that supports several players. It does this by having a list of player objects, that each have a cards variable, where the player's cards are stored.

I want to draw a card and append it to player 2's list of cards (player 2 is the last player). I have a function to draw a card and i thought it would be possible to just take the output from that and append it to the player's list of cards.

So i did that with the line: players[2].cards.append(drawCard()) But instead it appended the card to all the player objects cards variable

I have no clue why

This is the code:

import random

players: list[object] = [] # list for the player objects to be put into


def drawCard(): # Takes a random number from 2, 14 and returns it. Like in blackjack
    card = random.randint(2,14)
    if (card >= 11) and (card <= 13):
        print("[DRAWCARD] - Facecard")
        card = 10
    elif card == 14:
        print("[DRAWCARD] - Ace")
        card = 11
    return card


class Player: # The player with a list of cards
    cards: list[int] = []


for i in range(3): # Make three players and save them in players list
    players.append(Player())


players[2].cards.append(drawCard()) # use drawCard() and append players[2]'s card list with the given card

for player in players: # print the cards of all players
    print(player.cards)
    print(player)

And this is the output: (the numbers of course change every time you run it, but the problem is persistent, it should only give a card to the last player)

[5]
<__main__.Player object at 0x00000140AEB5A3F0>
[5]
<__main__.Player object at 0x00000140AEB5A330>
[5]
<__main__.Player object at 0x00000140AEB5BDA0>

Solution

  • cards: list[int] = []
    

    Assigned there, this creates a class attribute that's shared by all instances. To create instance attributes that are unique to each instance, use __init__:

    class Player: # The player with a list of cards
        def __init__(self):
            self.cards: list[int] = []
    

    Or make the class a Dataclass.