Skip to content

Instantly share code, notes, and snippets.

@voroninman
Last active December 29, 2015 00:49
Show Gist options
  • Save voroninman/7588850 to your computer and use it in GitHub Desktop.
Save voroninman/7588850 to your computer and use it in GitHub Desktop.
"""
Question:
Design a deck of cards that can be used for different card games
Python 3.x
"""
import random
import itertools
class Deck(object):
"""A deck for a card game."""
def __init__(self, StrategyCls, CardCls):
"""
Get a name and copy all the cards from Strategy and shuffle them.
"""
self.name = StrategyCls.deck_name()
self.cards = [CardCls(self, face) for face in StrategyCls.all_faces()]
random.shuffle(self.cards)
def __repr__(self):
"""Output the name and the unique value for a deck."""
return ' '.join([self.name, str(id(self))])
class Card(object):
"""A card of a deck."""
def __init__(self, deck, face):
"""
Link the card with a deck and assign its face.
By default, the face is closed.
"""
self.deck = deck
self._face = face
self.close()
def __repr__(self):
"""The card face is its represantation."""
return str(self.face)
def open(self):
"""Make the face public."""
self.face = self._face
return self.face
def close(self):
"""Make the face private."""
self.face = '<?>'
class DeckStrategy(object):
"""The basic class for a deck Strategy."""
pass
class PockerDeckStrategy(DeckStrategy):
"""An example of an inherited DeckStrategy class."""
@staticmethod
def all_faces():
"""The set of cards for the particular game."""
return tuple([''.join(face) for face in itertools.product(
['2', '3', '4', '5', '6', '7', '8', '9', '10', 'J', 'Q', 'K', 'A'],
['♠', '♣', '♥', '♦'])])
@staticmethod
def deck_name():
"""The name of the desk."""
return 'Classic Pocker Deck'
if __name__ == '__main__':
"""
Of course, the question is more theoretical than practical. There are
a lot of implementations of this problem. It depends on author's
preferences in terms of fabrics or strategies, memory usage limits, a level of
abstraction, further game customization. I don't want to make a simple thing
complicated. As far as I'm concerned, I think this draft is understandable,
scaleable and has simple API/Interface. As you can see, this example
has no comparison method for cards. I did it deliberately
because it's a game strategic side and it should be implementend as
a part of a game abstraction.
Usage example:
"""
pd = Deck(PockerDeckStrategy, Card)
print(pd, [card.open() for card in pd.cards[0:5]])
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment