Source code for maverick.utils.holding_strength

from typing import TYPE_CHECKING, Optional
from functools import partial

if TYPE_CHECKING:  # pragma: no cover
    from ..card import Card

from .scoring import find_highest_scoring_hand

__all__ = ["estimate_holding_strength"]


[docs] def estimate_holding_strength( holding: list["Card"], *, community_cards: Optional[list["Card"]] = None, n_simulations: int = 1000, n_players: int = 8, n_private: int = 0, n_community_cards_total: int = 5, ) -> float: """ Estimate the holding strength as the relative linelihood of winning against n_players - 1 opponents. If you are pre-flop, provide only your two hole cards in `holding`. If you are post-flop, provide your hole cards plus the community cards on the table in `community_cards`. Parameters ---------- holding : list[Card] The player's holding cards. n_simulations : int, optional The number of Monte Carlo simulations to run (default is 1000). n_players : int, optional The total number of players at the table including the player (default is 8). community_cards : list[Card], optional The community cards already on the table. If provided, these will be used in the simulations. n_community_cards_total : int, optional The total number of community cards in the game (default is 5). n_private : int, optional The number of private cards that must be included in the hand (default is 0). A value of 0 means any number of private cards can be used. Returns ------- float The relative linelihood of winning as a value in the unit interval [0, 1]. Notes ----- The estimated strength is only as accurate as the number of simulations run. Also, it is only the relative linelihood of winning mathematically, and does not take into account betting strategies, player tendencies, or other psychological factors. """ from maverick import Deck community_cards = community_cards or [] n_opponents = n_players - 1 n_holding_cards = len(holding) n_community_cards = len(community_cards) n_community_cards_req = n_community_cards_total - n_community_cards n_wins = 0 scorer = partial(find_highest_scoring_hand, n_private=n_private) # run simulations for _ in range(n_simulations): # start a new deck for each simulation deck_sim = Deck.standard_deck().shuffle() # remove known cards deck_sim.remove_cards(holding + community_cards) # deal opponent holdings opponent_holdings = [deck_sim.deal(n_holding_cards) for _ in range(n_opponents)] # deal missing community cards if n_community_cards_req > 0: community_cards_full = community_cards + deck_sim.deal( n_community_cards_req ) else: community_cards_full = community_cards # compare scores score = scorer(holding, community_cards_full)[-1] if all(score >= scorer(h, community_cards_full)[-1] for h in opponent_holdings): n_wins += 1 return n_wins / n_simulations