From 41be9e422f3a8900d938bdc28772ea5b96e40b9f Mon Sep 17 00:00:00 2001 From: Shelby Potts Date: Sun, 16 Jun 2024 08:07:46 -0500 Subject: [PATCH] solution code --- src/card.py | 32 ++++++++++++++++++++++--------- src/deck.py | 48 +++++++++++++++++++++++++++++++++++++++-------- src/hand.py | 32 ++++++++++++++++++++++++++----- src/poker_hand.py | 43 ++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 133 insertions(+), 22 deletions(-) create mode 100644 src/poker_hand.py diff --git a/src/card.py b/src/card.py index c3c5139..1e60597 100644 --- a/src/card.py +++ b/src/card.py @@ -1,22 +1,36 @@ class Card: - # instance attributes - suit_names = ['Clubs', 'Diamonds', 'Hearts', 'Spades'] - rank_names = [None, 'Ace', '2', '3', '4', '5', '6', '7', - '8', '9', '10', 'Jack', 'Queen', 'King'] + """Represents a standard playing card. - def __init__(self, suit=0, rank=2): - # defaults to a 2 of Clubs + Attributes: + suit: integer 0-3 + rank: integer 1-13 + """ + + suit_names = ["Clubs", "Diamonds", "Hearts", "Spades"] + rank_names = [None, "Ace", "2", "3", "4", "5", "6", "7", + "8", "9", "10", "Jack", "Queen", "King"] - # class attributes + def __init__(self, suit=0, rank=2): self.suit = suit self.rank = rank def __str__(self): + """Returns a human-readable string representation.""" return '%s of %s' % (Card.rank_names[self.rank], Card.suit_names[self.suit]) + def __eq__(self, other): + """Checks whether self and other have the same rank and suit. + + returns: boolean + """ + return self.suit == other.suit and self.rank == other.rank + def __lt__(self, other): - # using tuple comparison + """Compares this card to other, first by suit, then rank. + + returns: boolean + """ t1 = self.suit, self.rank t2 = other.suit, other.rank - return t1 < t2 + return t1 < t2 \ No newline at end of file diff --git a/src/deck.py b/src/deck.py index 653c1f7..c2c78cd 100644 --- a/src/deck.py +++ b/src/deck.py @@ -1,11 +1,15 @@ -from random import random - -from src.card import Card - +import random class Deck: + """Represents a deck of cards. + + Attributes: + cards: list of Card objects. + """ def __init__(self): + """Initializes the Deck with 52 cards. + """ self.cards = [] for suit in range(4): for rank in range(1, 14): @@ -13,19 +17,47 @@ def __init__(self): self.cards.append(card) def __str__(self): + """Returns a string representation of the deck. + """ res = [] for card in self.cards: res.append(str(card)) return '\n'.join(res) - def pop_card(self): - return self.cards.pop() - def add_card(self, card): + """Adds a card to the deck. + + card: Card + """ self.cards.append(card) + def remove_card(self, card): + """Removes a card from the deck or raises exception if it is not there. + + card: Card + """ + self.cards.remove(card) + + def pop_card(self, i=-1): + """Removes and returns a card from the deck. + + i: index of the card to pop; by default, pops the last card. + """ + return self.cards.pop(i) + def shuffle(self): + """Shuffles the cards in this deck.""" random.shuffle(self.cards) def sort(self): - self.cards.sort() \ No newline at end of file + """Sorts the cards in ascending order.""" + self.cards.sort() + + def move_cards(self, hand, num): + """Moves the given number of cards from the deck into the Hand. + + hand: destination Hand object + num: integer number of cards to move + """ + for i in range(num): + hand.add_card(self.pop_card()) \ No newline at end of file diff --git a/src/hand.py b/src/hand.py index 39e4377..3b14d9c 100644 --- a/src/hand.py +++ b/src/hand.py @@ -1,12 +1,34 @@ from src.deck import Deck - class Hand(Deck): + """Represents a hand of playing cards.""" - def init__(self, label=''): + def __init__(self, label=''): self.cards = [] self.label = label - def move_cards(self, hand, num): - for i in range(num): - hand.add_card(self.pop_card()) + +def find_defining_class(obj, method_name): + """Finds and returns the class object that will provide + the definition of method_name (as a string) if it is + invoked on obj. + + obj: any python object + method_name: string method name + """ + for ty in type(obj).mro(): + if method_name in ty.__dict__: + return ty + return None + + +if __name__ == '__main__': + deck = Deck() + deck.shuffle() + + hand = Hand() + print(find_defining_class(hand, 'shuffle')) + + deck.move_cards(hand, 5) + hand.sort() + print(hand) \ No newline at end of file diff --git a/src/poker_hand.py b/src/poker_hand.py new file mode 100644 index 0000000..833e2dd --- /dev/null +++ b/src/poker_hand.py @@ -0,0 +1,43 @@ +from __future__ import print_function, division + +from src.hand import Hand +from src.deck import Deck + + +class PokerHand(Hand): + """Represents a poker hand.""" + + def suit_hist(self): + """Builds a histogram of the suits that appear in the hand. + + Stores the result in attribute suits. + """ + self.suits = {} + for card in self.cards: + self.suits[card.suit] = self.suits.get(card.suit, 0) + 1 + + def has_flush(self): + """Returns True if the hand has a flush, False otherwise. + + Note that this works correctly for hands with more than 5 cards. + """ + self.suit_hist() + for val in self.suits.values(): + if val >= 5: + return True + return False + + +if __name__ == '__main__': + # make a deck + deck = Deck() + deck.shuffle() + + # deal the cards and classify the hands + for i in range(7): + hand = PokerHand() + deck.move_cards(hand, 7) + hand.sort() + print(hand) + print(hand.has_flush()) + print('') \ No newline at end of file