clubs.poker package¶
Submodules¶
clubs.poker.card module¶
Classes and functions to create and manipulate cards and lists of cards from a standard 52 card poker deck
-
class
clubs.poker.card.
Card
(string: str)[source]¶ Bases:
object
Cards are represented as 32-bit integers. Most of the bits are used and have a specific meaning.
bitrank
suit
rank
prime
xxxbbbbbbbbbbbbb
cdhs
rrrr
xxpppppp
p = prime number of rank (deuce=2,trey=3,four=5,…,ace=41)
r = rank of card (deuce=0,trey=1,four=2,five=3,…,ace=12)
cdhs = suit of card (bit turned on based on suit of card)
b = bit turned on depending on rank of card
x = unused
- Parameters
string (str) – card string of format ‘{rank}{suit}’ where rank is from [2-9, T/t, J/j, Q/q, K/k, A/a] and suit is from [S/s, H/h, D/d, C/c]
Examples
>>> card = Card('TC') >>> card = Card('7H') >>> card = Card('ad')
-
class
clubs.poker.card.
Deck
(num_suits: int, num_ranks: int)[source]¶ Bases:
object
A deck contains at most 52 cards, 13 ranks 4 suits. Any “subdeck” of the standard 52 card deck is valid, i.e. the number of suits must be between 1 and 4 and number of ranks between 1 and 13. A deck can be tricked to ensure a certain order of cards.
- Parameters
num_suits (int) – number of suits to use in deck
num_ranks (int) – number of ranks to use in deck
-
draw
(n: int = 1) → List[clubs.poker.card.Card][source]¶ Draws cards from the top of the deck. If the number of cards to draw exceeds the number of cards in the deck, all cards left in the deck are returned.
- Parameters
n (int, optional) – number of cards to draw, by default 1
- Returns
cards drawn from the deck
- Return type
List[Card]
-
shuffle
() → clubs.poker.card.Deck[source]¶ Shuffles the deck. If a tricking order is given, the desired cards are placed on the top of the deck after shuffling.
- Returns
self
- Return type
-
trick
(top_cards: List[clubs.poker.card.Card]) → clubs.poker.card.Deck[source]¶ Tricks the deck by placing a fixed order of cards on the top of the deck and shuffling the rest. E.g. deck.trick([Card(‘AS’), Card(‘2H’)]) places the ace of spades and deuce of hearts on the top of the deck.
-
untrick
() → clubs.poker.card.Deck[source]¶ Removes the tricked cards from the top of the deck.
- Returns
self
- Return type
clubs.poker.engine module¶
Classes and functions for running poker games
-
class
clubs.poker.engine.
Dealer
(num_players: int, num_streets: int, blinds: Union[int, List[int]], antes: Union[int, List[int]], raise_sizes: Union[float, str, List[Union[float, str]]], num_raises: Union[float, List[float]], num_suits: int, num_ranks: int, num_hole_cards: int, num_community_cards: Union[int, List[int]], num_cards_for_hand: int, mandatory_num_hole_cards: int, start_stack: int, low_end_straight: bool = True, order: Optional[List[str]] = None)[source]¶ Bases:
object
Runs a range of different of poker games dependent on the given configuration. Supports limit, no limit and pot limit bet sizing, arbitrary deck sizes, arbitrary hole and community cards and many other options.
- Parameters
num_players (int) – maximum number of players
num_streets (int) – number of streets including preflop, e.g. for texas hold’em num_streets=4
blinds (Union[int, List[int]]) – blind distribution as a list of ints, one for each player starting from the button e.g. [0, 1, 2] for a three player game with a sb of 1 and bb of 2, passed ints will be expanded to all players i.e. pass blinds=0 for no blinds
antes (Union[int, List[int]]) – ante distribution as a list of ints, one for each player starting from the button e.g. [0, 0, 5] for a three player game with a bb ante of 5, passed ints will be expanded to all players i.e. pass antes=0 for no antes
raise_sizes (Union[float, str, List[Union[float, str]]]) – max raise sizes for each street, valid raise sizes are ints, floats, and ‘pot’, e.g. for a 1-2 limit hold’em the raise sizes should be [2, 2, 4, 4] as the small and big bet are 2 and 4. float(‘inf’) can be used for no limit games. pot limit raise sizes can be set using ‘pot’. if only a single int, float or string is passed the value is expanded to a list the length of number of streets, e.g. for a standard no limit game pass raise_sizes=float(‘inf’)
num_raises (Union[float, List[float]]) – max number of bets for each street including preflop, valid raise numbers are ints and floats. if only a single int or float is passed the value is expanded to a list the length of number of streets, e.g. for a standard limit game pass num_raises=4
num_suits (int) – number of suits to use in deck, must be between 1 and 4
num_ranks (int) – number of ranks to use in deck, must be between 1 and 13
num_hole_cards (int) – number of hole cards per player, must be greater than 0
num_community_cards (Union[int, List[int]]) – number of community cards per street including preflop, e.g. for texas hold’em pass num_community_cards=[0, 3, 1, 1]. if only a single int is passed, it is expanded to a list the length of number of streets
num_cards_for_hand (int) – number of cards for a valid poker hand, e.g. for texas hold’em num_cards_for_hand=5
mandatory_num_hole_cards (int) – number of hole cards which have to be used for the hand, e.g. for pot limit omaha mandatory_num_hole_cards=2
start_stack (int) – number of chips each player starts with
low_end_straight (bool, optional) – toggle to include the low ace straight within valid hands, by default True
order (Optional[List[str]], optional) – optional custom order of hand ranks, must be permutation of [‘sf’, ‘fk’, ‘fh’, ‘fl’, ‘st’, ‘tk’, ‘tp’, ‘pa’, ‘hc’]. if order=None, hands are ranked by rarity. by default None
Examples
>>> Dealer( # 1-2 Heads Up No Limit Texas Hold'em ... num_players=2, num_streets=4, blinds=[1, 2], antes=0, ... raise_sizes=float('inf'), num_raises=float('inf'), ... num_suits=4, num_ranks=13, num_hole_cards=2, ... mandatory_num_hole_cards=0, start_stack=200 ... ) >>> Dealer( # 1-2 6 Player PLO ... num_players=6, num_streets=4, blinds=[0, 1, 2, 0, 0, 0], ... antes=0, raise_sizes='pot', num_raises=float('inf'), ... num_suits=4, num_ranks=13, num_hole_cards=4, ... mandatory_num_hole_cards=2, start_stack=200 ... ) >>> Dealer( # 1-2 Heads Up No Limit Short Deck ... num_players=2, num_streets=4, blinds=[1, 2], antes=0, ... raise_sizes=float('inf'), num_raises=float('inf'), ... num_suits=4, num_ranks=9, num_hole_cards=2, ... mandatory_num_hole_cards=0, start_stack=200, ... order=[ ... 'sf', 'fk', 'fl', 'fh', 'st', ... 'tk', 'tp', 'pa', 'hc' ... ] ... )
-
render
(mode: str = 'human', sleep: float = 0, **kwargs)[source]¶ Renders poker table. Render mode options are: ascii, human
- Parameters
mode (str, optional) – toggle for using different renderer, by default ‘human’
-
reset
(reset_button: bool = False, reset_stacks: bool = False) → Dict[source]¶ Resets the table. Shuffles the deck, deals new hole cards to all players, moves the button and collects blinds and antes.
- Parameters
reset_button (bool, optional) – reset button to first position at table, by default False
reset_stacks (bool, optional) – reset stack sizes to starting stack size, by default False
- Returns
observation dictionary
- Return type
Dict
Examples
>>> dealer = Dealer(**configs.LEDUC_TWO_PLAYER) >>> dealer.reset() ... {'action': 1, ... 'active': [True, True], ... 'button': 1, ... 'call': 0, ... 'community_cards': [], ... 'hole_cards': [[Card (139879188163600): A♥], [Card (139879188163504): A♠]], ... 'max_raise': 2, ... 'min_raise': 2, ... 'pot': 2, ... 'stacks': [9, 9], ... 'street_commits': [0, 0]}
-
step
(bet: float) → Tuple[Dict, List[int], List[int]][source]¶ Advances poker game to next player. If the bet is 0, it is either considered a check or fold, depending on the previous action. The given bet is always rounded to the closest valid bet size. When it is the same distance from two valid bet sizes the smaller bet size is used, e.g. if the min raise is 10 and the bet is 5, it is rounded down to 0.
- Parameters
bet (int) – number of chips bet by player currently active
- Returns
observation dictionary, payouts for every player, boolean value for every player showing if that player is still active in the round
- Return type
Tuple[Dict, List[int], List[int]]
Examples
>>> dealer = Dealer(**configs.LEDUC_TWO_PLAYER) >>> obs = dealer.reset() >>> dealer.step(0) ... ({'action': 0, ... 'active': [True, True], ... 'button': 1, ... 'call': 0, ... 'community_cards': [], ... 'hole_cards': [[Card (139879188163600): A♥], [Card (139879188163504): A♠]], ... 'max_raise': 2, ... 'min_raise': 2, ... 'pot': 2, ... 'stacks': [9, 9], ... 'street_commits': [0, 0]}, ... [0, 0], ... [False, False])
-
win_probabilities
(n: int = 10000) → List[float][source]¶ Computes win probabilities for each player. If the possible remaining community card combinations are below 1000, the combinations are exhaustively checked, otherwise, n random samples are taken and averaged to compute an estimate of the win probabilities.
- Parameters
n (int, optional) – max number of iterations to approximate win probabilities, by default 10000
- Returns
win probabilities
- Return type
List[float]
clubs.poker.evaluator module¶
Classes and functions to evaluate poker hands
-
class
clubs.poker.evaluator.
Evaluator
(suits: int, ranks: int, cards_for_hand: int, mandatory_hole_cards: int = 0, low_end_straight: bool = True, order: Optional[list] = None)[source]¶ Bases:
object
Evalutes poker hands using hole and community cards
- Parameters
suits (int) – number of suits in deck
ranks (int) – number of ranks in deck
cards_for_hand (int) – number of cards used for valid poker hand
mandatory_hole_cards (int, optional) – number of hole cards which must be used for a hands, by default 0
low_end_straight (bool, optional) – toggle to include the low ace straight within valid hands, by default True
order (list, optional) – optional custom order of hand ranks, must be permutation of [‘sf’, ‘fk’, ‘fh’, ‘fl’, ‘st’, ‘tk’, ‘tp’, ‘pa’, ‘hc’]. if order=None, hands are ranked by rarity. by default None
-
evaluate
(hole_cards: List[clubs.poker.card.Card], community_cards: List[clubs.poker.card.Card]) → int[source]¶ Evaluates the hand rank of a poker hand from a list of hole and a list of community cards. Empty hole and community cards are supported as well as requiring a minimum number of hole cards to be used.
-
class
clubs.poker.evaluator.
LookupTable
(suits: int, ranks: int, cards_for_hand: int, low_end_straight: bool = True, order: Optional[List[str]] = None)[source]¶ Bases:
object
Lookup table maps unique prime product of hands to unique integer hand rank. The lower the rank the better the hand
- Parameters
suits (int) – number of suits in deck
ranks (int) – number of ranks in deck
cards_for_hand (int) – number of cards used for a poker hand
low_end_straight (bool, optional) – toggle to include straights where ace is the lowest card, by default True
order (List[str], optional) – custom hand rank order, if None hands are ranked by rarity, by default None
-
ORDER_STRINGS
= ['sf', 'fk', 'fh', 'fl', 'st', 'tk', 'tp', 'pa', 'hc']¶
-
lookup
(cards: List[clubs.poker.card.Card]) → int[source]¶ Return unique hand rank for list of cards
- Parameters
cards (List[card.Card]) – list of cards to be evaluated
- Returns
hand rank
- Return type
int
Module contents¶
-
class
clubs.poker.
Card
(string: str)[source]¶ Bases:
object
Cards are represented as 32-bit integers. Most of the bits are used and have a specific meaning.
bitrank
suit
rank
prime
xxxbbbbbbbbbbbbb
cdhs
rrrr
xxpppppp
p = prime number of rank (deuce=2,trey=3,four=5,…,ace=41)
r = rank of card (deuce=0,trey=1,four=2,five=3,…,ace=12)
cdhs = suit of card (bit turned on based on suit of card)
b = bit turned on depending on rank of card
x = unused
- Parameters
string (str) – card string of format ‘{rank}{suit}’ where rank is from [2-9, T/t, J/j, Q/q, K/k, A/a] and suit is from [S/s, H/h, D/d, C/c]
Examples
>>> card = Card('TC') >>> card = Card('7H') >>> card = Card('ad')
-
class
clubs.poker.
Dealer
(num_players: int, num_streets: int, blinds: Union[int, List[int]], antes: Union[int, List[int]], raise_sizes: Union[float, str, List[Union[float, str]]], num_raises: Union[float, List[float]], num_suits: int, num_ranks: int, num_hole_cards: int, num_community_cards: Union[int, List[int]], num_cards_for_hand: int, mandatory_num_hole_cards: int, start_stack: int, low_end_straight: bool = True, order: Optional[List[str]] = None)[source]¶ Bases:
object
Runs a range of different of poker games dependent on the given configuration. Supports limit, no limit and pot limit bet sizing, arbitrary deck sizes, arbitrary hole and community cards and many other options.
- Parameters
num_players (int) – maximum number of players
num_streets (int) – number of streets including preflop, e.g. for texas hold’em num_streets=4
blinds (Union[int, List[int]]) – blind distribution as a list of ints, one for each player starting from the button e.g. [0, 1, 2] for a three player game with a sb of 1 and bb of 2, passed ints will be expanded to all players i.e. pass blinds=0 for no blinds
antes (Union[int, List[int]]) – ante distribution as a list of ints, one for each player starting from the button e.g. [0, 0, 5] for a three player game with a bb ante of 5, passed ints will be expanded to all players i.e. pass antes=0 for no antes
raise_sizes (Union[float, str, List[Union[float, str]]]) – max raise sizes for each street, valid raise sizes are ints, floats, and ‘pot’, e.g. for a 1-2 limit hold’em the raise sizes should be [2, 2, 4, 4] as the small and big bet are 2 and 4. float(‘inf’) can be used for no limit games. pot limit raise sizes can be set using ‘pot’. if only a single int, float or string is passed the value is expanded to a list the length of number of streets, e.g. for a standard no limit game pass raise_sizes=float(‘inf’)
num_raises (Union[float, List[float]]) – max number of bets for each street including preflop, valid raise numbers are ints and floats. if only a single int or float is passed the value is expanded to a list the length of number of streets, e.g. for a standard limit game pass num_raises=4
num_suits (int) – number of suits to use in deck, must be between 1 and 4
num_ranks (int) – number of ranks to use in deck, must be between 1 and 13
num_hole_cards (int) – number of hole cards per player, must be greater than 0
num_community_cards (Union[int, List[int]]) – number of community cards per street including preflop, e.g. for texas hold’em pass num_community_cards=[0, 3, 1, 1]. if only a single int is passed, it is expanded to a list the length of number of streets
num_cards_for_hand (int) – number of cards for a valid poker hand, e.g. for texas hold’em num_cards_for_hand=5
mandatory_num_hole_cards (int) – number of hole cards which have to be used for the hand, e.g. for pot limit omaha mandatory_num_hole_cards=2
start_stack (int) – number of chips each player starts with
low_end_straight (bool, optional) – toggle to include the low ace straight within valid hands, by default True
order (Optional[List[str]], optional) – optional custom order of hand ranks, must be permutation of [‘sf’, ‘fk’, ‘fh’, ‘fl’, ‘st’, ‘tk’, ‘tp’, ‘pa’, ‘hc’]. if order=None, hands are ranked by rarity. by default None
Examples
>>> Dealer( # 1-2 Heads Up No Limit Texas Hold'em ... num_players=2, num_streets=4, blinds=[1, 2], antes=0, ... raise_sizes=float('inf'), num_raises=float('inf'), ... num_suits=4, num_ranks=13, num_hole_cards=2, ... mandatory_num_hole_cards=0, start_stack=200 ... ) >>> Dealer( # 1-2 6 Player PLO ... num_players=6, num_streets=4, blinds=[0, 1, 2, 0, 0, 0], ... antes=0, raise_sizes='pot', num_raises=float('inf'), ... num_suits=4, num_ranks=13, num_hole_cards=4, ... mandatory_num_hole_cards=2, start_stack=200 ... ) >>> Dealer( # 1-2 Heads Up No Limit Short Deck ... num_players=2, num_streets=4, blinds=[1, 2], antes=0, ... raise_sizes=float('inf'), num_raises=float('inf'), ... num_suits=4, num_ranks=9, num_hole_cards=2, ... mandatory_num_hole_cards=0, start_stack=200, ... order=[ ... 'sf', 'fk', 'fl', 'fh', 'st', ... 'tk', 'tp', 'pa', 'hc' ... ] ... )
-
render
(mode: str = 'human', sleep: float = 0, **kwargs)[source]¶ Renders poker table. Render mode options are: ascii, human
- Parameters
mode (str, optional) – toggle for using different renderer, by default ‘human’
-
reset
(reset_button: bool = False, reset_stacks: bool = False) → Dict[source]¶ Resets the table. Shuffles the deck, deals new hole cards to all players, moves the button and collects blinds and antes.
- Parameters
reset_button (bool, optional) – reset button to first position at table, by default False
reset_stacks (bool, optional) – reset stack sizes to starting stack size, by default False
- Returns
observation dictionary
- Return type
Dict
Examples
>>> dealer = Dealer(**configs.LEDUC_TWO_PLAYER) >>> dealer.reset() ... {'action': 1, ... 'active': [True, True], ... 'button': 1, ... 'call': 0, ... 'community_cards': [], ... 'hole_cards': [[Card (139879188163600): A♥], [Card (139879188163504): A♠]], ... 'max_raise': 2, ... 'min_raise': 2, ... 'pot': 2, ... 'stacks': [9, 9], ... 'street_commits': [0, 0]}
-
step
(bet: float) → Tuple[Dict, List[int], List[int]][source]¶ Advances poker game to next player. If the bet is 0, it is either considered a check or fold, depending on the previous action. The given bet is always rounded to the closest valid bet size. When it is the same distance from two valid bet sizes the smaller bet size is used, e.g. if the min raise is 10 and the bet is 5, it is rounded down to 0.
- Parameters
bet (int) – number of chips bet by player currently active
- Returns
observation dictionary, payouts for every player, boolean value for every player showing if that player is still active in the round
- Return type
Tuple[Dict, List[int], List[int]]
Examples
>>> dealer = Dealer(**configs.LEDUC_TWO_PLAYER) >>> obs = dealer.reset() >>> dealer.step(0) ... ({'action': 0, ... 'active': [True, True], ... 'button': 1, ... 'call': 0, ... 'community_cards': [], ... 'hole_cards': [[Card (139879188163600): A♥], [Card (139879188163504): A♠]], ... 'max_raise': 2, ... 'min_raise': 2, ... 'pot': 2, ... 'stacks': [9, 9], ... 'street_commits': [0, 0]}, ... [0, 0], ... [False, False])
-
win_probabilities
(n: int = 10000) → List[float][source]¶ Computes win probabilities for each player. If the possible remaining community card combinations are below 1000, the combinations are exhaustively checked, otherwise, n random samples are taken and averaged to compute an estimate of the win probabilities.
- Parameters
n (int, optional) – max number of iterations to approximate win probabilities, by default 10000
- Returns
win probabilities
- Return type
List[float]
-
class
clubs.poker.
Deck
(num_suits: int, num_ranks: int)[source]¶ Bases:
object
A deck contains at most 52 cards, 13 ranks 4 suits. Any “subdeck” of the standard 52 card deck is valid, i.e. the number of suits must be between 1 and 4 and number of ranks between 1 and 13. A deck can be tricked to ensure a certain order of cards.
- Parameters
num_suits (int) – number of suits to use in deck
num_ranks (int) – number of ranks to use in deck
-
draw
(n: int = 1) → List[clubs.poker.card.Card][source]¶ Draws cards from the top of the deck. If the number of cards to draw exceeds the number of cards in the deck, all cards left in the deck are returned.
- Parameters
n (int, optional) – number of cards to draw, by default 1
- Returns
cards drawn from the deck
- Return type
List[Card]
-
shuffle
() → clubs.poker.card.Deck[source]¶ Shuffles the deck. If a tricking order is given, the desired cards are placed on the top of the deck after shuffling.
- Returns
self
- Return type
-
trick
(top_cards: List[clubs.poker.card.Card]) → clubs.poker.card.Deck[source]¶ Tricks the deck by placing a fixed order of cards on the top of the deck and shuffling the rest. E.g. deck.trick([Card(‘AS’), Card(‘2H’)]) places the ace of spades and deuce of hearts on the top of the deck.
-
untrick
() → clubs.poker.card.Deck[source]¶ Removes the tricked cards from the top of the deck.
- Returns
self
- Return type
-
class
clubs.poker.
Evaluator
(suits: int, ranks: int, cards_for_hand: int, mandatory_hole_cards: int = 0, low_end_straight: bool = True, order: Optional[list] = None)[source]¶ Bases:
object
Evalutes poker hands using hole and community cards
- Parameters
suits (int) – number of suits in deck
ranks (int) – number of ranks in deck
cards_for_hand (int) – number of cards used for valid poker hand
mandatory_hole_cards (int, optional) – number of hole cards which must be used for a hands, by default 0
low_end_straight (bool, optional) – toggle to include the low ace straight within valid hands, by default True
order (list, optional) – optional custom order of hand ranks, must be permutation of [‘sf’, ‘fk’, ‘fh’, ‘fl’, ‘st’, ‘tk’, ‘tp’, ‘pa’, ‘hc’]. if order=None, hands are ranked by rarity. by default None
-
evaluate
(hole_cards: List[clubs.poker.card.Card], community_cards: List[clubs.poker.card.Card]) → int[source]¶ Evaluates the hand rank of a poker hand from a list of hole and a list of community cards. Empty hole and community cards are supported as well as requiring a minimum number of hole cards to be used.
-
class
clubs.poker.
LookupTable
(suits: int, ranks: int, cards_for_hand: int, low_end_straight: bool = True, order: Optional[List[str]] = None)[source]¶ Bases:
object
Lookup table maps unique prime product of hands to unique integer hand rank. The lower the rank the better the hand
- Parameters
suits (int) – number of suits in deck
ranks (int) – number of ranks in deck
cards_for_hand (int) – number of cards used for a poker hand
low_end_straight (bool, optional) – toggle to include straights where ace is the lowest card, by default True
order (List[str], optional) – custom hand rank order, if None hands are ranked by rarity, by default None
-
ORDER_STRINGS
= ['sf', 'fk', 'fh', 'fl', 'st', 'tk', 'tp', 'pa', 'hc']¶
-
lookup
(cards: List[clubs.poker.card.Card]) → int[source]¶ Return unique hand rank for list of cards
- Parameters
cards (List[card.Card]) – list of cards to be evaluated
- Returns
hand rank
- Return type
int