Created
June 6, 2019 19:07
-
-
Save clamytoe/9db2b9faf6d036405dd8ea2c59f3f33f to your computer and use it in GitHub Desktop.
Quick little generic card game demo
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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