Basic Strategy Generation

Command line options

-e EFFORT, --effort EFFORT
                      How many different hand combinations to test. (min: 0=fastest, very accurate; max: 5=very
                      slow, super accurate; default: 0)
--cores CORES         How many cores to use in the calculation. (default: 1, use -1 for all cores)
-f FILENAME, --filename FILENAME
                      Where to save the basic strategy generated. Leave empty to not save. (default: don't save)
-tc TRUE_COUNT, --true-count TRUE_COUNT
                      Generate deviations from basic strategy for a specific true count. Leave empty to generate
                      basic strategy. (default: generate basic strategy)
--decks DECKS         How many decks the shoe starts with. (default: 6)
--deck-penetration DECK_PENETRATION
                      When to reshuffle the shoe. Reshuffles when cards remaining < starting cards * deck
                      penetration. (default: 0.25)
--stand17             Dealer should stand on soft 17. (default: true)
--hit17               Dealer should hit on soft 17. (default: false)
--das                 Allow double after split. (default: true)
--no-das              Don't allow double after split. (default: false)
--peek                Dealer peeks for blackjack. (default: true)
--no-peek             Dealer doesn't peek for blackjack. (default: false)
--surrender           Allow surrendering. (default: true)
--no-surrender        Don't allow surrendering. (default: false)

See the help by running python basic_strategy_generator.py -h.

Creating the basic strategy plots

basic_strategy_generator.draw_and_export_tables(effort=0, cores=1, filename=None, true_count=None, number_of_decks=6, deck_penetration=0.25, dealer_peeks_for_blackjack=True, das=True, dealer_stands_soft_17=True, can_surrender=True, plot_results=True)

Create the graphs with the basic strategy (and maybe save it to a file).

Parameters:
  • effort (int) – How many different hand combinations to test. (min: 0=fastest, very accurate; max: 5=very slow, super accurate)

  • cores (int) – How many cores to use in the generation of basic strategy.

  • filename (str | None) – Where to store the basic strategy. If it is None, then it isn’t saved.

  • true_count (int | None) – The true count that we should generate basic strategy for. Default is None which generates general basic strategy. An integer, generated deviations from basic strategy.

  • number_of_decks (int) – The number of decks in the initial shoe.

  • deck_penetration (float) – When to reshuffle the shoe. Reshuffles when cards remaining < starting cards * deck penetration. So the shoe can’t have fewer than starting cards * deck penetration cards.

  • dealer_peeks_for_blackjack (bool) – Whether the dealer peeks for blackjack.

  • das (bool) – Whether we can double after splitting.

  • dealer_stands_soft_17 (bool) – Whether the dealer stands on soft 17.

  • can_surrender (bool) – Whether the game rules allow surrendering.

  • plot_results (bool) – Whether we should plot the basic strategy at the end.

Returns:

The three basic strategy tables. (for hard totals, soft totals, and pair splitting)

Return type:

tuple[list[list[str]], …]

Example:

from basic_strategy_generator import draw_and_export_tables

hard_totals, soft_totals, pair_splitting = draw_and_export_tables(effort=1, cores=2, filename="strategy.csv", true_count=2,
                                                                  number_of_decks=8, deck_penetration=.25, dealer_peeks_for_blackjack=True,
                                                                  das=True, dealer_stands_soft_17=True, can_surrender=True, plot_results=False)

Generating basic strategy

basic_strategy_generator.no_ace_table_generator(cores=1, card_numbers=(2, 3, 4), number_of_decks=6, true_count=None, shoes_to_test=None, deck_penetration=0.25, dealer_peeks_for_blackjack=True, das=True, dealer_stands_soft_17=True, can_surrender=True)

Generate basic strategy when we don’t have an ace.

Parameters:
  • cores (int) – How many cores to use in the generation of basic strategy.

  • card_numbers (tuple[int, ...]) – Test all hand with card_numbers number of hands. (e.g. if card_numbers is (2, 3), then all hands with 2 or 3 cards will be tested)

  • number_of_decks (int) – The number of decks in the initial shoe.

  • true_count (int | None) – The true count that we should generate basic strategy for. Default is None which generates general basic strategy. An integer, generated deviations from basic strategy.

  • shoes_to_test (int | None) – How many shoes to test when generating deviations.

  • deck_penetration (float) – When to reshuffle the shoe. Reshuffles when cards remaining < starting cards * deck penetration. So the shoe can’t have fewer than starting cards * deck penetration cards.

  • dealer_peeks_for_blackjack (bool) – Whether the dealer peeks for blackjack.

  • das (bool) – Whether we can double after splitting.

  • dealer_stands_soft_17 (bool) – Whether the dealer stands on soft 17.

  • can_surrender (bool) – Whether the game rules allow surrendering.

Returns:

The basic strategy table, to be saved and/or plotted.

Return type:

dict[int, dict[int, str]]

basic_strategy_generator.ace_table_generator(cores=1, card_numbers=(2, 3, 4), number_of_decks=6, true_count=None, shoes_to_test=None, deck_penetration=0.25, dealer_peeks_for_blackjack=True, das=True, dealer_stands_soft_17=True, can_surrender=True)

Generate basic strategy when we have an ace.

Parameters:
  • cores (int) – How many cores to use in the generation of basic strategy.

  • card_numbers (tuple[int, ...]) – Test all hand with card_numbers number of hands. (e.g. if card_numbers is (2, 3), then all hands with 2 or 3 cards will be tested)

  • number_of_decks (int) – The number of decks in the initial shoe.

  • true_count (int | None) – The true count that we should generate basic strategy for. Default is None which generates general basic strategy. An integer, generated deviations from basic strategy.

  • shoes_to_test (int | None) – How many shoes to test when generating deviations.

  • deck_penetration (float) – When to reshuffle the shoe. Reshuffles when cards remaining < starting cards * deck penetration. So the shoe can’t have fewer than starting cards * deck penetration cards.

  • dealer_peeks_for_blackjack (bool) – Whether the dealer peeks for blackjack.

  • das (bool) – Whether we can double after splitting.

  • dealer_stands_soft_17 (bool) – Whether the dealer stands on soft 17.

  • can_surrender (bool) – Whether the game rules allow surrendering.

Returns:

The basic strategy table, to be saved and/or plotted.

Return type:

dict[int, dict[int, str]]

basic_strategy_generator.split_table_generator(cores=1, max_splits=1, number_of_decks=6, true_count=None, shoes_to_test=None, deck_penetration=0.25, dealer_peeks_for_blackjack=True, das=True, dealer_stands_soft_17=True, can_surrender=True)

Generate basic strategy when we can split.

Parameters:
  • cores (int) – How many cores to use in the generation of basic strategy.

  • max_splits (int) – The maximum number of times a hand can be split. (1=fastest, fairly accurate; 3=slowest, super accurate)

  • number_of_decks (int) – The number of decks in the initial shoe.

  • true_count (int | None) – The true count that we should generate basic strategy for. Default is None which generates general basic strategy. An integer, generated deviations from basic strategy.

  • shoes_to_test (int | None) – How many shoes to test when generating deviations.

  • deck_penetration (float) – When to reshuffle the shoe. Reshuffles when cards remaining < starting cards * deck penetration. So the shoe can’t have fewer than starting cards * deck penetration cards.

  • dealer_peeks_for_blackjack (bool) – Whether the dealer peeks for blackjack.

  • das (bool) – Whether we can double after splitting.

  • dealer_stands_soft_17 (bool) – Whether the dealer stands on soft 17.

  • can_surrender (bool) – Whether the game rules allow surrendering.

Returns:

The basic strategy table, to be saved and/or plotted.

Return type:

dict[int, dict[int, str]]

Utilities

basic_strategy_generator.argmax(*profits)

Return the maximum profit and the action that gets you that profit.

Parameters:

profits (float) – The profits generated by each action.

Returns:

The best profit, and the best action.

Return type:

tuple[float, str]

class basic_strategy_generator.Hand(cards)

Hold information about the hand of the player and the dealer.

Save the initial cards.

Parameters:

cards (Iterable[int]) – The cards the hand started with.

add_card(card)

Add a new card to the hand.

Parameters:

card (int) – The new card to add for the hand (an ace is symbolised as 11).

Return type:

None

value()

Return the value of a hand.

Returns:

The hand’s value.

Return type:

int

value_aces()

Return the value of a hand and how many aces that count as 11 it has.

Returns:

The hand’s value and how many aces are counted as 11 (0 or 1).

Return type:

tuple[int, int]