poker-ranking-service/poker/models.py

59 lines
1.5 KiB
Python
Raw Normal View History

2022-11-18 20:45:19 +00:00
from __future__ import annotations
from collections import Counter
from pydantic import BaseModel, validator
2022-11-18 20:45:19 +00:00
from poker.constants import Rank, Suit, Value
class Card(BaseModel):
"""Card domain model class."""
suit: Suit
value: Value
def __hash__(self) -> int:
"""Hash function."""
return hash(f"{self.value} {self.suit}")
2022-11-18 20:45:19 +00:00
def __le__(self, other: Card) -> bool:
"""Less than or equal to."""
return self.value <= other.value
2022-11-18 20:45:19 +00:00
def __lt__(self, other: Card) -> bool:
"""Strictly less than."""
return self.value < other.value
class Hand(BaseModel):
"""Hand domain model class."""
2022-11-18 20:45:19 +00:00
cards: list[Card]
@validator("cards")
2022-11-18 20:45:19 +00:00
def validate_unique(cls, cards: list[Card]) -> list[Card]:
"""Validate hand comprises unique cards."""
if len(cards) != len(set(cards)):
raise ValueError("Hand contains duplicate cards.")
return cards
2022-11-18 20:45:19 +00:00
@validator("cards")
def validate_length(cls, cards: list[Card]) -> list[Card]:
"""Validate hand has five cards."""
if len(cards) != 5:
raise ValueError("Hand must have five cards.")
return cards
@property
def value_counts(self) -> list[tuple[Value, int]]:
"""Return count of each card value in hand."""
return Counter([card.value for card in self.cards]).most_common()
2022-11-18 20:45:19 +00:00
class RankedHand(Hand):
2023-05-16 18:16:43 +00:00
"""Ranked hand domain model class."""
2022-11-18 20:45:19 +00:00
rank: Rank
description: str