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])