Skip to content

Commit

Permalink
solution code
Browse files Browse the repository at this point in the history
  • Loading branch information
smpotts committed Jun 16, 2024
1 parent 55e2d43 commit 41be9e4
Show file tree
Hide file tree
Showing 4 changed files with 133 additions and 22 deletions.
32 changes: 23 additions & 9 deletions src/card.py
Original file line number Diff line number Diff line change
@@ -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
48 changes: 40 additions & 8 deletions src/deck.py
Original file line number Diff line number Diff line change
@@ -1,31 +1,63 @@
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):
card = Card(suit, rank)
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()
"""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())
32 changes: 27 additions & 5 deletions src/hand.py
Original file line number Diff line number Diff line change
@@ -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)
43 changes: 43 additions & 0 deletions src/poker_hand.py
Original file line number Diff line number Diff line change
@@ -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('')

0 comments on commit 41be9e4

Please sign in to comment.