Source code for maverick.holding

from typing import Optional, Tuple
import random
from itertools import combinations

from pydantic import BaseModel

from .card import Card
from .deck import Deck
from .utils import estimate_holding_strength, score_hand
from .enums import HandType

__all__ = ["Holding"]


[docs] class Holding(BaseModel): """A number of cards held by a player. Fields ------ cards : list[Card] The list of cards in the holding. Examples -------- >>> from maverick import Holding, Card ... pair_of_aces = Holding(cards=[ ... Card(suit='S', rank=14), # Ace of Spades ... Card(suit='H', rank=14) # Ace of Hearts ... ]) >>> pair_of_aces.estimate_strength(n_simulations=1000, n_players=8) 0.85 # Example output, actual value may vary """ cards: list[Card]
[docs] @classmethod def random(cls, *, n: int = 2, deck: Optional[Deck] = None) -> "Holding": """Generate a random holding of 2 cards. Parameters ---------- n : int, optional The number of cards in the holding (default is 2). deck : Deck, optional An optional deck to draw cards from. If not provided, random cards will be generated. """ if deck: cards = random.sample(deck.cards, n) else: cards = Card.random(n=n) return cls(cards=cards)
[docs] @classmethod def all_possible_holdings(cls, cards: list[Card], n: int = 2) -> iter: """Generate all possible holdings of n cards from the given deck. Parameters ---------- cards : list[Card] The list of cards to choose from. n : int, optional The number of cards in each holding (default is 2). """ for combination in combinations(cards, n): yield cls(cards=list(combination))
[docs] def score(self) -> Tuple[HandType, float]: """Classifies and scores the hand. Returns (HandType, float_score) where higher scores = stronger hands. """ return score_hand(self.cards)
[docs] def estimate_strength(self, **kwargs) -> float: """ Estimate the strength of the holding via Monte Carlo simulation. Returns a number between 0 and 1, representing the probability of the current hand being the strongest. The keyword arguments are passed to `estimate_holding_strength`. """ return estimate_holding_strength(holding=self.cards, **kwargs)
def __repr__(self) -> str: return " ".join([card.utf8() for card in self.cards])