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 of IN or TO_CALL).

  • in_pot_iter() which is an iterator over player ids who have a stake in the pot (i.e. with a state of IN, TO_CALL, or ALL_IN).

  • player_iter() which is a general iterator over ALL seats at the table and which allows you to exclude states with the filter_states argument or match states with the match_states argument.

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.

Note

Additionally, we include the lesser-known SETTLE phase and our own PREHAND phase.

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 chips behind a player (i.e. chips not bet or ante’d)

  • The state of a player which is of type PlayerState and can be one of

    • OUT, if the player folded this round.

    • SKIP, if a player cannot play anymore this game.

    • TO_CALL, if a player needs to put in more chips to continue to play.

    • IN, if a player has posted enough chips to be in the pot

    • ALL_IN, if a player has posted all their chips (and thus cannot take anymore actions).

  • The id of the last_pot the 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 considered IN. 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:

  • amount is 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 the amount plus 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.