|
| 1 | +# game.py |
| 2 | + |
| 3 | +import random |
| 4 | +import sys |
| 5 | + |
| 6 | + |
| 7 | +class Card: |
| 8 | + SUITS = "♠ ♡ ♢ ♣".split() |
| 9 | + RANKS = "2 3 4 5 6 7 8 9 10 J Q K A".split() |
| 10 | + |
| 11 | + def __init__(self, suit, rank): |
| 12 | + self.suit = suit |
| 13 | + self.rank = rank |
| 14 | + |
| 15 | + def __repr__(self): |
| 16 | + return f"{self.suit}{self.rank}" |
| 17 | + |
| 18 | + |
| 19 | +class Deck: |
| 20 | + def __init__(self, cards): |
| 21 | + self.cards = cards |
| 22 | + |
| 23 | + @classmethod |
| 24 | + def create(cls, shuffle=False): |
| 25 | + """Create a new deck of 52 cards""" |
| 26 | + cards = [Card(s, r) for r in Card.RANKS for s in Card.SUITS] |
| 27 | + if shuffle: |
| 28 | + random.shuffle(cards) |
| 29 | + return cls(cards) |
| 30 | + |
| 31 | + def deal(self, num_hands): |
| 32 | + """Deal the cards in the deck into a number of hands""" |
| 33 | + cls = self.__class__ |
| 34 | + return tuple(cls(self.cards[i::num_hands]) for i in range(num_hands)) |
| 35 | + |
| 36 | + |
| 37 | +class Player: |
| 38 | + def __init__(self, name, hand): |
| 39 | + self.name = name |
| 40 | + self.hand = hand |
| 41 | + |
| 42 | + def play_card(self): |
| 43 | + """Play a card from the player's hand""" |
| 44 | + card = random.choice(self.hand.cards) |
| 45 | + self.hand.cards.remove(card) |
| 46 | + print(f"{self.name}: {card!r:<3} ", end="") |
| 47 | + return card |
| 48 | + |
| 49 | + |
| 50 | +class Game: |
| 51 | + def __init__(self, *names): |
| 52 | + """Set up the deck and deal cards to 4 players""" |
| 53 | + deck = Deck.create(shuffle=True) |
| 54 | + self.names = (list(names) + "P1 P2 P3 P4".split())[:4] |
| 55 | + self.hands = { |
| 56 | + n: Player(n, h) for n, h in zip(self.names, deck.deal(4)) |
| 57 | + } |
| 58 | + |
| 59 | + def play(self): |
| 60 | + """Play a card game""" |
| 61 | + start_player = random.choice(self.names) |
| 62 | + turn_order = self.player_order(start=start_player) |
| 63 | + |
| 64 | + # Play cards from each player's hand until empty |
| 65 | + while self.hands[start_player].hand.cards: |
| 66 | + for name in turn_order: |
| 67 | + self.hands[name].play_card() |
| 68 | + print() |
| 69 | + |
| 70 | + def player_order(self, start=None): |
| 71 | + """Rotate player order so that start goes first""" |
| 72 | + if start is None: |
| 73 | + start = random.choice(self.names) |
| 74 | + start_idx = self.names.index(start) |
| 75 | + return self.names[start_idx:] + self.names[:start_idx] |
| 76 | + |
| 77 | + |
| 78 | +if __name__ == "__main__": |
| 79 | + # Read player names from command line |
| 80 | + player_names = sys.argv[1:] |
| 81 | + game = Game(*player_names) |
| 82 | + game.play() |
0 commit comments