Object Oriented Playing Cards in Python

Thu Jun 13 2019

Photo by Michał Parzuchowski on Unsplash

enum became a part of the Python standard library starting in version 3.4 and I thought that the classic OOP playing cards example would be a good demonstration of it.

In this example, I'm not going to worry about the actual playing card values like in Poker (twos are more valuable than threes, spades are more valuable than hearts, etc.) since there are many games where cards may not conform to those values.

I'll first create the set of four enums for the suite and the set of thirteen enums for the card's face value. I'll also use auto, since I'm not going to worry about the exact value of the enum, though I'll list them in Poker value order and auto will automatically give me those values anyway.

from enum import Enum, auto


class Suite(Enum):
    DIAMOND = auto()
    CLUB = auto()
    HEART = auto()
    SPADE = auto()


class Value(Enum):
    TWO = auto()
    THREE = auto()
    FOUR = auto()
    FIVE = auto()
    SIX = auto()
    SEVEN = auto()
    EIGHT = auto()
    NINE = auto()
    TEN = auto()
    JACK = auto()
    QUEEN = auto()
    KING = auto()
    ACE = auto()

Now I'll create the Card class with getters and setters so I can ensure the proper enums are passed when initializing each card.

class Card:
    def __init__(self, suite: Suite, value: Value):
        self.suite = suite
        self.value = value

    @property
    def suite(self):
        return self._suite

    @property
    def value(self):
        return self._value

    @suite.setter
    def suite(self, suite: Suite):
        if suite not in Suite:
            raise Exception
        self._suite = suite

    @value.setter
    def value(self, value: Value):
        if value not in Value:
            raise Exception
        self._value = value

    def __repr__(self):
        return f"<Card {self.value} of {self.suite}>"

If we try to initialize the Card with anything other than a valid Suite or Value, Python will raise an Exception.

Okay, now we can create a class for a deck of cards.

class Deck:
    def __init__(self):
        self.cards = [Card(s, v) for s in Suite for v in Value]

    def __repr__(self):
        output = [f"{c}\n" for c in self.cards]
        return "".join(output)

Now, let's give this a try and see if everything is alright.

>>> from card import Suite, Value, Card, Deck
>>> deck = Deck()
>>> len(deck.cards)
52
>>> deck
<Card Value.TWO of Suite.DIAMOND>
<Card Value.THREE of Suite.DIAMOND>
<Card Value.FOUR of Suite.DIAMOND>
<Card Value.FIVE of Suite.DIAMOND>
<Card Value.SIX of Suite.DIAMOND>
<Card Value.SEVEN of Suite.DIAMOND>
<Card Value.EIGHT of Suite.DIAMOND>
<Card Value.NINE of Suite.DIAMOND>
<Card Value.TEN of Suite.DIAMOND>
<Card Value.JACK of Suite.DIAMOND>
<Card Value.QUEEN of Suite.DIAMOND>
<Card Value.KING of Suite.DIAMOND>
<Card Value.ACE of Suite.DIAMOND>
<Card Value.TWO of Suite.CLUB>
<Card Value.THREE of Suite.CLUB>
<Card Value.FOUR of Suite.CLUB>
<Card Value.FIVE of Suite.CLUB>
<Card Value.SIX of Suite.CLUB>
<Card Value.SEVEN of Suite.CLUB>
<Card Value.EIGHT of Suite.CLUB>
<Card Value.NINE of Suite.CLUB>
<Card Value.TEN of Suite.CLUB>
<Card Value.JACK of Suite.CLUB>
<Card Value.QUEEN of Suite.CLUB>
<Card Value.KING of Suite.CLUB>
<Card Value.ACE of Suite.CLUB>
<Card Value.TWO of Suite.HEART>
<Card Value.THREE of Suite.HEART>
<Card Value.FOUR of Suite.HEART>
<Card Value.FIVE of Suite.HEART>
<Card Value.SIX of Suite.HEART>
<Card Value.SEVEN of Suite.HEART>
<Card Value.EIGHT of Suite.HEART>
<Card Value.NINE of Suite.HEART>
<Card Value.TEN of Suite.HEART>
<Card Value.JACK of Suite.HEART>
<Card Value.QUEEN of Suite.HEART>
<Card Value.KING of Suite.HEART>
<Card Value.ACE of Suite.HEART>
<Card Value.TWO of Suite.SPADE>
<Card Value.THREE of Suite.SPADE>
<Card Value.FOUR of Suite.SPADE>
<Card Value.FIVE of Suite.SPADE>
<Card Value.SIX of Suite.SPADE>
<Card Value.SEVEN of Suite.SPADE>
<Card Value.EIGHT of Suite.SPADE>
<Card Value.NINE of Suite.SPADE>
<Card Value.TEN of Suite.SPADE>
<Card Value.JACK of Suite.SPADE>
<Card Value.QUEEN of Suite.SPADE>
<Card Value.KING of Suite.SPADE>
<Card Value.ACE of Suite.SPADE>

If you found the post helpful and would like this same content delivered to you,

Subscribe to my newsletter

;