GithubHelp home page GithubHelp logo

mhluska / blackjack-simulator Goto Github PK

View Code? Open in Web Editor NEW
47.0 3.0 12.0 2.07 MB

๐Ÿƒ Realistic blackjack simulator (practice card counting using Hi-Lo and calculate EV for any table conditions)

Home Page: https://mhluska.github.io/blackjack-atlas

License: MIT License

JavaScript 3.26% HTML 0.10% TypeScript 96.64%
blackjack blackjack-game cli nodejs javascript blackjack-simulator simulator typescript multiprocessing

blackjack-simulator's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

blackjack-simulator's Issues

Remove EventEmitter

It's too dynamic for AssemblyScript and isn't really needed now that we advance the game with a DFA. We can just get a full tree of game state after every step with a function call from the outside. After that is removed, we can also remove Proxy code which wouldn't be supported in AS either.

TypeError: Cannot read property 'takeCards' of undefined

The error seems to happen when simulating 3 spots played simultaneously with a large number of hands:

./bin/cli.js simulate --hands 1000000000 --player-bet-spread '$200,$200,$400,$600' --player-wong-out-true-count 2 --allow-late-surrender true --hit-soft17 false --minimum-bet '$200.00' --maximum-bet '$2,000.00' --deck-count 6 --player-spots 3,3,3,3

Fix spotCount option

It looks like when we increase the number of spots played at positive counts from 1 to 2 in a simulation, the EV plummets which is not what is expected.

1 spot:

./bin/cli.js simulate --minimum-bet '$50' --hands 10000000 --player-bet-spread '$50,$100,$200,$400' --player-spots 1,1,1,1
Table Rules:    $50โ€“$5,000 2D 3:2 H17 DAS RSA
Bet Spread:     TC 0: $50, TC 1: $100, TC 2: $200, TC 3+: $400
Spots Played:   TC 0+: 1
Bankroll Rqd:   $63,788.37 (5% RoR)
Expected Value: $184.81/hour
Std Deviation:  $194.05
House Edge:     -0.76%
Hands Played:   10M
Amount Earned:  $8,842,425.00
Amount Wagered: $1,156,445,150.00
Hands Lost:     4.8M
Hands Pushed:   821.3K
Hands Won:      4.4M
Time Elapsed:   17.52 seconds

2 spots:

./bin/cli.js simulate --minimum-bet '$50' --hands 10000000 --player-bet-spread '$50,$100,$200,$400' --player-spots 1,2,2,2
Table Rules:    $50โ€“$5,000 2D 3:2 H17 DAS RSA
Bet Spread:     TC 0: $50, TC 1: $100, TC 2: $200, TC 3+: $400
Spots Played:   TC 0: 1, TC 1โ€“3+: 2
Bankroll Rqd:   $189,759.33 (5% RoR)
Expected Value: $125.54/hour
Std Deviation:  $275.85
House Edge:     -0.47%
Hands Played:   10M
Amount Earned:  $6,006,500.00
Amount Wagered: $1,272,839,800.00
Hands Lost:     4.8M
Hands Pushed:   817.7K
Hands Won:      4.4M
Time Elapsed:   16.62 seconds

Incorrect hints for 6 deck

With double deck, 16vT is a stand on TC 0+. But what about 6 deck? Seems like surrender should take priority regardless of the count.

Also the game doesn't seem to use the S17 charts. For example 15vA is a hit but says it should be surrender.

Missing basic strategy charts

Most of the charts are missing for anything other than double deck. Ideally we have charts for:

  • 1 deck DAS
  • 1 deck DAS LS
  • 2 deck DAS
  • 2 deck DAS LS

Up to 4, 6, and 8 decks. Also variants for H17 and S17. This is basically a data entry task unless we find a way to compute these based on EV.

Incorrect bankroll calculation when playing multiple spots

We currently use amountEarned / handsPlayed to calculate expectation per hand and use bankroll variance to estimate variance per hand. This works well when playing only one hand the entire session but breaks down when multiple spots are played.

It might be better to calculate expectation per hand not empirically. But then we'll need to precompute count distributions for the various deck counts and penetrations and also precompute a baseline house advantage for each game type.

Dollar values for CLI args

Currently the CLI args accept cent integer values only which is kind of annoying. Allow it to also accept dollar values.

Broken game modes

Uncommon and pairs game modes are broken in master after switching to enum types. A fix would involve changing the basic strategy charts away from objects to Maps to avoid the keys being cast to strings.

Add saved sims

Similar to CVCX, we can precompute the simulation results with several billion hands. It can be done with every permutation of table conditions as well as some preset table minimums ($10, $15, $25, $50, $100 etc).

There's be a storage format like JSON to serialize and commit to the repo. And maybe a CLI arg to bypass and recompute the result if needed.

Loading indicator

We should immediately show the table conditions and player strategy and then a loading indicator until the simulation is finished. Consider how this would affect piping output from one command to another.

CLI flag validation

There should be an error when trying to use an invalid flag via the command line.

WebAssembly

Consider converting this project to something like AssemblyScript. Would probably be much more performant.

Would probably have to first switch away from the current async/await to a simple state machine: #21

Afterwards, the user input concerns could also be totally removed from the library. Ideally any DOM interactions are removed from the library to make converting to wasm simpler.

Add optimal bet spread calculation

Currently we're able to manually define the bet spread or use a simple exponential spread (e.g. TC 1 $10, TC 2 $20, TC 3 $40 etc.). It would be nice if there was a command to return the optimal spread given table conditions. As well as using the optimal one by default for simulations if a custom one isn't provided.

Wrong EV results for 6D

./bin/cli.js simulate --minimum-bet '$25.00' --deck-count 6 --penetration 0.75 gives a positive house edge with a 10x spread and I18. That's unexpected.

Wrong or missing version number

npx @blackjacktrainer/blackjack-simulator -v reads the version from package.json in the current directory which is wrong. It should be relative to the local directory where bin/cli.js is installed.

Unexpected standard deviation value

The current output for standard deviation seems to be the standard deviation for earnings per hand. This empirical number doesn't seem to line up with the equations. For example:

$ blackjack-simulator simulate --minimum-bet '$25'

Table Rules:    $25โ€“$2,500 2D 3:2 H17 DAS NLS NRSA
Penetration:    75.00%
Bet Spread:     TC 0: $25, TC 1: $50, TC 2: $100, TC 3: $200, TC 4+: $400
Spots Played:   TC 0+: 1
Bankroll Rqd:   $36,026.41 (5.00% RoR)
Expected Value: $255.97/hour
Std Deviation:  $171.63
House Edge:     -1.42%
Hands Played:   10M
Amount Earned:  $12,247,462.50
Amount Wagered: $860,190,225.00
Hands Lost:     4.8M
Hands Pushed:   820.7K
Hands Won:      4.4M
Time Elapsed:   1.78 seconds

So sd is $171.63 per hand if we're spreading $25-$400 over 10M hands. That already seems unusual.

sd = 1.1 * sqrt(N) = 1.1 * sqrt(10M) = 3478.51 units. If our average bet or unit here is $86, then we're looking at a total sd of $299,851 after playing 10M hands.

I'm not really sure how to reconcile that number with our $171.63 value. If the value is correct, it seems to say that s.d. per hand for us is 1.99 whereas BJA says it should be 1.15 or 1.11. This could be entirely due to our aggressive (and imperfect) bet spread.

So things to do:

  • Revisit this value after calculating an optimal bet spread and see if it aligns more closely with 1.1
  • Add "per hand" to the output to make it clearer what it represents
  • Maybe add an average bet size to the output too

Basic Strategy suggest incorrect when pair

chartType is based upon hand.allowSplit but playerTotal based upon hand.hasPairs. As a result, treats J,K or similar as 10 and doubles most every time causing incorrect results.

Candidate fix:

const playerTotal = Utils.clamp(
  hand.allowSplit ? hand.cards[0].value : hand.cardTotal,
  chartMin,
  chartMax
);

House edge value should not change with player bet spread

Currently the house edge is calculated by looking at amount wagered vs amount earned which of course will change based on the player decisions. One option here is to first run the simulator with flat betting and perfect basic strategy to get an accurate house edge. The other is to just estimate the house edge based on rules (e.g. double after split adds 0.x% etc).

Incorrect EV when playing more than two spots

1 spot seems fine:

blackjack-simulator simulate --player-spots 1,1,1,1,1 --player-bet-spread '$15,$15,$30,$100,$150' --minimum-bet '$15'
Table Rules:  $15โ€“$1,500 2D 3:2 H17 DAS NLS NRSA
Penetration:  75.00%
Bet Spread:   TC 0โ€“1: $15, TC 2: $30, TC 3: $100, TC 4+: $150
Spots Played: TC 0+: 1
Simulating 10M hands...

Expected Value: $68.30/hour
Bankroll Rqd:   $21,784.49
Risk Of Ruin:   5.00%
Std Deviation:  $68.94/hand
House Edge:     -0.89%
Hands Played:   10M
Amount Earned:  $3,268,090.00
Amount Wagered: $367,725,995.00
Hands Lost:     4.8M
Hands Pushed:   814.2K
Hands Won:      4.4M
Time Elapsed:   2.15 seconds

Two spots seems fine (sort of):

blackjack-simulator simulate --player-spots 1,1,2,2,2 --player-bet-spread '$15,$15,$30,$100,$150' --minimum-bet '$15'
Table Rules:  $15โ€“$1,500 2D 3:2 H17 DAS NLS NRSA
Penetration:  75.00%
Bet Spread:   TC 0โ€“1: $15, TC 2: $30, TC 3: $100, TC 4+: $150
Spots Played: TC 0โ€“1: 1, TC 2โ€“4+: 2
Simulating 10M hands...

Expected Value: $61.98/hour
Bankroll Rqd:   $47,702.43
Risk Of Ruin:   5.00%
Std Deviation:  $97.18/hand
House Edge:     -0.69%
Hands Played:   10M
Amount Earned:  $2,965,670.00
Amount Wagered: $427,507,670.00
Hands Lost:     4.8M
Hands Pushed:   811.4K
Hands Won:      4.4M
Time Elapsed:   1.97 seconds

We see slightly less total EV but a reduction in variance (the std deviation value is probably wrong and should be roughly halved).

Three spots is messed up:

blackjack-simulator simulate --player-spots 1,1,3,3,3 --player-bet-spread '$15,$15,$30,$100,$150' --minimum-bet '$15'
Table Rules:  $15โ€“$1,500 2D 3:2 H17 DAS NLS NRSA
Penetration:  75.00%
Bet Spread:   TC 0โ€“1: $15, TC 2: $30, TC 3: $100, TC 4+: $150
Spots Played: TC 0โ€“1: 1, TC 2โ€“4+: 3
Simulating 10M hands...

Expected Value: -$36.23/hour
Bankroll Rqd:   -$124,235.88
Risk Of Ruin:   5.00%
Std Deviation:  $119.90/hand
House Edge:     0.38%
Hands Played:   10M
Amount Earned:  -$1,733,345.00
Amount Wagered: $458,045,890.00
Hands Lost:     4.8M
Hands Pushed:   808.4K
Hands Won:      4.4M
Time Elapsed:   1.93 seconds

Negative EV? Seems wrong.

Four spots:

blackjack-simulator simulate --player-spots 1,1,4,4,4 --player-bet-spread '$15,$15,$30,$100,$150' --minimum-bet '$15'
Table Rules:  $15โ€“$1,500 2D 3:2 H17 DAS NLS NRSA
Penetration:  75.00%
Bet Spread:   TC 0โ€“1: $15, TC 2: $30, TC 3: $100, TC 4+: $150
Spots Played: TC 0โ€“1: 1, TC 2โ€“4+: 4
Simulating 10M hands...

Expected Value: -$1,705.36/hour
Bankroll Rqd:   -$3,513.91
Risk Of Ruin:   5.00%
Std Deviation:  $138.35/hand
House Edge:     17.27%
Hands Played:   10M
Amount Earned:  -$81,596,050.00
Amount Wagered: $472,593,010.00
Hands Lost:     5.2M
Hands Pushed:   733.1K
Hands Won:      4.1M
Time Elapsed:   1.88 seconds

Massive drop in EV.

Risk and bankroll calculation

Currently the simulator accepts a bankroll. It would be nice if it could instead accept a desired risk of ruin and automatically compute a required bankroll for the simulation. Also, excluding a RoR or bankroll param should default to computing a bankroll for 1% RoR.

It would also be useful to have an additional command just for calculating bankroll based on parameters like RoR.

Loops forever with multiple players

For example with 5 players and 75% pen, the simulation will loop forever when enough hands are simulated. I suspect its because an edge case is reached where we run out of cards on the last hand of the shoe. Look into how this is dealt with in a realistic situation - probably just finish the hand by reshuffling the remainder of the deck and playing with those cards.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.