0

I'm making a card game in python, and having trouble dealing the cards out to players (for simplification, cards are just strings, where AH is ace of hearts). I'm trying to deal one card to each player in turn using modulo. However, for each iteration of the for loop every player is getting the same card, not just one player. I don't understand why - if anyone could help I'd be v appreciative!

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


deck = ["AS", "2S", "3S", "4S", "5S", "6S", "7S", "8S", "9S", "10S", "JS", "QS", "KS",
        "AH", "2H", "3H", "4H", "5H", "6H", "7H", "8H", "9H", "10H", "JH", "QH", "KH",
        "AC", "2C", "3C", "4C", "5C", "6C", "7C", "8C", "9C", "10C", "JC", "QC", "KC",
        "AD", "2D", "3D", "4D", "5D", "6D", "7D", "8D", "9D", "10D", "JD", "QD", "KD"]

player1 = Player()
player2 = Player()
player3 = Player()
players = [player1, player2, player3]


def dealCards(deck, players):
    for i in range(len(deck)):
        j = i % len(players)
        players[j].hand.append(deck[i])


calculateHandSize(deck, players)
tyates97
  • 45
  • 6
  • 2
    Possible duplicate of ["Least Astonishment" and the Mutable Default Argument](https://stackoverflow.com/questions/1132941/least-astonishment-and-the-mutable-default-argument) – Brad Solomon Oct 04 '19 at 18:24
  • All instances of `Player` share the same `hand` object – Brad Solomon Oct 04 '19 at 18:25
  • 1
    By 'same hand object', Brad means that they all point to the exact same spot in memory. Using a mutable object as a default argument will give you this behavior. Instead, you can set `None` as the default value for `hand` and then do `self.hand = [ ] if hand is None else hand`. – SyntaxVoid Oct 04 '19 at 18:28

1 Answers1

0

This gets the result I believe you want. There were a few issues I fixed:

class Player:
    def __init__(self, hand=None):
        if hand is None:
            self.hand = []
        else:
            self.hand = hand

deck = ["AS", "2S", "3S", "4S", "5S", "6S", "7S", "8S", "9S", "10S", "JS", "QS", "KS",
        "AH", "2H", "3H", "4H", "5H", "6H", "7H", "8H", "9H", "10H", "JH", "QH", "KH",
        "AC", "2C", "3C", "4C", "5C", "6C", "7C", "8C", "9C", "10C", "JC", "QC", "KC",
        "AD", "2D", "3D", "4D", "5D", "6D", "7D", "8D", "9D", "10D", "JD", "QD", "KD"]

player1 = Player()
player2 = Player()
player3 = Player()
players = [player1, player2, player3]


def deal_cards(deck, players):
    for i, card in enumerate(deck):
        j = i % len(players)
        players[j].hand.append(deck[i])


deal_cards(deck, players)

for p in players:
    print(p.hand)

Where the hands look like:

['AS', '4S', '7S', '10S', 'KS', '3H', '6H', '9H', 'QH', '2C', '5C', '8C', 'JC', 'AD', '4D', '7D', '10D', 'KD']
['2S', '5S', '8S', 'JS', 'AH', '4H', '7H', '10H', 'KH', '3C', '6C', '9C', 'QC', '2D', '5D', '8D', 'JD']
['3S', '6S', '9S', 'QS', '2H', '5H', '8H', 'JH', 'AC', '4C', '7C', '10C', 'KC', '3D', '6D', '9D', 'QD']

I think the problem was in the use of range where enumerate is a better choice. I did not dig in to prove exactly what was wrong. I also changed the default arg in the __init__ to be more Python happy.

The solution could be compacted more and probably streamlined.

Marc
  • 1,895
  • 18
  • 25