Source code for blackjack21.deck

__all__ = ('Card', 'Deck')

from random import shuffle
from typing import List, Text, Tuple, Any, Generator

from .exceptions import InvalidSuits, InvalidRanks

Suits = Tuple[Text, Text, Text, Text]
Ranks = Tuple[Text, Text, Text, Text, Text, Text, Text, Text, Text, Text, Text, Text, Text]

[docs] class Card: """Card class :param suit: suit of the card :param rank: rank of the card :param value: value of the card in the game """ __slots__ = ( '_suit', '_rank', '_value', ) def __init__(self, suit: Text, rank: Text, value: int): self._suit = suit self._rank = rank self._value = value def __repr__(self) -> Text: return f"{self.rank} of {self.suit}" def __str__(self) -> Text: return f"{self.rank} of {self.suit}" @property def suit(self) -> Text: """Card suit""" return self._suit @property def rank(self) -> Text: """Card rank""" return self._rank @property def value(self) -> int: """Card value""" return self._value
[docs] class Deck: # noinspection PyUnresolvedReferences """Deck of cards class (Iterable) :param suits: tuple of 4 suits :param ranks: tuple of 13 card ranks :keyword count: int number of decks to be merged :raises InvalidSuits: if length of suits is not 4 :raises InvalidRanks: if length of ranks is not 13 """ __slots__ = ( '_cards', '_drawn_cards', ) def __init__(self, suits: Suits, ranks: Ranks, **kwargs: Any): if len(suits) != 4: raise InvalidSuits(suits) if len(ranks) != 13: raise InvalidRanks(ranks) self._cards = [] for suit in suits: for rank, value in zip(ranks, (11, 2, 3, 4, 5, 6, 7, 8, 9, 10, 10, 10, 10)): self._cards.append(Card(suit, rank, value)) self._cards *= kwargs.get('count', 1) self._drawn_cards = [] shuffle(self._cards) def __repr__(self) -> Text: return f"<Deck cards: {len(self._cards)}>" def __str__(self) -> Text: return f"<Deck cards: {len(self._cards)}>" def __iter__(self) -> Generator['Card', None, None]: """Iterate through the cards in the deck""" yield from self._cards def __getitem__(self, index: int) -> 'Card': """Get card at index""" return self._cards[index] def __len__(self) -> int: """Number of cards left in the deck""" return len(self._cards) @property def cards(self) -> List['Card']: """List of Card class objects currently in the deck""" return self._cards @property def drawn_cards(self) -> List['Card']: """List of Card class objects drawn from the deck""" return self._drawn_cards
[docs] def shuffle(self) -> None: """Shuffle the cards in the deck""" shuffle(self._cards) return None
[docs] def draw_card(self) -> 'Card': """Draw a card from the deck :return: Card object """ drawn_card = self._cards.pop() self._drawn_cards.append(drawn_card) return drawn_card