All notable changes to this project will be documented in this file.
Changed
- Update PokerStars parser format to accept bounty logs.
Changed
- Update PokerStars parser format to accept tournament logs.
Changed
- Update PokerStars parser format to accept the latest logs.
This version release introduces backward incompatible changes. Please read the below content carefully!
Changed
- Rename
pokerkit.state.State.stander_pat_or_discarder_indextopokerkit.state.State.stand_patter_or_discarder_index.
Added
- New pre-defined variants:
- Added
pokerkit.games.KuhnPoker. - Added
pokerkit.games.RhodeIslandHoldem. - Added
pokerkit.games.RoyalHoldemMixin. - Added
pokerkit.games.RoyalRhodeIslandHoldem.
- Added
- New hand types:
- Added
pokerkit.hands.RhodeIslandHoldemHand. - Added
pokerkit.lookups.RhodeIslandHoldemLookup.
- Added
- New helper attributes:
- Added
pokerkit.state.State.folded_status. - Added
pokerkit.state.State.total_pushed_amount.
- Added
Bugfixes
ZeroDivisionErrorwhen non-standard folds are performed in all-in pots (cash-game mode only).- Incorrect opener index in heads-up when blinds are
[0, 2].
Changed
- Add trailing period
'.'to some warning messages. - Enforce correct card burning/dealing sequence in bomb pots and Courchevel: hole dealing -> card burning -> board dealing.
Changed
- Set default
deal_countparameter forpokerkit.state.State.get_dealable_cardsto0to prevent confusion since previous default ofNonedenoted arbitrary number of dealings which also fetches the reserved cards. This caused some confusion among users. - Add
warning_statusparameter forpokerkit.state.State.get_dealable_cardsto silence newly added warnings when passingNoneasdeal_count. - Warn when users pass
Noneasdeal_countparameter topokerkit.state.State.get_dealable_cards. - Update PokerStars winnings pattern to make it compatible with newer hand histories.
Changed
- Implement another exception to Rule 96 of the 2024 WSOP Tournament Rules. The rule states that "An all-in wager of less than a full raise does not reopen the betting to a Participant who has already acted." However, it is reasonable to interpret this rule as saying that a full raise turns all non-all-in players into participants who have not yet acted. For more information, please take a look at the corresponding unit test method of this rule.
Added
- No-limit royal hold'em pre-defined variant
pokerkit.games.NoLimitRoyalHoldem. - Royal poker deck
pokerkit.utilities.Deck.ROYAL_POKER. - Royal poker rank ordering
pokerkit.utilities.RankOrder.ROYAL_POKER.
Changed
- Implement Rule 96 and 96a (its exception) of the 2024 WSOP Tournament Rules which states the following: "In no-limit and pot-limit, all raises must be equal to or greater than the size of the previous bet or raise on that betting round. An all-in wager of less than a full raise does not reopen the betting to a Participant who has already acted." The exception to this rule is triggered when "two or more consecutive all-in wagers that exceed the minimum allowable bet or raise." I would like to thank Phenom Poker for reporting this issue.
This version release introduces backward incompatible changes. Please read the below content carefully!
Added
- Parsing hands from logs of online poker rooms/research environments. The testing has been limited to old data and is known to fail to parse certain hands. Please open an issue if you find incompatibilities. I would be happy to support them.
- Absolute Poker:
pokerkit.notation.HandHistory.from_absolute_poker()viapokerkit.notation.AbsolutePokerParser. - Full Tilt Poker:
pokerkit.notation.HandHistory.from_full_tilt_poker()viapokerkit.notation.FullTiltPokerParser. - iPoker Network:
pokerkit.notation.HandHistory.from_ipoker_network()viapokerkit.notation.IPokerNetworkParser. - Ongame Network:
pokerkit.notation.HandHistory.from_ongame_network()viapokerkit.notation.OngameNetworkParser. - PartyPoker:
pokerkit.notation.HandHistory.from_partypoker()viapokerkit.notation.PartyPokerParser. - PokerStars:
pokerkit.notation.HandHistory.from_pokerstars()viapokerkit.notation.PokerStarsParser. - Annual Computer Poker Competition:
pokerkit.notation.HandHistory.from_acpc_protocol()viapokerkit.notation.ACPCProtocolParser.
- Absolute Poker:
- Base classes for hand history log parser using regular expressions like
pokerkit.notation.Parserandpokerkit.notation.REParser. pokerkit.utilities.Card.UNKNOWNstatic variable as a constant for a card with unknown rank and suit.- Pending additions of the PHH specification are also added in
pokerkit.notation.HandHistory. Namely, the new fieldspokerkit.notation.HandHistory.venue,pokerkit.notation.HandHistory.time_zone_abbreviation,pokerkit.notation.HandHistory.winnings, andpokerkit.notation.HandHistory.currency_symbol. - A helper unmatchable regular expression pattern
pokerkit.utilities.UNMATCHABLE_PATTERN. - Helper methods
pokerkit.utilities.rotated,pokerkit.utilities.parse_time, andpokerkit.utilities.parse_month.
Changed
pokerkit.state.ChipsPushing'sboard_indexandhand_indexattributes will beNonewhen the hands terminate due to every player except one folding. Previously,-1was used to denote as such.- Automatic repair of broken hand histories during iteration.
- Allow non-standard folds (i.e. folding even when you don't need to) in a cash-game mode.
- Allow showing the hole cards of the last remaining player after everyone folds around.
- Allow only showing a part of a player's hand.
- Only available in the cash-game mode.
- A player may want to keep cards face-down (even in all-in situations or final showdown).
- Simply pass in something like
??Asor an empty iterable topokerkit.state.State.show_or_muck_hole_cards().- If an empty iterable is passed in or all passed cards are unknown (i.e.
??), all hole cards of the current showdown player will stay face down. - If known cards are among the passed cards, the known cards will become face-up while all others will stay face-down.
- If an empty iterable is passed in or all passed cards are unknown (i.e.
pokerkit.utilities.Cardinstances are truthy or falsy depending on the Boolean value ofpokerkit.utilities.Card.unknown_status.- Pending additions of the PHH specification is also added in
pokerkit.notation.HandHistory. Namely, the widening of types forpokerkit.notation.HandHistory.handandpokerkit.notation.HandHistory.table. - Commas are handled
pokerkit.utilities.Card.parseandpokerkit.utilities.parse_value. "10"is now a valid way to express the rank of 10 for cards inpokerkit.utilities.Card.parse.pokerkit.utilities.parse_valuereturnsdecimal.Decimalfor decimal values instead offloat, as it used to. If integral, it returnsintas it used to.- Cleaned up docstrings or fixed docstring inaccuracies.
- Fix inaccurate error messages.
- Fix error raised during equity calculation when no valid hand can be formed.
Removed
- The previously deprecated
pokerkit.notation.HandHistory.iter_state_actions(). This was deprecated and renamed topokerkit.notation.HandHistory.state_actionsin Version 0.5.4.
Added
- Post bet support.
- Post bets are a type of forced bet which a player who just seated must pay to play right away instead of waiting for the button to pass.
- To denote a post bet, it must be passed alongside
raw_blinds_or_straddlesvariable during state construction.- For example, say UTG+1 wants to put a post-bet in a 6-max game. Then,
[1, 2, 0, -2, 0, 0]or, equivalently,{0: 1, 1: 2, 3: -2}.
- For example, say UTG+1 wants to put a post-bet in a 6-max game. Then,
pokerkit.notation.HandHistory.state_actionsis a new alias forpokerkit.notation.HandHistory.iter_state_actions().
Deprecated
pokerkit.notation.HandHistory.iter_state_actions()due to poor naming. It is superceded bypokerkit.notation.HandHistory.state_actionswhich behaves identically. This method will be removed in PokerKit Version 0.6.
Changed
- Fix incorrect implementation of
pokerkit.hands.StandardBadugi.from_game.
Changed
- Allow
numbers.Numberlikedecimal.Decimalto be used as chip values. While documented as allowed, usage of non-intor non-floatused to result in error. - The main pot is pushed first, followed by side pots (reverse was true previously).
- Chips pushing operation is more fine-grained in that each operation pushes a portion of the main/side pot should there be multiple boards or hand types.
- Removed
pokerkit.state.ChipsPushing.raked_amountattribute. - Removed
pokerkit.state.ChipsPushing.unraked_amountproperty.
Added
- Added
pokerkit.state.ChipsPushing.pot_index,pokerkit.state.ChipsPushing.board_index, andpokerkit.state.ChipsPushing.hand_type_indexattributes to provide information on what portion of the pot was pushed. - Added ICM calculation
pokerkit.analysis.calculate_icmfunction.
Added
- Add standard error property
pokerkit.analysis.Statistics.payoff_stderrto statistics.
This version release introduces a number of backward incompatible changes. Please read the below content carefully!
Summary of changes
- Minor cleanup that may break older code.
- Option to choose cash-game vs. tournament (default) mode (defaults to tournament mode).
- Unlike in tourneys, in cash-games, players can select the number of runouts during all-in situations.
- Option to choose the number of runouts during all-in situations (disabled in tournament mode).
- In theory, people choose number of runouts before they show their hands. But, this isn't always followed. It is also unclear who must select the number of runouts first. As such, after all-in, when showdown takes place,
- Multi-board games.
- More degree of freedom in hole dealing/showdown order.
- Docstring and documentation overhaul.
- Unknown starting stacks can be expressed with
math.inf. - More flexible raking system.
Changed
- The parameters
divmod, andrakefor relevant poker game/state initialization methods are now keyword-only arguments. Before, one could supply them as positional arguments but this is no longer allowed! pokerkit.state.State.board_cards(previouslylist[Card]) is now of typelist[list[Card]].- For example, if an all-in happens on the flop (AsKsQs) and is run twice (JsTs, JhTh),
state.board_cards == [[As], [Ks], [Qs], [Js, Jh], [Ts, Th]]. Or, when double board omaha is played, something likestate.board_cards == [[??, ??], [??, ??], [??, ??]]will develop after the flop. - The function signatures for
pokerkit.state.State.get_hand,pokerkit.state.State.get_up_hand, andpokerkit.state.State.get_up_handsnow also requires theboard_indexto be supplied. - The properties/method
pokerkit.state.State.reserved_cards,pokerkit.state.State.cards_in_play,pokerkit.state.State.cards_not_in_play, andpokerkit.state.State.get_dealable_cards(deal_count: int)now returnIterator[Card]instead oftuple[Card, ...]. - The method triplets for the hole dealing and showdown operation
pokerkit.state.State.verify_hole_dealing(),pokerkit.state.State.can_deal_hole(),pokerkit.state.State.deal_hole(),pokerkit.state.State.verify_hole_cards_showing_or_mucking(),pokerkit.state.State.can_show_or_muck_hole_cards(), andpokerkit.state.State.show_or_muck_hole_cards()also accepts an optional positional argumentplayer_indexto control the dealee, or the showdown performer. The verifiers also returns a player dealt if the dealee is not specified.
- For example, if an all-in happens on the flop (AsKsQs) and is run twice (JsTs, JhTh),
- The card-burning-related methods
pokerkit.state.State.verify_card_burning,pokerkit.state.State.can_burn_card, andpokerkit.state.State.burn_cardalso accept a singleton card iterable. - The
pokerkit.state.State.all_in_show_statuswas renamed topokerkit.state.State.all_in_status. - Renamed
pokerkit.state.ChipsPushing.raketopokerkit.state.ChipsPushing.raked_amount. - The attribute
pokerkit.state.Pot.amountis now a property and no longer a parameter during initialization.
Added
- New enum class
pokerkit.state.State.Modefor setting tournament/cash-game mode while initializing poker states.- Tournament mode:
pokerkit.state.Mode.TOURNAMENT - Cash-game mode:
pokerkit.state.Mode.CASH_GAME- In all-in situations, players have a chance to choose the number of runouts during showdown.
- Tournament mode:
- New parameter
modein relevant poker game/state initialization methods. It defaults to tournament mode. - New parameter
starting_board_countin relevant poker game/state initialization methods. It defaults to1. This allow multiple boards to be dealt if wished. - New automation
pokerkit.state.State.Automation.RUNOUT_COUNT_SELECTIONwhich instructs PokerKit to carry out only one run-out. - New
pokerkit.state.RunoutCountSelectionoperation.- Arguments:
runout_countandplayer_indexwho gives out the selection. - Querier:
pokerkit.state.State.can_select_runout_count(player_index: int | None = None, runout_count: int | None = None). - Validator:
pokerkit.state.State.verify_runout_count_selection(player_index: int | None = None, runout_count: int | None = None). - Operator:
pokerkit.state.State.select_runout_count(player_index: int | None = None, runout_count: int | None = None, *, commentary: str | None = None). - People who can select run count:
pokerkit.state.State.runout_count_selector_indices. - If
runout_countare in disagreement among active players, only1runout is performed. - When multiple runs are selected, the state will be incompatible with the PHH file format, as it stands.
- Arguments:
- New attributes
pokerkit.state.State.street_return_indexandpokerkit.state.State.street_return_countthat internally keeps track what street to return to and how many times to do so during multiple runouts. - New attribute
pokerkit.state.State.runout_countthat shows the players' preferences on the number of runouts. It maybeNonein which case the runout selection was skipped due to the state being of tournament mode or all players showed no preference by passing inNone(or leaving empty) for therunout_countargument during the corresponding method call ofpokerkit.state.select_runout_count(). - New attributes
pokerkit.state.State.board_countandpokerkit.state.State.board_indiceson the number of boards and the range of its indices. The number of boards is at least1but may be more due to multiple runouts or the variant being played. - New method
pokerkit.state.State.get_board_cards(board_index: int)on getting theboard_index'th board.- The maximum number of boards is either equal to the number of boards of the variant or (in case of multiple runouts) the product of it and the number of runouts.
- New attribute
pokerkit.state.State.runout_count_selector_statusesthat keeps track of who can select the number of runouts. - New attribute
pokerkit.state.State.runout_count_selection_flagthat keeps track of whether the runout count selection has been carried out. - In
pokerkit.utilities.rake, added parametersstate,cap, andno_flop_no_drop, andrakeis now renamed aspercentageand is a keyword parameter. - New attributes
pokerkit.state.Pot.raked_amountandpokerkit.state.Pot.unraked_amountthat gives the raked and the unraked amounts of the pot. - New property
pokerkit.state.ChipsPushing.unraked_amount. - New attribute
pokerkit.state.payoffsfor keeping track of payoffs (rewards).
Changed
- Make error/warning messages more descriptive.
Added
- Censored hole cards
pokerkit.state.State.get_censored_hole_cards(). - Turn index
pokerkit.state.State.turn_index.
Added
- Restore action notation
pn sm -for showing hole cards.
Added
- Raise error for ACPC protocol converter when hole cards unknown.
- PHH to Pluribus protocol converter.
Added
- Analysis module
- Range parser
pokerkit.analysis.parse_range(e.g."AKs,T8o-KJo,6h5h,A2+"). - Equity calculator
pokerkit.analysis.calculate_equities. - Hand strength calculator
pokerkit.analysis.calculate_hand_strength. - Player statistics
pokerkit.analysis.Statistics.
- Range parser
Changed
- Renamed
pokerkit.state.State.all_in_show_statustopokerkit.state.State.all_in_status.
Added
pokerkit.state.State.reserved_cardspokerkit.state.State.cards_in_playpokerkit.state.State.cards_not_in_play
Removed
- Remove non-compliant action notation
pn sm -for showing hole cards.
Added
- Commentary for state actions.
- User-defined field support for PHH.
- PHH to ACPC protocol converter
Added
- Deuce-to-seven badugi hand lookup/evaluator.
Added
pokerkit.state.State.pot_amountsfor iterating through main/side pot amounts.
Changed
- Forbid showdown without specifying cards if unknown hole cards are dealt.
Changed
- New field
rakeforpokerkit.notation.HandHistorywhen constructing games/states.
Changed
- New action notation
pn sm -for showing hole cards. pokerkit.notation.HandHistory.iter_state_actionsfor iterating through states with actions.
Changed
- If there are multiple pots (main + side),
pokerkit.state.State.push_chipsmust be called multiple times. - Custom automations are passed through the constructor for
pokerkit.notation.HandHistory. - Support rakes.
Changed
- Collapse pots (main + side) that have the same players in the
pokerkit.state.State.potsproperty. - Allow default automations to be overridden in
pokerkit.notation.HandHistory.create_gameandpokerkit.notation.HandHistory.create_game.
Changed
- Fix incorrect type annotation for class attribute
optional_field_namesinoptional_field_namesin``pokerkit.notation.HandHistory``. - Operation queries also catch
UserWarning.
Added
- Add class attributes
game_field_namesandignored_field_namestopokerkit.notation.HandHistory.
Changed
- Remove class attributes
game_field_namesandignored_field_namesfrompokerkit.notation.HandHistory
Added
- The new .phh optional fields:
time_zone
Added
- New .phh optional fields:
time,time_limit,time_banks,level.
Added
- New .phh optional fields:
url,city,region,postal_code,country.
Changed
ante_trimming_statusis now an optional field for .phh files.
Changed
- When not enough cards to deal everybody's hole cards, a board dealing is done.
- Showdown can specify what cards the player showed.
- More generous state operations when it comes to cards. Some things that were errors are now warnings.
- When all-in, cards are shown via
show_or_muck_hole_cards. Noneis no longerValuesLikeorCardsLike.
Added
- Cards with unknown rank or suit.
floatcompatibility (without static typing support).- Poker action notation support.
- Poker hand history file format (.phh) support.
Changed
- When saving state configuration,
player_countis not saved.
Added
- Allow state configuration to be saved.
Changed
- Call
unittest.mainin unit test files when executed as__main__. - Move the
automationsparameter to be the first parameter ofpokerkit.state.State.
Changed
- Make
pokerkit.state.Operationavailable aspokerkit.Operationby importing it inpokerkit.__init__.
Changed
- Limit the maximum number of completions, bets, or raises to 4 in the pre-configured Fixed-limit deuce-to-seven triple draw and Fixed-limit badugi variants.
- Flip antes just like blinds during heads-up play (in the case of big blind antes).
- Also reshuffle all discarded cards (including from the current draw round) along with mucked and burned cards when the deck runs out. Previously, discarded cards from the same draw round was excluded.
- Rename
pokerkit.state.State.verify_card_availability_makingtopokerkit.state.State.verify_cards_availability_making.
Added
- Add more unit tests and doctests to achieve 99% code coverage.
Bugfixes
- Fix
AssertionErrorbeing raised in certain scenarios after discards are made when the state was configured to automatically deal with hole cards.
Changed
- When the dealer deals hole cards after standing pat or discarding, an explicit
ValueErroris raised unless every player has stood pat or discarded.
Added
pokerkit.state.Operationabstract base class for all operation classes.pokerkit.utilities.shuffledhelper function.pokerkit.state.State.discarded_cardsto keep track of discarded cards.pokerkit.state.State.street_countproperty.pokerkit.state.State.street_indicesproperty.
Changed
pokerkit.state.Statenow also acceptspokerkit.utilities.ValuesLikeinstances as arguments for various parameters.pokerkit.state.Staterequiresplayer_countargument to be passed during initialization.- Various operation classes such as
pokerkit.state.State.AntePostingmoved topokerkit.stateand is no longer a nested class ofpokerkit.state.State. - Renamed
pokerkit.lookups.RegularLowLookuptopokerkit.lookups.RegularLookupfor enhanced consistency. - Renamed
pokerkit.state.State.burned_cardstopokerkit.state.State.burn_cards. - Renamed
pokerkit.state.State.verify_card_availabilitiestopokerkit.state.State.verify_card_availability_making. - Changed the property
pokerkit.state.State.available_cardsto methodpokerkit.state.State.get_available_cards. - Cards can be dealt from the mucked cards or burn cards if the deck is empty.
- Warning is printed if cards are dealt from burn cards without any good reason.
Added
- Introduce
pokerkit.utilities.CardsLikeandpokerkit.utilities.ValuesLiketype aliases to simplify type annotations of various methods.
Changed
- Modify the methods that only accept an iterable of
Cardso they can accept any card-like object. - Make the protected attributes of the instances of the
Handtype and its descendants public. - Move
pokerkit.state.State._clean_cardsandpokerkit.games.Game._clean_valuestopokerkit.utilities.
Initial Release