A BlackJack simulator in Python to simulate thousands or millions of hands using different strategies.

Overview

BlackJack Simulator (in Python)

A BlackJack simulator to play any number of hands using different strategies

The Rules

To keep the code relatively simple, a lot of the rules are hard-coded. This simulator assumes:

  • Dealer hits soft-17
  • Player can double-down any first 2 cards
  • Player can split any number of times
  • Blackjack pays 6:5 (1.2)
  • Surrender is allowed and the loss is 1/2

The Structure

Overview

The way this code is structured is:

  • That the game is played at a Table.
  • A Table has 1 Shoe of cards. The Shoe can have anywhere from 1 to 10 Decks of cards.
  • A Table has 1 Dealer.
  • A Table has 1 or more Players.
  • A Player has 1 or more Hands. Generally, a player has 1 hand unless there are splits, in which case player can have multiple hands.
  • A Dealer has 1 hand.

To simulate a round of BlackJack, you simply:

  1. Create a Table object (which creates a dealer and shoe with 8 decks by default)
  2. Add a player to the table
  3. And then you call Table.playRound() to play 1 round of BlackJack.
  4. The table then needs to reset using the Table.reset() method to play another hand.

The results of each hand is stored in the hand itself.

Code to simulate 1,000 rounds

The code to simulate 1,000 rounds of BlackJack can be as simple as:

table = Table()
table.players.append(Player())
for i in range(0, 1000):        # Simulates 1,000 rounds of BlackJack
    table.playRound()
    table.reset()

In order to see the results, including dealer's FaceCard and the decision the player made, you can also use the Table.printShortResults() or Table.printVerboseResults(). Here is an example of printing condensed results:

table = Table()

table.players.append(Player())
print("Round, Dealer FaceCard, Player Card 1, Card 2, Total, Soft Hand, Is BlackJack, Busted, Action, Result, Value")

for i in range(0, 1000):        # Simulates 1,000 rounds of BlackJack
    table.playRound()
    print(str(i) + ", " + table.printShortResults())
    table.reset()

The results include a "Value" for the hand that ranges from -2.0 to 2.0:

  • -1.0 Means a normal loss for a hand
  • +1.0 Means a normal win for a hand
  • -2.0 Means a Double-Downed round was lost
  • +2.0 Means a Double-Downed round was won
  • +1.2 Means a BlackJack win
  • -0.5 Means a loss by surrender

The Classes

The Shoe Class

The Shoe is designed to be extremely simple. When its initialized (or shuffled), it simply creates an array of 52 x [Num of Decks] elements numbered from 1 to 52. When a card is needed from the Shoe via getCard(), the Shoe randomly picks an array element and removes it from the array and returns it as the card. However, prior to returning the card, it first does a "% 13" operation to simulate a card from 1 (Ace) to 13 (King), and since in BlackJack, a 10, Jack, Queen and King are all 10s, if the card is >= 10, it returns a 10.

The Hand Class

A lot of the logic on how to play a hand is in the Hand class.

The Hand class has 3 main methods on how the hand will be played:

  • basicStrategyPlay - This plays using standard BlackJack basic strategy.
  • randomPlay - This plays using a random allowed action. Results of this could be used to train machine learning alogrithms.
  • dealerPlay - This plays using standard BlackJack dealer play strategy.

The getHandTotal() method is also useful to get the hand total, which takes into consideration soft hands (a hand with an Ace that is counted as an 11). If a hand total is considered to be a soft hand, it also sets the "softHand" variable that's passed in to true.

The Player and Dealer Classes

Since most of the logic for how the hand is played is actually in the Hand class, the Player and Dealer objects are just wrappers to hold a hand. Ideally, it might make sense to refactor the code to put the "play" methods into the Player and Dealer classes rather than the Hand class.

Another potential refactor might make the Dealer a kind of Player rather than its own class.

The Table Class

The Table class is where the bulk of the action is.

When the table "playRound()" is called, the table first deals the first 2 cards as no logic is needed prior to dealing the first 2 cards to all players and the dealer. If the dealer doesn't have a BlackJack, it then continues the play.

The playPlayerHand() is probably the most complicated part of the code because in the event of a Split, it can also be called recursively. The code is written so that the playPlayerHand() uses the basicStrategyPlay() method to play the round. You can also change this to randomPlay() to see what would happen if the player plays the game by taking a random action based on available actions.

You might also like...
Similar looking domain detection using python fuzzywuzzy

Major cause of phishing and BEC incident is similar looking domain, if you detect it early, you can prevent incidents early, python fuzzywuzzy module let you do that

SH-PUBLIC is a python based cloning script. You can clone unlimited UID facebook accounts by using this tool.

SH-PUBLIC is a python based cloning script. You can clone unlimited UID facebook accounts by using this tool. This tool works on any Android devices without root.

This utility lets you draw using your laptop's touchpad on Linux.
This utility lets you draw using your laptop's touchpad on Linux.

FingerPaint This utility lets you draw using your laptop's touchpad on Linux. Pressing any key or clicking the touchpad will finish the drawing

Protect your eyes from eye strain using this simple and beautiful, yet extensible break reminder

Protect your eyes from eye strain using this simple and beautiful, yet extensible break reminder

Backup a folder to an another folder by using mirror update method.

Mirror Update Backup Backup a folder to an another folder by using mirror update method. How to use Install requirement pip install -r requirements.tx

Software to help automate collecting crowdsourced annotations using Mechanical Turk.

Video Crowdsourcing Software to help automate collecting crowdsourced annotations using Mechanical Turk. The goal of this project is to enable crowdso

Run async workflows using pytest-fixtures-style dependency injection

Run async workflows using pytest-fixtures-style dependency injection

Simplex using Jordan exchanges taught in 236A
Simplex using Jordan exchanges taught in 236A

Simplex for 236A Python script to solve LP using simplex by Jordan exchanges taught in 236A. You will need python installed along with the 'numpy' and

✨ Voici un code en Python par moi, et en français qui permet d'exécuter du Javascript en Python.
✨ Voici un code en Python par moi, et en français qui permet d'exécuter du Javascript en Python.

JavaScript In Python ❗ Voici un code en Python par moi, et en français qui permet d'exécuter du Javascript en Python. 🔮 Une vidéo pour vous expliquer

Owner
Hamid
Hamid
Produce a simulate-able SDF of an arbitrary mesh with convex decomposition.

Mesh-to-SDF converter Given a (potentially nasty, nonconvex) mesh, automatically creates an SDF file that describes that object. The visual geometry i

Greg Izatt 22 Nov 23, 2022
Dice Rolling Simulator using Python-random

Dice Rolling Simulator As the name of the program suggests, we will be imitating a rolling dice. This is one of the interesting python projects and wi

PyLaboratory 1 Feb 2, 2022
A simulator for xkcd 2529's weirdly concrete problem

What is this? This is a quick hack implementation of a simulator for xkcd 2529's weirdly concrete problem. This is barely tested and I suck at computa

Reuben Steenekamp 6 Oct 27, 2021
Factoral Methods using two different method

Factoral-Methods-using-two-different-method Here, I am finding the factorial of a number by using two different method. The first method is by using f

Sachin Vinayak Dabhade 4 Sep 24, 2021
A library to easily convert climbing route grades between different grading systems.

pyclimb A library to easily convert climbing route grades between different grading systems. In rock climbing, mountaineering, and other climbing disc

Ilias Antonopoulos 4 Jan 26, 2022
cpp20.py is a Python script to compile C++20 code using modules.

cpp20.py is a Python script to compile C++20 code using modules. It browses the source files to determine their dependencies. Then, it compiles then in order using the correct flags.

Julien VERNAY 6 Aug 26, 2022
Here, I find the Fibonacci Series using python

Fibonacci-Series-using-python Here, I find the Fibonacci Series using python Requirements No Special Requirements Contribution I have strong belief on

Sachin Vinayak Dabhade 4 Sep 24, 2021
Adding two matrix from scratch using python.

Adding-two-matrix-from-scratch-using-python. Here, I have take two matrix from user and add it without using any library. I made this program from scr

Sachin Vinayak Dabhade 4 Sep 24, 2021
Python code to generate and store certificates automatically , using names from a csv file

WOC-certificate-generator Python code to generate and store certificates automatically , using names from a csv file IMPORTANT In order to make the co

Google Developer Student Club - IIIT Kalyani 10 May 26, 2022
Lock files using python and cmd

Python_Lock_Files Lock files using python and cmd license feel free to do whatever you want to with these files, i dont take any responsibility tho, u

null 1 Nov 1, 2021