Game Information
TexasHoldEm Object
The TexasHoldEm class is the main class of the package which includes complete
functionality to play a game of tournament-style Texas Hold ‘Em.
Instantiate
To instantiate an instance, we only need to specify the buyin, big blind, and small blind with a default of 9 players:
game = TexasHoldEm(buyin=500, big_blind=5, small_blind=2)
Optionally, we can include the number of players:
game = TexasHoldEm(buyin=500, big_blind=5, small_blind=2, max_players=6)
Playing Hands
To start playing a hand all we need to call is the start_hand() method:
game.is_hand_running() == False
game.start_hand()
game.is_hand_running() == True
Behind the scenes, this method will reset all the pots, move and post the blinds, deal cards, reset the history, etc.
(To see the details, see the _prehand function
here.) We can see how many hands have been
played with the num_hands attribute.
Actions
To let the current player act we call the take_action() method.
For example, game.take_action(ActionType.CALL), or game.take_action(ActionType.RAISE, total=50)
for a raise action.
Available actions include CALL,
ALL_IN, RAISE,
FOLD, CHECK. See
ActionType.
Note
The take_action() takes two optional arguments
value and total that are mutually exclusive (both mean how much to raise to).
To facilitate translation between the two based on preference there are the
total_to_value() and
value_to_total() methods.
Warning
As of version 0.6, the value argument has been renamed to total. The
value argument will be redefined in 1.0. Currently, value and total
mean to raise to the amount given. In 1.0, value will mean to raise an amount more
than the current bet amount.
There is a method get_available_moves() to get an iterator (of type
MoveIterator) of all the possible moves for the current player. The
MoveIterator class includes a few attributes such as
action_types and raise_range.
Also supports iteration and checking for membership with the in operator. Use the
sample() method to sample from the collection.
Canonical Loop
Additionally, with the is_game_running() method (which determines if
the game can run any more hands), we now know enough to create a canonical loop (which loops until there is
only one winner). Try it out with one of the basic agents, call_agent() or
random_agent():
while game.is_game_running():
game.start_hand()
while game.is_hand_running():
action, total = random_agent(game)
print(f"Player {game.current_player} {action} {total}")
game.take_action(action, total=total)
General Information
The following notes important attributes. For a full list of attributes, see
TexasHoldEm.
Buyin & Blind Amounts
Most of the general information of the game are instance attributes of the class, including the
buyin, big_blind amount, and
small_blind amount.
Blind Locations & Current Player
Additionally, there is btn_loc,
sb_loc, bb_loc for the locations
of the blinds given as a number 0 through max_players which are seat / player ids
and current_player for the id of the current player.
Players
There is a players attribute for a list of
Player objects indexed by id. For a more curated list of players based on
PlayerState and other criteria there is:
active_iter()which is an iterator over player ids who can take an action (i.e. with a state ofINorTO_CALL).
in_pot_iter()which is an iterator over player ids who have a stake in the pot (i.e. with a state ofIN,TO_CALL, orALL_IN).
player_iter()which is a general iterator over ALL seats at the table and which allows you to exclude states with thefilter_statesargument or match states with thematch_statesargument.
All three of these methods also include arguments loc which is the player id to start at (defaults to
current_player) and reverse which will return the player ids in
reverse play order.
More player information can be found under Player Information.
Board & Pots
Further, there is board for a list of the communal cards
(See Cards). Along with pots which is a list
of Pot objects.
See Pot Information. Note: pot information is more advanced, less relevant, and most methods will probably be private and refactored in future versions.
Hand Phase & History
To get the current HandPhase, there is the
hand_phase attribute. See Hand Phases.
There is the hand_history attribute which is a
History object and details the entire history of the current hand so far and includes
methods to export / import to files. See Hand History.
Valid Actions
In a very specific scenario (made by WSOP Rule 96) which says that an all-in raise action does not reopen the
betting round, there is the raise_option attribute which
tells when the current player has the option to raise (which will almost always be true, unless this rule is
triggered, then it would be false.)
Hand Phases
Hand phases in the texasholdem package include the well-known PREFLOP,
FLOP, TURN, and
RIVER which are referred to as betting rounds.
Generally, HandPhase objects have two attributes of note:
new_cards()which describes how many new cards come out that phase
next_phase()which returns the next hand phase.
We can get the current hand phase of the game with the hand_phase attribute.
The well-known hand phases are self-explanatory so we will briefly touch on the two other phases:
Settle Phase
The phase where cards are revealed, hand rank is determined, and chips are rewarded. Currently, there is not a
concept of hidden information implemented and it is up to the developer to implement such a system.
However, in the future we will implement a View object which encapsulates public & private information.
Then in this phase, players may choose to REVEAL or MUCK their cards, allowing other players to see
their cards if they so choose.
Prehand Phase
This phase is the in-between phase between hands. In other words, the game is in an undefined state until
start_hand() is called again.
is_hand_running() will return False.
Player Information
Player information can be found in a few locations and is generally found with a player_id aka seat id. This
number is a number 0 through max_players.
Player Object
The first location we can get basic player information is through the
players list (i.e. accessed by game.players[i]). This is the
Player object and includes
The
player_id.The number of
chipsbehind a player (i.e. chips not bet or ante’d)The
stateof a player which is of typePlayerStateand can be one ofThe id of the
last_potthe player is eligible for.
Chip Counts
The number of chips that a player currently has behind them as stated above can be found from the
chips attribute.
Additionally, the TexasHoldEm provides a few methods for chip counts:
chips_to_call()returns how many more chips the player needs to post to be consideredIN. Note: this is not capped by the number of chips the player can post. For instance, a player with only 25 chips remaining can still need to call >25 chips for the current pot.
player_bet_amount()returns the number of chips the player has bet this betting round across all pots.
chips_at_stake()returns how many chips the player can win so far (including the chips they’ve posted as well).
min_raise()returns the minimum value a player can raise.
value_to_total()translates a raise action phrase “raise amount” to the phrase “raise to total”.
total_to_value()translates a raise action phrase “raise to total” to the phrase “raise value”.
Hand History
The History object keeps all necessary information to be able to replay the hand it describes.
It includes an entry for each hand phase, accessible as history[HandPhase.PREHAND], etc. We record the location
of the blinds, player chip counts and cards, etc. for the prehand phase, the new cards and player actions for each
betting round, and finally the winners, hand rank, and win amounts for each pot in the settle phase.
Most usefully, we can export the history to a PGN file with export_history().
This will export the history in a human-readable format to a file.
Example PGN File
# We can comment anywhere that takes up the whole line
# There is a section for each hand phase
# Note: By convention, the button location is always assumed to be player 0
PREHAND
Big Blind: 5 # We also support end-of-line comments
Small Blind: 2
Player Chips: 500,500,500,500,500,500
Player Cards: [Ks 6c],[7d As],[Kc Ac],[7h 7s],[5h Ts],[6h 5d]
PREFLOP
# Each action is a tuple of (player_id,ActionType,value)
New Cards: []
1. (3,FOLD);(4,FOLD);(5,FOLD);(0,CALL);(1,CALL);(2,RAISE,12)
# New orbit number 2 means that each player here has already played once
2. (0,CALL);(1,CALL)
FLOP
New Cards: [8s,9s,6d]
1. (1,RAISE,13);(2,FOLD);(0,CALL)
TURN
New Cards: [4s]
1. (1,CHECK);(0,CHECK)
RIVER
New Cards: [3s]
1. (1,RAISE,90);(0,RAISE,183)
2. (1,RAISE,200);(0,RAISE,470)
3. (1,FOLD)
SETTLE
# We settle by pot in a tuple (Pot pot_id, amount, best_rank, winners)
# Note: best_rank is -1 if there is only one winner in the pot due to everyone folding
New Cards: []
Winners: (Pot 0,732,-1,[0])
Note
By convention, the button is assumed to be player 0 in the PGN format.
Note
Comments starting with ‘#’ is supported in the PGN format.
Replaying Hands
We can also import a PGN file with import_history(). This returns an iterator
over the intermediate states of the game:
for state in TexasHoldEm.import_history('./texas.pgn'):
gui.display_state(state)
If you’re using a GUI, the GUIs come with a special method to view history and wait until prompted with one line:
gui.replay_history('./texas.pgn')
Pot Information
The pots of the current hand is accessible through the pots attribute
which is a list of Pot objects (indexable by pot id). Generally, developers
should not touch these objects, but can glean some information off of it:
amountis the amount in the pot not including the current betting round (but including any player who folded this betting round).
get_player_amount()returns the amount the given player has in the pot.
get_total_amount()returns theamountplus the sum of all player amounts for this betting round.
The main pot always has id 0. The last_pot attribute on the
Player object returns the id of the last pot the player is eligible for.