kedoska / engine-blackjack Goto Github PK
View Code? Open in Web Editor NEWJavascript library to make blackjack engines
License: GNU General Public License v2.0
Javascript library to make blackjack engines
License: GNU General Public License v2.0
An optional rule exists where a player's hand will automatically win if they reach a certain number of cards without busting usually called "5 Card Charlie" to "7 Card Charlie" (depending on the variation). I believe this variant is common enough that it would be nice to have as an option
source: https://wizardofodds.com/games/blackjack/strategy/charlie/
How can I contact you privately?
What the prole is:
when the player gets 5, A, A, 5, the values are 22 / 12, and the game busted, when it should not have.
to reproduce:
'♥5 ♣1 ♥4 ♣9 ♠1 ♦5'
close: true
playerHasBlackjack: false
playerHasBusted: true
playerHasSurrendered: false
playerValue: {
hi: 22
lo: 12
}
Hi there,
3 years later... I decided to migrate the project to typescript and do some refactoring to it.
The stable release, what we use in production, is v0.9.2 what is currently in NPM.
I will try to keep the same tests at the beginning in order to prevent breaking changes. I will comment on the go.
I think I found a bug on the way the deck is updated in the state when taking an action.
There are 5 filters on game.js that update the deck like this:
deck = deck.filter(x => [cardLeft, cardRight].indexOf(x) === -1)
This removes all occurrences of cardLeft and cardRight and I think they are not needed because the cards are already removed when splicing the deck to get the hand or dealer cards. I think this is a bug when playing with more than one deck.
To fix that for this particular filter (the second one in game.js) I updated the deck like this:
const { deck } = this.state
And removed the line with the filter.
The rest can be a bit different depending on where the state deck is, but I think all 5 filters need to be removed.
I saw on #63 that you are planning on transcribing the project to typescript. Can you check that too while you are at it?
Build process must babelize the engine and make it browser usable with es2015
.
I will use neutrino and neutrino-preset-node
Double exposure is a blackjack variation in which both dealer cards are exposed. Naturally, there are other rule changes that favor the dealer to compensate.
source http://wizardofodds.com/
We want to implement this variation as set of rules:
exposeSecondDealerCard
to present the second dealer card (dealerHoleCard
) after deal1.5
but in this case will be 1
0
/cc @paulcardo
I'm not sure what arguments to give to new Game() for things like standOnSoft17
After the fix for #47 we now need to consider that handValue.hi
is not the only available value to be considered in getPrize
The following code is not enough at this point:
if (playerValue.hi > dealerValue) {
return (bet + bet)
} else if (playerValue.hi === dealerValue) {
return bet
}
Source: https://www.pagat.com/banking/blackjack.html
If the second card dealt to a split ace is a 10-point card you do not receive the blackjack bonus for this hand. It does however win against an ordinary 21 made of more than two cards. If the dealer also has a blackjack the result for this hand is a push as usual. In many places the same rule (no blackjack bonus) is played if an ace is dealt as the second card to a 10-point card after splitting.
Bug
In the history does not show the cards, the json is:
{
"bet": 1.1,
"dealerCards": [],
"left": [],
"right": [],
"type": "DOUBLE"
},
New game
Deal
Double
go to the History to see the cards
This is something I was trying to avoid since the beginning: considering limits or balance, but, available actions, considering that there is an initial amount in the game, should also consider the current available balance of the player. Of course, by implementing the engine it is possible to perform many other check according with the state of the customer (its balance, its limits etc) but ... actions are definitely wrong in some cases:
so, i think i should implement a value that represents the "current limit" of the user (unlimited by default) that if specified it will be considered to unlock actions.
it.only('what is this', function () {
const cards = '♠2 ♦1 ♥5 ♣6 ♠11 ♦10'
const actions = ['restore', 'deal', 'split', 'hitR', 'hitR', 'hitR']
const rules = {
decks: 1,
standOnSoft17: true,
double: 'any',
split: true,
doubleAfterSplit: true,
surrender: true,
insurance: true,
showdownAfterAceSplit: true
}
const state = executeFlow(rules, cards, actions.map(x => functions[x]))
if (state.stage === 'player-turn-right') {
console.dir(state.handInfo.right)
console.dir(state.handInfo.left)
}
assert.equal(state.stage, 'done', cards)
})
This little guy, sometimes fails...
and when it does... the stage is "player-turn-right" which is very strange cause
{ cards:
[ { text: '10', suite: 'diamonds', value: 10, color: 'R' },
{ text: '2', suite: 'spades', value: 2, color: 'B' },
{ text: '3', suite: 'hearts', value: 3, color: 'R' },
{ text: 'A', suite: 'diamonds', value: 1, color: 'R' },
{ text: '5', suite: 'clubs', value: 5, color: 'B' } ],
playerValue: { hi: 21, lo: 21 },
playerHasBlackjack: false,
playerHasBusted: false,
playerHasSurrendered: false,
playerInsuranceValue: 0,
close: false,
availableActions:
{ double: false,
split: false,
insurance: false,
hit: true,
stand: true,
surrender: false },
bet: 10
}
{ cards:
[ { text: 'J', suite: 'spades', value: 10, color: 'B' },
{ text: 'A', suite: 'diamonds', value: 1, color: 'R' } ],
playerValue: { hi: 21, lo: 11 },
playerHasBlackjack: true,
playerHasBusted: false,
playerHasSurrendered: false,
playerInsuranceValue: 0,
close: true,
availableActions:
{ double: false,
split: false,
insurance: false,
hit: false,
stand: false,
surrender: false },
bet: 10
}
A Custom variations that distribute 2 cards (one each side) after the split
.
Like the showdownAfterAceSplit
but without showdown.
I really like both, the project of @gsdriver blackjack-strategy and the references of wizardofodds used by him in README .
Instead of rebuild the entire strategy rules, I'm going to add the first dependencies even if i told in README we do not want to do it. That project is absolutely correlated to this project so I can talk with my ego and explain it.
There are some things to align in the rule of the engine but it is possible.
Strategy will be integrated as a post-action, player will receive the list of good
actions so that the UI can easily handle the alert when player is doing something wrong (without calling the server again)
No idea yet, as it will be probably integrated as dependencies, I will add references in source code where the lib is actually.
https://github.com/kedoska/engine-blackjack/blob/master/test/game.spec.js#L216
AssertionError: R has busted
+ expected - actual
-false
+true
at Context.<anonymous> (test/game.spec.js:234:12)
Source http://wizardofodds.com/games/blackjack/side-bets/lucky-lucky/
Lucky Lucky is a side bet based on the player's first two cards and the dealer's up card. As far as I know, it is the first side bet to be based on the player's first two cards and the dealer's up card. Since it came out, there have been many imitators.
Through the years I have seen four pay tables, which I refer to on this page as numbers 1 to 4. Pay table 1 was the original one and seen at casinos all over the United States and Canada. Pay table 2 was a double-deck version, omitting the pay for a suited 7-7-7, which is impossible in a double-deck game. Pay table 3 came along around 2014 as an apparent effort to increase what was a low house advantage for a side bet. Pay table 4 can be found at Internet casinos using Felt Gaming software.
There is a bug in the engine where the dealer hits when they shouldn't.
Here is scenario 1:
The player stands when they have 15 points.
The dealer was dealt 16 points.
Since the dealer has less than 17, the dealer hits.
The problem is that the dealer has already won and shouldn't hit.
Here is scenario 2:
The player stands when they have 15 points.
The dealer was dealt less than 15 points.
The dealer hits and gets 16 points.
Since the dealer has less than 17, the dealer hits again.
The problem is that the dealer has already won and shouldn't hit.
Actions should leave a better information in the history.
I personally do not pretend to store snapshot of all the states in production. So to archive time travelling, and allow player to navigate throw their game play, the history should contain at least:
stage
stage
Docs are too fuzzy.
We need to describe actions and available actions, stages and returned data.
In blackjack 1st card goes to player, 2nd to dealer, 3rd to player, 4th to dealer, but in engine it took 2 cards from end to player and 2 to dealer.
game.setState({
deck: serializeCards('2h 3h 4h 5h 6h 7h 8h 9h 10h 11h 12h 13h'),
});
Expected: Player / Dealer - 13h 11h / 12h 10h
Actual: Player / Dealer - 13h 12h / 11h 10h
BUG: issue #47 regarding the 2 aces bug still sends a hi
over 21
the fix for #47 still outputs this:
playerValue: {
hi: 22
lo: 12
}
To reproduce, you can use these cards:
'♥5 ♣1 ♥4 ♣9 ♠1 ♦5'
At this point we no longer need the 22, and the output could read:
playerValue: {
hi: 12
lo: 12
}
Insurance is now calculated during the INSURANCE action.
Insurance value is already returned as a side bet into the sideBetsInfo
Both wonOnRight
and wonOnLeft
should not add the value of the insurance.
So I've actually managed to implement this into a discord bot (wasn't really that hard tbh)
When testing around I stumbled upon this.
The player did stand immediately, on the first draw for dealer both dealer and player had 16, dealer got another card and overdraw making the player win. This causes the player to double it's points instead of win his original amount. Is there a way to add this as an option when initializing the game?
I think the engine is missing the insurance special case where the dealer asks for 'even money'. This kind of insurance should be available when the dealer has an ace card and the player has a blackjack.
After the 'DEAL' action, and if the player has a blackjack and the dealer face-up card is an ace, the game goes to the 'SHOWDOWN' stage instead of asking for even money/insurance.
The following link has an explanation with an example: http://www.hitorsplit.com/articles/What_is_Insurance_and_Even_Money.html
I might try to add this to the engine but maybe you can give me some hints.
Bug
Unexpected exception 'TypeError: Cannot read property 'bet' of undefined'
const game = new blackjack.Game();
game.dispatch(blackjack.actions.deal());
Error goes away by providing a bet value of 0 to deal({ bet: 0 })
, but I think if bet
is omitted it should automatically default 0 instead of throwing error.
You used to have an example basic ui, did that get obsoleted?
can i use this engine to support multiple players?
left and right are close: false
so prize calculation is not executed
rule: showdownAfterAceSplit: true
cards: ...... ♥8 ♥8 ♥1 ♦4 ♥10 ♦1 ♦1
actions: ['deal', 'split']
Calling another deal after stage is 'done' does not work. Creating a new game with the state sent through does not work.
So, we need to close the game when player hits 21
it('should finish the game when player hits 21 (soft)', function () {
const cards = '♠6 ♠5 ♥3 ♦K ♦1 ♦9'
const actions = [ 'restore', 'deal', 'hitR', 'hitR' ]
const rules = {
decks: 1,
standOnSoft17: true,
double: 'any',
split: true,
doubleAfterSplit: true,
showdownAfterAceSplit: true
}
const state = executeFlow(rules, cards, actions.map(x => functions[ x ]))
const { stage, wonOnRight, handInfo: { right } } = state
assert.equal(right.playerValue.hi, 21, 'Player has 21 on right')
assert.equal(stage, 'done', 'game is over')
assert.equal(wonOnRight, 10 * 2, 'Won')
})
})
I just got a copy of TurboFan: A new code generation architecture for V8. I guess my favorite slide is
That number is enough to push me to some refactoring
Multiplayer
Hey there Kedoska, My name is Tyrell and I am working with AltspaceVR. After looking through your repository we really liked what we saw and we would like to implement your your blackjack engine with our product.
In order to do so we need to add multiplayer functionality to the engine but before we got started I wanted to ask if you had any thoughts on how to approach this endeavor.
When player surrender, the game finish
and the Dealer must show his second card.
Hi there! Love this engine, thanks so much for sharing! Pretty sure I've found a bug...
when the dealer is showing an ace, all player actions return INVALID
stage = "player-turn-right"
action = "stand" or "split" or "hit" or "double" (they all come back invalid)
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.