StatJack is a BlackJack simulator, written in Ruby. It provides:
- an interactive blackjack game
- an automated blackjack simulator
- a learning algorithm, making the best moves based upon previously observed hands and their outcomes
- a statistics generator for win/loss odds for every decision at any possible gamestate
- Blackjack Rules
- StatJack Rules
- Simulation Cost and Parameters
- Model Formulation
- Gathering Results and Data
- Results and Observations
The object of blackjack is to accumulate cards with points totaling as close to 21 without actually going over 21:
- Face cards (Jacks, Queens and Kings) are worth 10 points.
- Aces are worth 1 or 11, whichever is preferable.
- Other cards are represented by their number.
The goal of the game is quite simple: to win, the player needs to beat the dealer without busting. The player busts when his or her cards total to more than 21 and the player loses automatically. The winner is whoever has closest to a total of 21. The player reaches 21 by adding up the values of the cards.
The blackjack table seats about six players depending on specific casino venues. In the American style of blackjack, the standard has become to either use six or eight decks of cards to be used and to be shuffled together by the dealer and placed in a card dispensing box called “Shoe.”
Before receiving any cards, the player must place a bet. Then the player is dealt two cards face up. The dealer gets one face up, one face down. The player either stands or demands more cards (hit) to try and get closer to 21 without busting. If playing with more than one player, those who do not bust wait for the dealer’s turn. When all the players are done, the dealer turns up the card that was faced down. By rule, on counts of 17 or higher the dealer must stay (Soft 17 Rule) or keep playing depending on the casino house rules – some casinos make it a rule to have dealers stand on a 17 and others let the dealer keep hitting if desired.
If the player makes a total of 21 with the first two cards (a 10 or a face card and an Ace) that are dealt at the beginning of each game, the player wins automatically. This is called “Blackjack.” If the player has Blackjack, he or she will win one and one-half times the original bet unless the dealer also has Blackjack, in which case it is a Push or a Tie (or a Stand-off) and you get your bet back.
The remaining players with a higher count than the dealer win an amount equal to their bet. Players with a lower count than the dealer lose their bet. If the dealer busts, all the remaining players win. There are other betting options namely Insurance, Surrender, Double Down, Even Money and Split (please note that we the only strategies or betting options that have not been implemented in StatJack are Even Money and Split).
Rule Set Definition
StatJack utilizes the American style Vegas rules. The following parameters and rule sets have been defined within the simulator to produce a decision matrix as accurately as possible to the theoretical one:
Number of Decks: StatJack is configured to utilize six different decks of cards for shuffling – Exhibit 1 demonstrates the house advantage when given a conditional number of deck(s).
Payout Ratio: in keeping consistent with Vegas rules by defining a payout ratio of 3/2 (or 1.5) if the player gets a Blackjack or if the player wins the hand in general.
Number of Hands before Re-Shuffling: to be as authentic as possible to a real blackjack game, the dispensing box in which cards are shuffled together (the “Shoe”) will be automatically re-shuffled if the Shoe appears to contain less than 25 cards within its deck. By refilling the cards consistently, the house will keep the statistical advantage against the player throughout each game-state.
Soft 17 Rule: depending on specific casinos, some venues will require their dealers to stand if the total cards value for the dealer happens to be 17. In other venues, some casinos will allow their dealers to hit on their next move if their total cards value is also 17. StatJack offers the option to employ the Soft 17 Rule but this is disabled by default in order to reduce complexity during the production of decision matrixes.
Insurance Strategy: in this scenario, the player has the possibility to raise a side bet up to half the initial bet’s value against the dealer if the latter happens to have a natural 21 – only allowed when the dealer’s showing card is an Ace. If the dealer has a 10 on the card that is face down and makes a blackjack, insurance pays at 2-1 odds (2:1 ratio) to the player, but if the face down card is not a 10 and therefore does not produce a natural 21, the side bet and the initial bet are both counted as losses. StatJack also offers the functionality of the insurance strategy but this too is disabled by default in order to avoid adding any unnecessary layer of complexity during the production of decision matrixes.
Surrender Strategy: under this scenario, the player may give up his or her hand at any time during the current playing hand and lose only half of the initial bet. StatJack simulator offers the functionality of the surrender strategy as well but is turned off by default in order to avoid adding any unnecessary layer of complexity during the production of decision matrixes.
Double Down Strategy: this strategy involves doubling down your initial bet following the initial two-card deal, however on the condition that once the player decides to double down, the player must take one and only one additional card. Most casinos will allow players to double down on any two cards. Other casinos let you double down after splitting and some will even limit your doubling down to hands that total ten or eleven. StatJack offers factors in the possible game-states in which doubling down would be an optimal decision but with limited functionality.
Minimum Bet and Starting Funds: the default values for each minimum bet has been set to $10 and the player’s and house’s starting funds are both set to $1,000,000. Both of these parameters are user defined and can be changed to any positive integers.
Exhibit 1: Statistical Summary of House Advantage based on Number of Decks
|Number of Decks||House Advantage|
To produce a decision matrix with the statistically correct decision at every possible game-state.
Exhibit 2 shows a mock-up of the decision matrix we are trying to replicate.
Exhibit 2 – Theoretical Decision Matrix Mock-up (please note splits are not taken into account)
Simulation Cost and Parameters
Since StatJack is a simulator that has been built from the ground-up with no cost associated to it, simulating games also does not have a cost associated with it. Given the flexibility in the number of simulations StatJack can produce, the following amounts of iterations were simulated:
2,000 simulated blackjack games following the StatJack default rule set.
20,000 simulated blackjack games following the StatJack default rule set.
The following criteria summarize the boundaries and constraints of StatJack in the production of decision matrixes :
Splitting was not taken into consideration – similar pairs of cards were ignored in each captured game-state.
Never Bust, Mimic the Dealer, and Ten in the Hole were all strategies that were not implemented within the StatJack simulator.
Insurance and Surrender strategies are implemented but not included in the final decision matrix produced by the StatJack simulator to avoid further layer of complexities that were not within the scope of the project.
Statjack is written entirely in the Ruby programming language. The codebase contains approximately 2,500 lines of code in the following files:
The entire codebase is provided in Appendix A.
Ruby is written in C and is a general-purpose, object-oriented programming language. Ruby can be downloaded here: http://www.ruby-lang.org/en/downloads/ although newer implementations of OSx and Linux likely have ruby installed by default (try: ruby –v to see if ruby is already running on your system). StatJack requires several gems (ruby libraries). All requirements are managed in /lib/requirements.rb. The first four lines of this file require four external libraries that StatJack requires to run.
- Win32/Console/ANSI (windows only)
- Once Ruby has been installed, these gems can be installed via the following commands:
- gem install win32console
- gem install awesome_print
- gem install progressbar
- gem install spreadsheet
- The command: ‘gem list’ will list all currently installed gems.
- All gems are used either for console output formatting or, in the case of spreadsheet, for outputting to .xls files.
The code is documented heavily throughout and was written to be readable without specialized knowledge of ruby syntax (i.e. any moderately proficient programmer should be able to read the code easily).
The initial scope of the program was to include the option for the player to split his or her hand but the implementation of this functionality was postponed for a future refactoring of the codebase due to time and resource constraints.
StatJack.rb essentially serves as the main() code block for the program. Running StatJack (ruby ./StatJack.rb) will begin the program. Exit is by interrupt or user input.
The simulation class is the highest level class and its primary contents are an array of game objects. Game objects, in turn, are comprised of a series of game snapshots called game-states. Each game-state is a record of the current bet, house and player cards, house and player funds as well as the player’s action in response to the given game-state (whether that action be from user input or randomly generated in a Monte Carlo simulation). Accordingly, a simulation object contains a series of games that can be consistently replayed via their game-states which allows us to record summary statistics and ultimately produce a matrix of all the best decisions at every possible game-state.
Gathering Results and Data
The Results class handles, collects, calculates and stores all statistical measures of gameplay and simulation. The following methodology was adopted in order to produce an accurate decision matrix:
The Game class will only contain information about the current game actively being played. This where the gathering of simulated data begins.
Individual game metrics from each simulated iteration that is currently happening in the Game class will be consequently stored into the Gamestate class which provides a unique snapshot of the game at a given point in time – in this case I am interested in capturing the final outcome of the simulation between the player and the house.
An array of simulated games within the Gamestate class will contain a set of snapshots of the game statuses at each point in time and for each iterated simulation.
Once the array of simulated games within the Gamestate class has been completed, it is then processed into the Simulation class where the statistical analysis of the captured Gamestates will be transferred into a decision matrix using the functionalities provided from the Spreadsheet gem.
Finally, in order to get the right statistical decisions within the decision matrix, the utilization of ratios as the basis for the decision factoring of each Gamestate is the main decision logic process.
To provide an example, I decide to simulate 20 games. I will look at the first iteration of the simulation and see the logic behind the decision matrix:
Player card values are 16 (a 9 and 7 are the player cards).
House card value is 5 (the other house card is faced down so the player has no idea what the value is).
In this case, to calculate the hit-to-win ratio, I divide 5/16 = 0.3125 or 31.25% chance of getting a card that will not bust the player over 21.
On the other hand, to calculate the stand-to-win ratio, the player has two choices: either stand or hit. Since only two choices are available, its stand-to-win ratio is ½ = 0.5 or 50%.
Conclusion: in this specific Gamestate (a snapshot at this current simulated iteration), the player will make the decision to stand since it has a higher percentage of actually winning the game without busting over 21.
In order to figure out whether or not to Double Down the bet at each specific Gamestate, I have defined a threshold that is defined the following way:
If the hit-to-win ratio and the stand-to-win ratio are higher than 70%, then the game logic translates this criteria by showing the player that he should Double Down at this specific game-state within the decision matrix.
In order to guarantee that the technical specifications and the game logic behind the StatJack simulator are correct, I decided to find an already pre-existing blackjack simulator similar to the genre or simulation software like NS-2 which exists to replicate network traffic.
The professional simulation software that I utilized is called Casino Vérité Blackjack 5.5 which enabled us to replicate the StatJack simulator in almost the exact same conditions in which I programmed it. Here is a quick overview as to what the Casino Vérité Blackjack 5.5 software provides and what parameters I utilized and defined to simulate a similar number of iterations between the StatJack decision matrix and the Casino Vérité Blackjack 5.5 decision matrix:
(Advanced Simulation/Strategy Construction)
Rounds - Up to 300,000,000,000 rounds of Blackjack can be simulated.
- Players - 1-7 seats, each seat can use a different playing & betting strategy.
- Data - Up to 20,000 stats are created per seat.
- Reports - A customized report can be defined including only the data that you wish for the players that you wish. To deal with the large variety of stats; descriptions can be included on the reports.
- Charts - 41 standard graphs.
- Do it yourself Graphs - You can take any sets of the 60,000 data items and graph them.
- CVSpread - A spreadsheet subsystem has been included with CVData that can support Excel commands, functions and files. 143 math functions are included.
- Number formatting - To ease readability, thousands separators are now included in the 60,000 stats. To support the huge number of rounds, each number is tested for size and converted to scientific format if necessary. To improve readability for non-U.S. users; numbers, currencies and dates are customized by country.
- Playing Strategies - CVData can use the 400 CVBJ card counting tables and strategy creation screens.
- Betting strategies - A new, much simpler, method of specifying a betting strategy has been included. Although it is much easier to use, it still provides for sophisticated camouflage plays and betting errors. For more advanced strategies the old advanced method of defining a betting strategy is also included. For details see Blackjack Betting Strategies.
- Optimal Bet calculation - This feature supports optimal bet calculations for 1-7 hands and changing number of hands by the count.
- True-counting Unbalanced Strategies - Strategies like TKO (true-counted KO) are supported for simulation and index generation.
- Real Shuffling - As an alternative to random shuffling, you can now specify real shuffles. The shuffles can be extremely complex and variability can be specified in every step. A shuffle animator is supplied to ensure that you have correctly defined the strategy. Note: Shuffle-Tracking support has not been added. This is to test for shuffle weaknesses. (Note: I am calling this section experimental as it is highly complex. It has been extensively tested and verifies deck contents successfully after every shuffle. But, I won’t declare it non-experimental until after a few more months of testing.)
- Custom output screen - Create your own output screen with charts if desired.
The above criteria were utilized and customized to replicate a version of the StatJack simulator as accurately as possible. Essentially, all of the blackjack rules and strategies that were omitted out of StatJack were also omitted out of the simulation runs through Casino Vérité Blackjack 5.5. The software provided us with almost 100% customization accuracy. The only area where I could not compare the game logic on a case-by-case basis was through the definition of the hit-to-win and stand-to-win ratio definitions.
StatJack (20,000 iterations)
Casino Vérité Blackjack 5.5 (20,000 iterations)
Results and Observations
A few discrepancies between the decision matrix produced by StatJack and Casino Vérité Blackjack 5.5 are noticeable.
Result: if you would look at the StatJack decision matrix, you can see that the player hands for a having a card with a value of 4 is there but is not available on the Casino Vérité Blackjack 5.5 decision matrix.
Observation: it seems that the Casino Vérité Blackjack 5.5 decision matrix does not provide decisions for player cards with a hand value of 4. the prediction would be that the row would be exactly the same as the one found in the StatJack decision matrix where the player should Hit at every possible game-state.
Result: if you would look at the StatJack decision matrix at rows 18, 19, and 20, you will see that a few Double Down decision game-states do not appear on the Casino Vérité Blackjack 5.5 decision matrix.
Observation: when the player has cards with values totaling 18, 19, and 20, the best choice at this specific game-state would be to stand regardless of the dealer’s own cards (unless she or he has a blackjack or natural 21). However, given how I define player actions based on hit-to-win and stand-to-win ratios, this is where the discrepancy is most likely occurring. It seems that the Casino Vérité Blackjack 5.5 simulator is more risk averse than the StatJack simulator under this scenario.
Result: if you would look at the StatJack decision matrix under the Pair section, rows [A, 7], [A, 8], and [A, 9], I once again see discrepancies between the StatJack decision matrix and the Casino Vérité Blackjack 5.5 decision matrix.
Observation: when the player has the following card values [A, 7], [A, 8], and [A, 9], it is left up to the interpretation of either software to either consider to count the Aces as either 1 or 11. The Casino Vérité Blackjack 5.5 simulator is risk tolerant, converting the Aces to ones. Conversely, StatJack operates in a risk averse manner, generally favoring ace valuations of 11 in order to secure upfront the highest hit-to-win or stand-to-win ratios.