0

I encountered a bug while writing a text-based Poker game. In the code below, at line 45, I am trying to append a Card object into a Player object's array instance "cards". However, as seen from the output, it is inserted into all cards instance of all Player objects. The same case applies when there are 3 players as well. I am using Python 3.9.9. Why does Python behave so and how can I fix it?

Code:

from random import shuffle

class Game:
    def __init__(self, players=[], n_players=0, common_cards=[]):
        self.players = players
        self.n_players = n_players
        self.common_cards = common_cards

class Player:
    def __init__(self, id, cards=[]):
        self.id = id
        self.cards = cards

    def __repr__(self):
        return 'Player %d' % (self.id + 1)

class Card:
    def __init__(self, rank, house):
        self.rank = rank
        self.house = house
    
    def __repr__(self):
        return '{%d, %d}' % (self.rank, self.house)

def generate_deck():
    deck = []
    for house in range(4):
        for rank in range(2, 15):
            deck.append(Card(rank, house))
    shuffle(deck)
    return deck


if __name__ == '__main__':
    game = Game()
    game.players.append(Player(game.n_players))
    game.n_players += 1
    game.players.append(Player(game.n_players))
    game.n_players += 1

    deck = generate_deck()
    for counter in range(2):
        for i in range(game.n_players):
            card = deck.pop(0)
            game.players[i].cards.append(card)
            print('Card rank=%d house=%d dealt to %s with id %d cards %s at counter=%d i=%d' % (card.rank, card.house, game.players[i], game.players[i].id, game.players[i].cards, counter, i))
    for _ in range(5):
        game.common_cards.append(deck.pop(0))
    print(game.players[0].cards)
    print(game.players[1].cards)
    print(game.common_cards)
    

Output:

Card rank=11 house=2 dealt to Player 1 with id 0 cards [{11, 2}] at counter=0 i=0
Card rank=8 house=2 dealt to Player 2 with id 1 cards [{11, 2}, {8, 2}] at counter=0 i=1
Card rank=4 house=3 dealt to Player 1 with id 0 cards [{11, 2}, {8, 2}, {4, 3}] at counter=1 i=0
Card rank=5 house=1 dealt to Player 2 with id 1 cards [{11, 2}, {8, 2}, {4, 3}, {5, 1}] at counter=1 i=1
[{11, 2}, {8, 2}, {4, 3}, {5, 1}]
[{11, 2}, {8, 2}, {4, 3}, {5, 1}]
[{8, 1}, {3, 3}, {8, 0}, {6, 0}, {3, 0}]
funnydman
  • 9,083
  • 4
  • 40
  • 55
  • I bet it is https://stackoverflow.com/questions/1132941/least-astonishment-and-the-mutable-default-argument – funnydman Sep 04 '22 at 20:46

0 Answers0