Skip to content

Instantly share code, notes, and snippets.

@clamytoe
Created June 6, 2019 19:07
Show Gist options
  • Save clamytoe/9db2b9faf6d036405dd8ea2c59f3f33f to your computer and use it in GitHub Desktop.
Save clamytoe/9db2b9faf6d036405dd8ea2c59f3f33f to your computer and use it in GitHub Desktop.
Quick little generic card game demo
from dataclasses import dataclass, field
from random import shuffle
from secrets import choice
from typing import Dict, Generator, List
NUMBERS: List[str] = list(map(str, range(1, 11)))
FACES: List[str] = "J Q K A".split()
SUITS: List[str] = "♠ ♥ ♦ ♣".split()
FACE_SCORES: Dict[str, int] = {"J": 11, "Q": 12, "K": 13, "A": 14}
@dataclass
class Card:
face: str
suit: str
@property
def value(self) -> int:
return int(self.face) if self.face not in FACES else FACE_SCORES[self.face]
def __str__(self) -> str:
return f"{self.face}{self.suit}"
@dataclass
class Hand:
cards: List[Card] = field(default_factory=list)
def __iter__(self) -> Generator[Card, None, None]:
for cards in self.__dict__.keys():
for card in self.__getattribute__(cards):
yield card
def __str__(self) -> str:
return " ".join([str(card) for card in self.cards])
@property
def score(self) -> int:
return sum([card.value for card in self.cards])
@dataclass
class Poker:
numbers: List[str] = field(default_factory=list)
faces: List[str] = field(default_factory=list)
suits: List[str] = field(default_factory=list)
deck: List[Card] = field(default_factory=list)
def __post_init__(self):
self.numbers = self.numbers if self.numbers else NUMBERS
self.faces = self.faces if self.faces else FACES
self.suits = self.suits if self.suits else SUITS
self.deck = self.deck if self.deck else self.shuffle
@property
def shuffle(self) -> List[Card]:
deck = [
Card(card, suit)
for card in (self.numbers + self.faces)
for suit in self.suits
]
shuffle(deck)
return deck
def deal(self, number_of_cards: int = 5) -> Hand:
hand = []
for _ in range(number_of_cards):
card = choice(self.deck)
hand.append(card)
self.deck.remove(card)
return Hand(hand)
def play(self, players: int = 2) -> None:
hands = [game.deal() for _ in range(players)]
scores = [hand.score for hand in hands]
highest_score = max(scores)
for idx, hand in enumerate(hands, 1):
winner = " * " if hand.score == highest_score else " "
msg = f"{winner} [{hand.score}] Player {idx}: {hand}"
print(msg)
if __name__ == "__main__":
game = Poker()
game.play(8)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment