Blackjack strategy: Difference between revisions
Content added Content deleted
Line 1,318: | Line 1,318: | ||
Loss % staked : 1.801 |
Loss % staked : 1.801 |
||
</pre> |
</pre> |
||
=={{header|Nim}}== |
|||
{{trans|Go}} |
|||
<lang Nim>import random, sequtils, strformat, strutils |
|||
type |
|||
Card = 1..10 |
|||
Deck = object |
|||
size: int |
|||
cards: array[Card, int] |
|||
HandKind {.pure.} = enum Hard, Soft, Pair |
|||
Action {.pure.} = enum Stand, Hit, Double, Split |
|||
ActionGain = tuple[action: Action; gain: float] |
|||
var |
|||
# Computed strategy tables. |
|||
hTable: array[15, array[10, Action]] # Hard strategy table (round 1). |
|||
sTable: array[8, array[10, Action]] # Soft strategy table (round 1). |
|||
pTable: array[10, array[10, Action]] # Pairs strategy table (round 1). |
|||
hTable2: array[18, array[10, Action]] # Hard strategy table (round >= 2, no doubling). |
|||
sTable2: array[10, array[10, Action]] # Soft strategy table (round >= 2, no doubling). |
|||
func initDeck(): Deck = |
|||
Deck(size: 52, cards: [4, 4, 4, 4, 4, 4, 4, 4, 4, 16]) |
|||
func `<`(ag1, ag2: ActionGain): bool = ag1.gain < ag2.gain |
|||
func dealerProbs(upcard: Card; startDeck: Deck): array[7, float] = |
|||
## Returns probabilities of dealer eventually getting: |
|||
## 0: 17, 1: 18, 2: 19, 3: 20, 4: 21 (non-blackjack), 5: blackjack (nil), 6: bust. |
|||
## It is assumed that the dealer has already checked for blackjack, that one deck is used |
|||
## and that the dealer stands on 'soft' 17. |
|||
var |
|||
res: array[7, float] # Results. |
|||
decks: array[9, Deck] # Decks for each level. |
|||
scores: array[9, int] # Scores for each level. |
|||
elevens: array[9, int] # Number of aces for each level scored as 11. |
|||
probs: array[9, float] # Probabilities for each level. |
|||
decks[0] = startDeck |
|||
scores[0] = upCard |
|||
if upcard == 1: |
|||
# An ace. |
|||
scores[0] = 11 |
|||
elevens[0] = 1 |
|||
probs[0] = 1.0 |
|||
proc drawCard(lev: Natural) = |
|||
## Recursive closure. |
|||
for c in Card.low..Card.high: |
|||
if decks[lev].cards[c] == 0: continue # Card no longer present in deck. |
|||
# Temporary variables for current level. |
|||
var |
|||
deck = decks[lev] |
|||
score = scores[lev] |
|||
eleven = elevens[lev] |
|||
prob = probs[lev] |
|||
inc score, c # Add card to score. |
|||
if c == 1: |
|||
# Score all aces initially as 11. |
|||
inc score, 10 |
|||
inc eleven |
|||
prob *= deck.cards[c] / deck.size |
|||
if score > 21 and eleven > 0: |
|||
dec score, 10 # Bust but can demote an ace. |
|||
dec eleven |
|||
if lev == 0 and (upCard == 1 and c == 10 or upCard == 10 and c == 1): |
|||
res[5] += prob # Blackjack, allow for now. |
|||
elif score in 17..21: |
|||
res[score-17] += prob # 17 to (non-blackjack) 21. |
|||
elif score > 21 and eleven == 0: |
|||
res[6] += prob # Bust. |
|||
else: |
|||
dec deck.cards[c] # Remove card from deck. |
|||
dec deck.size |
|||
let lev = lev + 1 |
|||
decks[lev] = deck |
|||
scores[lev] = score |
|||
elevens[lev] = eleven |
|||
probs[lev] = prob |
|||
drawCard(lev) |
|||
drawCard(0) |
|||
# But can't have blackjack, so adjust probabilities accordingly. |
|||
let pnbj = 1 - res[5] |
|||
for i in 0..6: res[i] /= pnbj |
|||
res[5] = 0 |
|||
result = res |
|||
proc dealerChart = |
|||
## Print chart of dealer probabilities (as a check against an external source). |
|||
echo "Dealer Probabilities, Stands on Soft 17, 1 Deck, U.S Rules" |
|||
echo "Up Card 17 18 19 20 21 Bust" |
|||
echo "———————————————————————————————————————————————————————————————————" |
|||
var deck = initDeck() |
|||
deck.size = 51 |
|||
for uc in Card.low..Card.high: |
|||
var deck2 = deck |
|||
dec deck2.cards[uc] |
|||
let dp = dealerProbs(uc, deck2) |
|||
stdout.write if uc > 1: &"{uc:3} " else: "Ace " |
|||
for i in [0, 1, 2, 3, 4, 6]: stdout.write &" {dp[i]:.6f}" |
|||
echo() |
|||
func calcGain(pscore: int; dp: openArray[float]): float = |
|||
## Calculates gain per unit staked for a given scenario (helper function). |
|||
case pscore |
|||
of 17: |
|||
result += dp[6] # Dealer is bust. |
|||
result -= dp[1] + dp[2] + dp[3] + dp[4] # Dealer has 18 to 21. |
|||
of 18: |
|||
result += dp[0] + dp[6] # Dealer has 17 or is bust. |
|||
result -= dp[2] + dp[3] + dp[4] # Dealer has 19 to 21. |
|||
of 19: |
|||
result += dp[0] + dp[1] + dp[6] # Dealer has 17, 18 or is bust. |
|||
result -= dp[3] + dp[4] # Dealer has 20 or 21. |
|||
of 20: |
|||
result += dp[0] + dp[1] + dp[2] + dp[6] # Dealer has 17 to 19 or is bust. |
|||
result -= dp[4] # Dealer has (non-blackjack) 21. |
|||
of 21: |
|||
result += dp[0] + dp[1] + dp[2] + dp[3] + dp[6] # Dealer has 17 to 20 or is bust. |
|||
of 22: # Notional. |
|||
result += 1.5 # Player blackjack. |
|||
of 23: # Notional. |
|||
result -= 1 # Player bust, loses stake irrespective of what dealer has. |
|||
else: # Player has less than 17 |
|||
result += dp[6] # Dealer is bust. |
|||
result -= 1 - dp[6] # Dealer isn't bust. |
|||
func playerGain(card1, card2, uc: Card; startDeck: Deck): float = |
|||
## Returns player's expected gain per unit staked after hitting once and then standing. |
|||
let deck = startDeck |
|||
var |
|||
score = card1 + card2 |
|||
eleven = false |
|||
if card1 == 1 or card2 == 1: |
|||
inc score, 10 |
|||
eleven = true |
|||
for c in Card.low..Card.high: |
|||
# Get another card. |
|||
if deck.cards[c] == 0: continue # Card no longer present in deck. |
|||
# Temporary variables for current card. |
|||
var |
|||
deck2 = deck |
|||
score2 = score |
|||
eleven2 = eleven |
|||
inc score2, c # Add card to score. |
|||
if c == 1: |
|||
# Score all aces initially as 11. |
|||
inc score2, 10 |
|||
eleven2 = true |
|||
let prob = deck2.cards[c] / deck2.size |
|||
dec deck2.cards[c] |
|||
dec deck2.size |
|||
if score2 > 21 and eleven2: |
|||
dec score2, 10 # Bust but can demote an ace. |
|||
if score2 <= 21: |
|||
let dp = dealerProbs(uc, deck2) |
|||
result += calcGain(score2, dp) * prob |
|||
else: |
|||
# Bust. |
|||
result -= prob |
|||
func playerGain2(card1, card2, uc: Card; startDeck: Deck): float = |
|||
## Return player's expected gain per unit staked after hitting once |
|||
## and then continuing in accordance with the tables for rounds >= 2. |
|||
var |
|||
eg = 0.0 # Result. |
|||
decks: array[9, Deck] # Decks for each level. |
|||
scores: array[9, int] # Scores for each level. |
|||
elevens: array[9, int] # Number of aces for each level scored as 11. |
|||
probs: array[9, float] # Probabilities for each level. |
|||
decks[0] = startDeck |
|||
scores[0] = card1 + card2 |
|||
if card1 == 1 or card2 == 1: |
|||
inc scores[0], 10 |
|||
elevens[0] = 1 |
|||
probs[0] = 1.0 |
|||
proc drawCard(lev: Natural) = |
|||
## Recursive closure. |
|||
for c in Card.low..Card.high: |
|||
if decks[lev].cards[c] == 0: continue # Card no longer present in deck. |
|||
# Temporary variables for current level. |
|||
var |
|||
deck = decks[lev] |
|||
score = scores[lev] |
|||
eleven = elevens[lev] |
|||
prob = probs[lev] |
|||
inc score, c # Add card to score. |
|||
if c == 1: |
|||
# Score all aces initially as 11. |
|||
inc score, 10 |
|||
inc eleven |
|||
prob *= deck.cards[c] / deck.size |
|||
if score > 21 and eleven > 0: |
|||
dec score, 10 # Bust but can demote an ace. |
|||
dec eleven |
|||
dec deck.cards[c] # Remove card from deck. |
|||
dec deck.size |
|||
if (eleven == 0 and (score >= 17 or score >= 13 and uc < 7) or |
|||
eleven == 0 and score == 12 and uc >= 4 and uc <= 6 or |
|||
eleven > 0 and score == 18 and uc != 9 and uc != 10 or |
|||
eleven > 0 and score >= 19) and score <= 21: |
|||
let dp = dealerProbs(uc, deck) |
|||
eg += calcGain(score, dp) * prob |
|||
elif score > 21 and eleven == 0: |
|||
# Bust. |
|||
eg -= prob |
|||
else: |
|||
let lev = lev + 1 |
|||
decks[lev] = deck |
|||
scores[lev] = score |
|||
elevens[lev] = eleven |
|||
probs[lev] = prob |
|||
drawCard(lev) |
|||
drawCard(0) |
|||
result = eg |
|||
func stand(card1, card2: Card): array[10, float] = |
|||
## Return player's expected gains per unit staked, for each dealer up-card, after standing. |
|||
var deck = initDeck() |
|||
dec deck.cards[card1] |
|||
dec deck.cards[card2] |
|||
deck.size = 50 |
|||
var pscore = card1 + card2 # Player score. |
|||
if card1 == 1 or card2 == 1: |
|||
inc pscore, 10 |
|||
for uc in Card.low..Card.high: # Dealer's up-card. |
|||
var deck2 = deck |
|||
dec deck2.cards[uc] |
|||
dec deck2.size |
|||
let dp = dealerProbs(uc, deck2) |
|||
let eg = calcGain(pscore, dp) # Expected gain for this up-card. |
|||
if uc > 1: |
|||
result[uc-2] = eg |
|||
else: # Dealer has Ace. |
|||
result[9] = eg # Ace comes last in tables. |
|||
func hit(card1, card2: Card; once: bool): array[10, float] = |
|||
## Return player's expected gains per unit staked, for each dealer |
|||
## up-card, after hitting once and then either standing (once == true) |
|||
## or continuing as per the round >= 2 tables (once == false). |
|||
var deck = initDeck() |
|||
dec deck.cards[card1] |
|||
dec deck.cards[card2] |
|||
deck.size = 50 |
|||
for uc in Card.low..Card.high: # Dealer's up-card. |
|||
var deck2 = deck |
|||
dec deck2.cards[uc] |
|||
deck2.size = 49 |
|||
# Player's expected gain for this up-card. |
|||
let peg = if once: playerGain(card1, card2, uc, deck2) |
|||
else: playerGain2(card1, card2, uc, deck2) |
|||
if uc > 1: |
|||
result[uc-2] = peg |
|||
else: # Dealer has Ace. |
|||
result[9] = peg |
|||
func double(card1, card2: Card): array[10, float] = |
|||
## Return player's expected gains per unit originally staked, |
|||
## for each dealer up-card, after doubling i.e. hitting once |
|||
## and then standing with a doubled stake. |
|||
result = hit(card1, card2, true) # Hit once and then stand. |
|||
for item in result.mitems: |
|||
item *= 2 |
|||
proc split(card: Card): array[10, float] = |
|||
## Return player's expected gains per unit originally staked, for each dealer up-card, after |
|||
## splitting a pair and doubling the stake, getting a second card for each hand and then |
|||
## continuing in accordance with the rounds >= 2 tables. It is assumed that a player cannot |
|||
## double or re-split following a split. It is also assumed (in the interests of simplicity) |
|||
## that the expected gains for each split hand (after calculating the gains for the first hand |
|||
## as though the second hand is not completed) are exactly the same. |
|||
var deck = initDeck() |
|||
dec deck.cards[card], 2 # Must be a pair. |
|||
deck.size = 50 |
|||
# Now play a single hand. |
|||
var score: int = card |
|||
var eleven = 0 |
|||
if card == 1: |
|||
score = 11 |
|||
eleven = 1 |
|||
for uc in Card.low..Card.high: # Collect results for each dealer up-card. |
|||
if deck.cards[uc] == 0: continue # Card no longer present in deck. |
|||
var deck2 = deck |
|||
dec deck2.cards[uc] |
|||
dec deck2.size |
|||
var ix = uc - 2 |
|||
if ix == -1: ix = 9 # In tables ace comes last. |
|||
var peg: float # Player expected gain for this up-card. |
|||
# Get second player card. |
|||
for c in Card.low..Card.high: |
|||
if deck2.cards[c] == 0: continue # Card no longer present in deck. |
|||
let prob = deck2.cards[c] / deck2.size |
|||
var deck3 = deck2 |
|||
dec deck3.cards[c] |
|||
dec deck3.size |
|||
var score2 = score + c |
|||
var eleven2 = eleven |
|||
if c == 1: |
|||
# Score all aces initially as 11. |
|||
inc score2, 10 |
|||
inc eleven2 |
|||
if score2 == 21: |
|||
# Player has blackjack & we know dealer hasn't. |
|||
peg += 1.5 * prob |
|||
continue |
|||
if score2 > 21 and eleven2 > 0: |
|||
dec score2, 10 # Bust but can demote an ace. |
|||
dec eleven2 |
|||
let action = if eleven2 > 0: sTable2[score2-12][ix] # Use soft strategy table, no doubling. |
|||
else: hTable2[score2-4][ix] # Use hard strategy table, no doubling |
|||
let peg2 = if action == Stand: calcGain(score2, dealerProbs(uc, deck3)) |
|||
else: playerGain2(card, c, uc, deck3) |
|||
peg += peg2 * prob |
|||
if uc > 1: |
|||
result[uc-2] = peg * 2 # Allow for both hands in overall results. |
|||
else: |
|||
result[9] = peg * 2 # Ditto. |
|||
func bestAction(ags: openArray[ActionGain]): Action = |
|||
## Return the action with the highest expected gain. |
|||
ags[ags.maxIndex()].action |
|||
proc printHeader(title: string) = |
|||
## Print title and header for a given chart. |
|||
echo title |
|||
echo "P/D 2 3 4 5 6 7 8 9 T A" |
|||
echo "——————————————————————————————————————————————————————————————————————————" |
|||
proc printPair(c: Card) = |
|||
## Print header for a pair of cards. |
|||
stdout.write if c == 1: "AA " elif c == 10: "TT " else: &"{c}{c} " |
|||
func dealerPlay(pscore: int, next: var int; cards, d: openArray[Card]): float = |
|||
## Simulate a dealer's play for a given player's hand and state of deck. |
|||
## Return the player's gain (positive or negative) per unit staked. |
|||
var dscore = d[0] + d[1] |
|||
var aces = 0 |
|||
if d[0] == 1 or d[1] == 1: |
|||
# Dealer has an ace. |
|||
inc dscore, 10 |
|||
inc aces |
|||
while true: |
|||
if dscore > 21 and aces > 0: |
|||
dec dscore, 10 # Bust but we can demote an ace. |
|||
dec aces |
|||
if dscore > 21: |
|||
return 1 # Dealer is bust and player gains stake. |
|||
if dscore >= 17: |
|||
# Dealer must stick on 17 or above, hard or not. |
|||
if dscore > pscore: |
|||
return -1 # Dealer wins and player loses stake. |
|||
if dscore == pscore: |
|||
break # Player breaks even. |
|||
return 1 # Dealer loses and player gains stake. |
|||
let nc = cards[next] # Get new card from pack. |
|||
inc next |
|||
inc dscore, nc |
|||
if nc == 1: |
|||
# Count aces initially as 11. |
|||
inc dscore, 10 |
|||
inc aces |
|||
proc playerPlay(): (float, float) = |
|||
## Simulate the playing of a random player's hand according to the strategy tables. |
|||
## Return both the gain (positive or negative) and the stake (1 or 2). |
|||
var perm = toSeq(0..51) |
|||
perm.shuffle() |
|||
var cards: array[52, Card] |
|||
for i, r in perm: |
|||
var card = r div 4 + 1 |
|||
if card > 10: card = 10 |
|||
cards[i] = card |
|||
var p, d: seq[Card] # Player and dealer hands. |
|||
# Initial deal. |
|||
p.add cards[0..1] |
|||
d.add cards[2..3] |
|||
var next = 4 # Index of next card to be dealt. |
|||
# Check if dealer and/or player have blackjack. |
|||
let dbj = d[0] == 1 and d[1] == 10 or d[0] == 10 and d[1] == 1 |
|||
let pbj = p[0] == 1 and p[1] == 10 or p[0] == 10 and p[1] == 1 |
|||
if dbj: |
|||
if pbj: return (0.0, 1.0) # Player neither wins nor loses. |
|||
else: return (-1.0, 1.0) # Player loses stake. |
|||
if pbj: return (1.5, 1.0) # Player wins 1.5 x stake. |
|||
var uc = d[0] - 2 # Dealer's up-card as index to access tables. |
|||
if uc < 0: uc = 9 # Ace is at last place in tables. |
|||
var stake = 1.0 # Player's initial stake. |
|||
var fscores: array[2, int] # Final player scores (one or, after split, two hands). |
|||
var action: Action |
|||
var score, aces: int |
|||
proc h(hand: int) = |
|||
## Process a hit. |
|||
while true: |
|||
let nc = cards[next] # Get new card from pack. |
|||
inc next |
|||
inc score, nc |
|||
if nc == 1: |
|||
# Count aces initially as 11. |
|||
inc score, 10 |
|||
inc aces |
|||
if score > 21 and aces > 0: |
|||
dec score, 10 # Bust but we can demote an ace. |
|||
dec aces |
|||
if score > 21: |
|||
fscores[hand] = 22 # Player is bust and loses stake. |
|||
break |
|||
if action == Double: |
|||
fscores[hand] = score |
|||
break |
|||
# Get further strategy and act accordingly. |
|||
action = if aces == 0: hTable2[score-4][uc] else: sTable2[score-12][uc] |
|||
if action == Stand: |
|||
fscores[hand] = score |
|||
break |
|||
score = p[0] + p[1] |
|||
# Get kind of player hand: hard, soft, pair. |
|||
let kind = if p[0] == p[1]: Pair elif p[0] == 1 or p[1] == 1: Soft else: Hard |
|||
case kind |
|||
of Hard: |
|||
action = hTable[score-5][uc] |
|||
of Soft: # includes one ace. |
|||
let othercard = if p[0] == 1: p[1] else: p[0] |
|||
inc score, 10 |
|||
aces = 1 |
|||
action = sTable[otherCard-2][uc] |
|||
of Pair: |
|||
if p[0] == 1: |
|||
# Pair of aces. |
|||
inc score, 10 |
|||
aces = 2 |
|||
action = pTable[p[0]-1][uc] |
|||
case action |
|||
of Stand: |
|||
fscores[0] = score |
|||
of Hit: |
|||
h(0) |
|||
of Double: |
|||
h(0) |
|||
stake = 2 |
|||
of Split: |
|||
for hand in 0..1: |
|||
score = p[0] |
|||
aces = 0 |
|||
if score == 1: |
|||
# Count aces initially as 11. |
|||
score = 11 |
|||
inc aces |
|||
h(hand) |
|||
var sum = 0.0 |
|||
if fscores[0] < 22: |
|||
sum += dealerPlay(fscores[0], next, cards, d) * stake |
|||
else: |
|||
sum -= 1 * stake # This hand is bust. |
|||
if fscores[1] > 0: |
|||
# Pair. |
|||
if fscores[1] < 22: |
|||
sum += dealerPlay(fscores[1], next, cards, d) |
|||
else: |
|||
sum -= 1 |
|||
stake = 2 |
|||
result = (sum, stake) |
|||
proc simulate(perDay, days: int) = |
|||
## Simulate "perDay" blackjack games for "days" days. |
|||
var |
|||
winDays, loseDays, evenDays = 0 |
|||
bigWin, bigLoss = 0.0 |
|||
totalGain, totalStake = 0.0 |
|||
for d in 1..days: |
|||
var dailyGain, dailyStake = 0.0 |
|||
for p in 1..perDay: |
|||
let (gain, stake) = playerPlay() |
|||
dailyGain += gain |
|||
dailyStake += stake |
|||
if dailyGain > 0: inc winDays |
|||
elif dailyGain < 0: inc loseDays |
|||
else: inc evenDays |
|||
if dailyGain > bigWin: bigWin = dailyGain |
|||
elif -dailyGain > bigLoss: bigLoss = -dailyGain |
|||
totalGain += dailyGain |
|||
totalStake += dailyStake |
|||
echo &"\nAfter playing {perDay} times a day for {days} days:" |
|||
echo "Winning days: ", winDays |
|||
echo "Losing days: ", loseDays |
|||
echo "Breakeven days: ", evenDays |
|||
echo "Biggest win: ", bigWin |
|||
echo "Biggest loss: ", bigLoss |
|||
if totalGain < 0: |
|||
echo "Total loss: ", -totalGain |
|||
echo "Total staked: ", totalStake |
|||
echo &"Loss % staked: {-totalGain/totalStake*100:0.3f}\n" |
|||
else: |
|||
echo "Total win: ", totalGain |
|||
echo "Total staked: ", totalStake |
|||
echo &"Win % staked: {totalGain/totalStake*100:0.3f}\n" |
|||
proc main() = |
|||
# Print dealer probabilities chart. |
|||
dealerChart() |
|||
# For hard scores (i.e. different cards, no aces). |
|||
const Tuples = [(2, 3), |
|||
(2, 4), |
|||
(2, 5), (3, 4), |
|||
(2, 6), (3, 5), |
|||
(2, 7), (3, 6), (4, 5), |
|||
(2, 8), (3, 7), (4, 6), |
|||
(2, 9), (3, 8), (4, 7), (5, 6), |
|||
(2, 10), (3, 9), (4, 8), (5, 7), |
|||
(3, 10), (4, 9), (5, 8), (6, 7), |
|||
(4, 10), (5, 9), (6, 8), |
|||
(5, 10), (6, 9), (7, 8), |
|||
(6, 10), (7, 9), |
|||
(7, 10), (8, 9), |
|||
(8, 10), |
|||
(9, 10)] |
|||
# Number of tuples for each player score from 5 to 19. |
|||
const Counts = [float 1, 1, 2, 2, 3, 3, 4, 4, 4, 3, 3, 2, 2, 1, 1] |
|||
# Expected gains for each player score & for each dealer up-card. |
|||
var |
|||
segs: array[15, array[10, float]] # if stands. |
|||
hegs: array[15, array[10, float]] # if hits. |
|||
degs: array[15, array[10, float]] # if doubles. |
|||
for t in Tuples: |
|||
let i = t[0] + t[1] |
|||
let sg = stand(t[0], t[1]) |
|||
let hg = hit(t[0], t[1], false) |
|||
let dg = double(t[0], t[1]) |
|||
for j in 0..9: |
|||
segs[i-5][j] += sg[j] |
|||
hegs[i-5][j] += hg[j] |
|||
degs[i-5][j] += dg[j] |
|||
# Calculate the average per tuple for each score. |
|||
for i in 0..14: |
|||
for j in 0..9: |
|||
segs[i][j] /= Counts[i] |
|||
hegs[i][j] /= Counts[i] |
|||
degs[i][j] /= Counts[i] |
|||
printHeader("\nHard Chart - Player Expected Gains per unit (Stand)") |
|||
for i in 5..19: |
|||
stdout.write &"{i:2} " |
|||
for j in 0..9: |
|||
stdout.write &"{segs[i-5][j]: 0.3f} " |
|||
echo() |
|||
printHeader("\nHard Chart - Player Expected Gains per unit (Hit)") |
|||
for i in 5..19: |
|||
stdout.write &"{i:2} " |
|||
for j in 0..9: |
|||
stdout.write &"{hegs[i-5][j]: 0.3f} " |
|||
echo() |
|||
printHeader("\nHard Chart - Player Expected Gains per unit (Double)") |
|||
for i in 5..19: |
|||
stdout.write &"{i:2} " |
|||
for j in 0..9: |
|||
stdout.write &"{degs[i-5][j]: 0.3f} " |
|||
echo() |
|||
printHeader("\nHard Chart - Player Strategy (Round 1)") |
|||
for i in 5..19: |
|||
stdout.write &"{i:2} " |
|||
for j in 0..9: |
|||
let ags = [(Stand, segs[i-5][j]), (Hit, hegs[i-5][j]), (Double, degs[i-5][j])] |
|||
let action = bestAction(ags) |
|||
hTable[i-5][j] = action |
|||
stdout.write &"{action:^6} " |
|||
echo() |
|||
# For hard scores (no aces) - after round 1 (no doubling or splitting). |
|||
# Based on hard table figures (round 1) with scores of 4, 20, and 21 added. |
|||
var |
|||
segs2: array[18, array[10, float]] # Expected gains if stands. |
|||
hegs2: array[18, array[10, float]] # Expected gains if hits. |
|||
for i in 5..19: |
|||
segs2[i-4] = segs[i-5] |
|||
hegs2[i-4] = hegs[i-5] |
|||
let sg4 = stand(2, 2) |
|||
let hg4 = hit(2, 2, false) |
|||
let sg20 = stand(10, 10) |
|||
let hg20 = hit(10, 10, false) |
|||
let sg21 = stand(1, 10) |
|||
let hg21 = hit(1, 10, false) |
|||
for j in 0..9: |
|||
segs2[0][j] += sg4[j] |
|||
hegs2[0][j] += hg4[j] |
|||
segs2[16][j] += sg20[j] |
|||
hegs2[16][j] += hg20[j] |
|||
segs2[17][j] += sg21[j] |
|||
hegs2[17][j] += hg21[j] |
|||
printHeader("\nHard Chart - Player Strategy (Round >= 2, No Doubling)") |
|||
for i in 4..21: |
|||
stdout.write &"{i:2} " |
|||
for j in 0..9: |
|||
var action = Stand |
|||
if hegs2[i-4][j] > segs2[i-4][j]: action = Hit |
|||
hTable2[i-4][j] = action |
|||
stdout.write &"{action:^6} " |
|||
echo() |
|||
# For soft scores (i.e. including exactly one ace). |
|||
# Expected gains for each player second card (2 to 9) & for each dealer up-card. |
|||
var |
|||
segs3: array[8, array[10, float]] # if stands. |
|||
hegs3: array[8, array[10, float]] # if hits. |
|||
degs3: array[8, array[10, float]] # if doubles. |
|||
for c in 2..9: |
|||
let sg = stand(1, c) |
|||
let hg = hit(1, c, false) |
|||
let dg = double(1, c) |
|||
for j in 0..9: |
|||
segs3[c-2][j] += sg[j] |
|||
hegs3[c-2][j] += hg[j] |
|||
degs3[c-2][j] += dg[j] |
|||
printHeader("\nSoft Chart - Player Expected Gains per unit (Stand)") |
|||
for c in 2..9: |
|||
stdout.write &"A{c} " |
|||
for j in 0..9: |
|||
stdout.write &"{segs3[c-2][j]: 0.3f} " |
|||
echo() |
|||
printHeader("\nSoft Chart - Player Expected Gains per unit (Hit)") |
|||
for c in 2..9: |
|||
stdout.write &"A{c} " |
|||
for j in 0..9: |
|||
stdout.write &"{hegs3[c-2][j]: 0.3f} " |
|||
echo() |
|||
printHeader("\nSoft Chart - Player Expected Gains per unit (Double)") |
|||
for c in 2..9: |
|||
stdout.write &"A{c} " |
|||
for j in 0..9: |
|||
stdout.write &"{degs3[c-2][j]: 0.3f} " |
|||
echo() |
|||
printHeader("\nSoft Chart - Player Strategy (Round 1)") |
|||
for c in 2..9: |
|||
stdout.write &"A{c} " |
|||
for j in 0..9: |
|||
let ags = [(Stand, segs3[c-2][j]), (Hit, hegs3[c-2][j]), (Double, degs3[c-2][j])] |
|||
let action = bestAction(ags) |
|||
sTable[c-2][j] = action |
|||
stdout.write &"{action:^6} " |
|||
echo() |
|||
# For soft scores (at least one ace) - after round 1 (no doubling or splitting). |
|||
# Based on soft table figures (round 1) with scores of 12 and 21 added. |
|||
# Assumes one ace counted as 11. |
|||
var |
|||
segs4: array[10, array[10, float]] # Expected gains if stands. |
|||
hegs4: array[10, array[10, float]] # Expected gains if hits. |
|||
for i in 1..8: |
|||
segs4[i] = segs3[i-1] |
|||
hegs4[i] = hegs3[i-1] |
|||
let sg12 = stand(1, 1) |
|||
let hg12 = hit(1, 1, false) |
|||
for j in 0..9: |
|||
segs4[0][j] += sg12[j] |
|||
hegs4[0][j] += hg12[j] |
|||
segs4[9][j] += sg21[j] |
|||
hegs4[9][j] += hg21[j] |
|||
printHeader("\nSoft Chart - Player Strategy (Round >= 2, No Doubling)") |
|||
for i in 12..21: |
|||
stdout.write &"{i:2} " |
|||
for j in 0..9: |
|||
var action = Stand |
|||
if hegs4[i-12][j] > segs4[i-12][j]: action = Hit |
|||
sTable2[i-12][j] = action |
|||
stdout.write &"{action:^6} " |
|||
echo() |
|||
# For pairs. |
|||
# Expected gains for each pair (A to 10) & for each dealer up-card. |
|||
var |
|||
segs5: array[10, array[10, float]] # if stands. |
|||
hegs5: array[10, array[10, float]] # if hits. |
|||
degs5: array[10, array[10, float]] # if double. |
|||
pegs5: array[10, array[10, float]] # if split. |
|||
for c in 1..10: |
|||
let |
|||
sg = stand(c, c) |
|||
hg = hit(c, c, false) |
|||
dg = double(c, c) |
|||
pg = split(c) |
|||
for j in 0..9: |
|||
segs5[c-1][j] += sg[j] |
|||
hegs5[c-1][j] += hg[j] |
|||
degs5[c-1][j] += dg[j] |
|||
pegs5[c-1][j] += pg[j] |
|||
printHeader("\nPairs Chart - Player Expected Gains per unit (Stand)") |
|||
for c in 1..10: |
|||
printPair(c) |
|||
for j in 0..9: |
|||
stdout.write &"{segs5[c-1][j]: 0.3f} " |
|||
echo() |
|||
printHeader("\nPairs Chart - Player Expected Gains per unit (Hit)") |
|||
for c in 1..10: |
|||
printPair(c) |
|||
for j in 0..9: |
|||
stdout.write &"{hegs5[c-1][j]: 0.3f} " |
|||
echo() |
|||
printHeader("\nPairs Chart - Player Expected Gains per unit (Double)") |
|||
for c in 1..10: |
|||
printPair(c) |
|||
for j in 0..9: |
|||
stdout.write &"{degs5[c-1][j]: 0.3f} " |
|||
echo() |
|||
printHeader("\nPairs Chart - Player Expected Gains per unit (Split)") |
|||
for c in 1..10: |
|||
printPair(c) |
|||
for j in 0..9: |
|||
stdout.write &"{pegs5[c-1][j]: 0.3f} " |
|||
echo() |
|||
printHeader("\nPairs Chart - Player Strategy (Round 1)") |
|||
for c in 1..10: |
|||
printPair(c) |
|||
for j in 0..9: |
|||
let ags = [(Stand, segs5[c-1][j]), (Hit, hegs5[c-1][j]), |
|||
(Double, degs5[c-1][j]), (Split, pegs5[c-1][j])] |
|||
let action = bestAction(ags) |
|||
pTable[c-1][j] = action |
|||
stdout.write &"{action:^6} " |
|||
echo() |
|||
randomize() |
|||
# Do 10 years of simulation. |
|||
for i in 1..10: |
|||
echo &"Simulation for year {i}:" |
|||
simulate(50, 365) |
|||
main()</lang> |
|||
{{out}} |
|||
<pre>Dealer Probabilities, Stands on Soft 17, 1 Deck, U.S Rules |
|||
Up Card 17 18 19 20 21 Bust |
|||
——————————————————————————————————————————————————————————————————— |
|||
Ace 0.183786 0.190890 0.188680 0.191692 0.075137 0.169815 |
|||
2 0.138976 0.131762 0.131815 0.123948 0.120526 0.352973 |
|||
3 0.130313 0.130946 0.123761 0.123345 0.116047 0.375588 |
|||
4 0.130973 0.114163 0.120679 0.116286 0.115096 0.402803 |
|||
5 0.119687 0.123483 0.116909 0.104694 0.106321 0.428905 |
|||
6 0.166948 0.106454 0.107192 0.100705 0.097878 0.420823 |
|||
7 0.372345 0.138583 0.077334 0.078897 0.072987 0.259854 |
|||
8 0.130857 0.362989 0.129445 0.068290 0.069791 0.238627 |
|||
9 0.121886 0.103921 0.357391 0.122250 0.061109 0.233442 |
|||
10 0.124156 0.122486 0.124421 0.356869 0.039570 0.232499 |
|||
Hard Chart - Player Expected Gains per unit (Stand) |
|||
P/D 2 3 4 5 6 7 8 9 T A |
|||
—————————————————————————————————————————————————————————————————————————— |
|||
5 -0.293 -0.248 -0.176 -0.104 -0.122 -0.469 -0.513 -0.533 -0.546 -0.659 |
|||
6 -0.291 -0.232 -0.172 -0.101 -0.119 -0.467 -0.522 -0.533 -0.547 -0.659 |
|||
7 -0.283 -0.229 -0.163 -0.098 -0.117 -0.471 -0.521 -0.537 -0.547 -0.658 |
|||
8 -0.276 -0.229 -0.162 -0.100 -0.130 -0.478 -0.523 -0.539 -0.549 -0.648 |
|||
9 -0.277 -0.224 -0.160 -0.108 -0.134 -0.480 -0.528 -0.543 -0.542 -0.646 |
|||
10 -0.279 -0.227 -0.172 -0.120 -0.146 -0.484 -0.531 -0.539 -0.537 -0.644 |
|||
11 -0.277 -0.231 -0.175 -0.123 -0.147 -0.488 -0.529 -0.537 -0.537 -0.646 |
|||
12 -0.286 -0.241 -0.185 -0.134 -0.151 -0.485 -0.526 -0.535 -0.533 -0.655 |
|||
13 -0.282 -0.236 -0.181 -0.133 -0.156 -0.488 -0.529 -0.537 -0.534 -0.649 |
|||
14 -0.282 -0.238 -0.188 -0.134 -0.159 -0.489 -0.529 -0.533 -0.536 -0.651 |
|||
15 -0.280 -0.239 -0.190 -0.144 -0.169 -0.494 -0.531 -0.536 -0.531 -0.648 |
|||
16 -0.287 -0.250 -0.194 -0.152 -0.179 -0.495 -0.526 -0.540 -0.530 -0.648 |
|||
17 -0.147 -0.120 -0.074 -0.044 -0.011 -0.122 -0.405 -0.414 -0.402 -0.459 |
|||
18 0.119 0.144 0.164 0.202 0.268 0.389 0.096 -0.196 -0.155 -0.082 |
|||
19 0.385 0.384 0.404 0.448 0.484 0.610 0.577 0.264 0.103 0.308 |
|||
Hard Chart - Player Expected Gains per unit (Hit) |
|||
P/D 2 3 4 5 6 7 8 9 T A |
|||
—————————————————————————————————————————————————————————————————————————— |
|||
5 -0.131 -0.098 -0.041 0.022 0.019 -0.119 -0.181 -0.262 -0.309 -0.417 |
|||
6 -0.151 -0.107 -0.055 0.009 0.014 -0.164 -0.234 -0.305 -0.349 -0.443 |
|||
7 -0.111 -0.072 -0.013 0.053 0.064 -0.069 -0.223 -0.295 -0.332 -0.401 |
|||
8 -0.015 0.021 0.084 0.136 0.148 0.092 -0.056 -0.213 -0.253 -0.275 |
|||
9 0.090 0.137 0.181 0.226 0.235 0.194 0.111 -0.052 -0.148 -0.128 |
|||
10 0.215 0.246 0.277 0.314 0.319 0.277 0.211 0.119 0.030 0.030 |
|||
11 0.272 0.296 0.327 0.361 0.362 0.293 0.222 0.146 0.107 0.113 |
|||
12 -0.256 -0.232 -0.206 -0.181 -0.179 -0.241 -0.308 -0.380 -0.378 -0.413 |
|||
13 -0.315 -0.293 -0.270 -0.252 -0.251 -0.301 -0.362 -0.389 -0.423 -0.440 |
|||
14 -0.363 -0.353 -0.337 -0.315 -0.313 -0.346 -0.366 -0.426 -0.455 -0.460 |
|||
15 -0.419 -0.414 -0.406 -0.392 -0.383 -0.351 -0.406 -0.466 -0.496 -0.487 |
|||
16 -0.461 -0.460 -0.454 -0.448 -0.397 -0.376 -0.426 -0.481 -0.510 -0.497 |
|||
17 -0.534 -0.536 -0.538 -0.493 -0.484 -0.450 -0.475 -0.529 -0.558 -0.546 |
|||
18 -0.633 -0.634 -0.597 -0.591 -0.586 -0.567 -0.565 -0.593 -0.624 -0.630 |
|||
19 -0.750 -0.713 -0.712 -0.709 -0.707 -0.699 -0.697 -0.698 -0.712 -0.740 |
|||
Hard Chart - Player Expected Gains per unit (Double) |
|||
P/D 2 3 4 5 6 7 8 9 T A |
|||
—————————————————————————————————————————————————————————————————————————— |
|||
5 -0.587 -0.497 -0.352 -0.209 -0.244 -0.938 -1.025 -1.066 -1.093 -1.318 |
|||
6 -0.560 -0.446 -0.324 -0.186 -0.215 -0.870 -1.023 -1.045 -1.074 -1.295 |
|||
7 -0.415 -0.317 -0.186 -0.066 -0.059 -0.555 -0.851 -0.936 -0.956 -1.127 |
|||
8 -0.165 -0.081 0.032 0.143 0.157 -0.140 -0.433 -0.697 -0.743 -0.802 |
|||
9 0.114 0.193 0.286 0.380 0.393 0.175 0.007 -0.281 -0.442 -0.409 |
|||
10 0.428 0.492 0.554 0.628 0.638 0.446 0.313 0.164 0.007 0.025 |
|||
11 0.542 0.592 0.654 0.722 0.724 0.479 0.341 0.223 0.164 0.198 |
|||
12 -0.511 -0.463 -0.413 -0.362 -0.358 -0.556 -0.690 -0.811 -0.789 -0.827 |
|||
13 -0.630 -0.587 -0.541 -0.503 -0.503 -0.651 -0.775 -0.807 -0.862 -0.880 |
|||
14 -0.727 -0.706 -0.673 -0.630 -0.627 -0.723 -0.759 -0.862 -0.915 -0.921 |
|||
15 -0.838 -0.829 -0.812 -0.783 -0.767 -0.716 -0.826 -0.937 -0.992 -0.973 |
|||
16 -0.921 -0.920 -0.908 -0.896 -0.793 -0.751 -0.853 -0.961 -1.019 -0.995 |
|||
17 -1.069 -1.072 -1.076 -0.985 -0.967 -0.901 -0.949 -1.058 -1.116 -1.092 |
|||
18 -1.265 -1.267 -1.195 -1.182 -1.172 -1.135 -1.130 -1.186 -1.248 -1.260 |
|||
19 -1.499 -1.425 -1.423 -1.417 -1.414 -1.397 -1.395 -1.396 -1.425 -1.481 |
|||
Hard Chart - Player Strategy (Round 1) |
|||
P/D 2 3 4 5 6 7 8 9 T A |
|||
—————————————————————————————————————————————————————————————————————————— |
|||
5 Hit Hit Hit Hit Hit Hit Hit Hit Hit Hit |
|||
6 Hit Hit Hit Hit Hit Hit Hit Hit Hit Hit |
|||
7 Hit Hit Hit Hit Hit Hit Hit Hit Hit Hit |
|||
8 Hit Hit Hit Double Double Hit Hit Hit Hit Hit |
|||
9 Double Double Double Double Double Hit Hit Hit Hit Hit |
|||
10 Double Double Double Double Double Double Double Double Hit Hit |
|||
11 Double Double Double Double Double Double Double Double Double Double |
|||
12 Hit Hit Stand Stand Stand Hit Hit Hit Hit Hit |
|||
13 Stand Stand Stand Stand Stand Hit Hit Hit Hit Hit |
|||
14 Stand Stand Stand Stand Stand Hit Hit Hit Hit Hit |
|||
15 Stand Stand Stand Stand Stand Hit Hit Hit Hit Hit |
|||
16 Stand Stand Stand Stand Stand Hit Hit Hit Hit Hit |
|||
17 Stand Stand Stand Stand Stand Stand Stand Stand Stand Stand |
|||
18 Stand Stand Stand Stand Stand Stand Stand Stand Stand Stand |
|||
19 Stand Stand Stand Stand Stand Stand Stand Stand Stand Stand |
|||
Hard Chart - Player Strategy (Round >= 2, No Doubling) |
|||
P/D 2 3 4 5 6 7 8 9 T A |
|||
—————————————————————————————————————————————————————————————————————————— |
|||
4 Hit Hit Hit Hit Hit Hit Hit Hit Hit Hit |
|||
5 Hit Hit Hit Hit Hit Hit Hit Hit Hit Hit |
|||
6 Hit Hit Hit Hit Hit Hit Hit Hit Hit Hit |
|||
7 Hit Hit Hit Hit Hit Hit Hit Hit Hit Hit |
|||
8 Hit Hit Hit Hit Hit Hit Hit Hit Hit Hit |
|||
9 Hit Hit Hit Hit Hit Hit Hit Hit Hit Hit |
|||
10 Hit Hit Hit Hit Hit Hit Hit Hit Hit Hit |
|||
11 Hit Hit Hit Hit Hit Hit Hit Hit Hit Hit |
|||
12 Hit Hit Stand Stand Stand Hit Hit Hit Hit Hit |
|||
13 Stand Stand Stand Stand Stand Hit Hit Hit Hit Hit |
|||
14 Stand Stand Stand Stand Stand Hit Hit Hit Hit Hit |
|||
15 Stand Stand Stand Stand Stand Hit Hit Hit Hit Hit |
|||
16 Stand Stand Stand Stand Stand Hit Hit Hit Hit Hit |
|||
17 Stand Stand Stand Stand Stand Stand Stand Stand Stand Stand |
|||
18 Stand Stand Stand Stand Stand Stand Stand Stand Stand Stand |
|||
19 Stand Stand Stand Stand Stand Stand Stand Stand Stand Stand |
|||
20 Stand Stand Stand Stand Stand Stand Stand Stand Stand Stand |
|||
21 Stand Stand Stand Stand Stand Stand Stand Stand Stand Stand |
|||
Soft Chart - Player Expected Gains per unit (Stand) |
|||
P/D 2 3 4 5 6 7 8 9 T A |
|||
—————————————————————————————————————————————————————————————————————————— |
|||
A2 -0.283 -0.241 -0.186 -0.119 -0.114 -0.462 -0.508 -0.517 -0.539 -0.662 |
|||
A3 -0.284 -0.240 -0.170 -0.116 -0.112 -0.460 -0.505 -0.527 -0.538 -0.661 |
|||
A4 -0.283 -0.224 -0.166 -0.113 -0.109 -0.458 -0.514 -0.526 -0.538 -0.659 |
|||
A5 -0.266 -0.221 -0.164 -0.111 -0.108 -0.468 -0.515 -0.525 -0.537 -0.659 |
|||
A6 -0.132 -0.093 -0.037 0.005 0.010 -0.090 -0.385 -0.407 -0.418 -0.483 |
|||
A7 0.136 0.167 0.204 0.222 0.262 0.412 0.121 -0.179 -0.186 -0.101 |
|||
A8 0.402 0.420 0.415 0.461 0.482 0.615 0.608 0.288 0.064 0.290 |
|||
A9 0.656 0.644 0.654 0.682 0.694 0.773 0.785 0.766 0.555 0.681 |
|||
Soft Chart - Player Expected Gains per unit (Hit) |
|||
P/D 2 3 4 5 6 7 8 9 T A |
|||
—————————————————————————————————————————————————————————————————————————— |
|||
A2 0.039 0.071 0.110 0.159 0.168 0.107 0.039 -0.014 -0.090 -0.184 |
|||
A3 0.017 0.044 0.091 0.137 0.147 0.060 0.035 -0.060 -0.124 -0.216 |
|||
A4 -0.012 0.022 0.061 0.108 0.120 0.034 -0.035 -0.114 -0.172 -0.256 |
|||
A5 -0.032 -0.003 0.038 0.082 0.116 -0.024 -0.084 -0.167 -0.229 -0.296 |
|||
A6 0.007 0.036 0.077 0.140 0.133 0.060 -0.065 -0.135 -0.189 -0.242 |
|||
A7 0.065 0.093 0.156 0.175 0.192 0.175 0.047 -0.087 -0.140 -0.160 |
|||
A8 0.120 0.173 0.187 0.227 0.241 0.222 0.158 0.005 -0.087 -0.081 |
|||
A9 0.191 0.196 0.230 0.268 0.280 0.243 0.172 0.096 0.007 -0.008 |
|||
Soft Chart - Player Expected Gains per unit (Double) |
|||
P/D 2 3 4 5 6 7 8 9 T A |
|||
—————————————————————————————————————————————————————————————————————————— |
|||
A2 -0.042 0.028 0.115 0.212 0.230 -0.157 -0.312 -0.373 -0.478 -0.586 |
|||
A3 -0.047 0.011 0.109 0.204 0.222 -0.175 -0.254 -0.394 -0.479 -0.588 |
|||
A4 -0.070 0.003 0.085 0.175 0.201 -0.141 -0.314 -0.422 -0.495 -0.613 |
|||
A5 -0.082 -0.019 0.063 0.148 0.217 -0.189 -0.333 -0.452 -0.536 -0.649 |
|||
A6 0.013 0.074 0.155 0.280 0.266 0.014 -0.230 -0.345 -0.433 -0.522 |
|||
A7 0.128 0.189 0.313 0.349 0.385 0.240 -0.015 -0.254 -0.322 -0.359 |
|||
A8 0.237 0.346 0.373 0.453 0.483 0.325 0.190 -0.060 -0.226 -0.200 |
|||
A9 0.380 0.392 0.459 0.536 0.560 0.351 0.230 0.111 -0.055 -0.055 |
|||
Soft Chart - Player Strategy (Round 1) |
|||
P/D 2 3 4 5 6 7 8 9 T A |
|||
—————————————————————————————————————————————————————————————————————————— |
|||
A2 Hit Hit Double Double Double Hit Hit Hit Hit Hit |
|||
A3 Hit Hit Double Double Double Hit Hit Hit Hit Hit |
|||
A4 Hit Hit Double Double Double Hit Hit Hit Hit Hit |
|||
A5 Hit Hit Double Double Double Hit Hit Hit Hit Hit |
|||
A6 Double Double Double Double Double Hit Hit Hit Hit Hit |
|||
A7 Stand Double Double Double Double Stand Stand Hit Hit Stand |
|||
A8 Stand Stand Stand Stand Double Stand Stand Stand Stand Stand |
|||
A9 Stand Stand Stand Stand Stand Stand Stand Stand Stand Stand |
|||
Soft Chart - Player Strategy (Round >= 2, No Doubling) |
|||
P/D 2 3 4 5 6 7 8 9 T A |
|||
—————————————————————————————————————————————————————————————————————————— |
|||
12 Hit Hit Hit Hit Hit Hit Hit Hit Hit Hit |
|||
13 Hit Hit Hit Hit Hit Hit Hit Hit Hit Hit |
|||
14 Hit Hit Hit Hit Hit Hit Hit Hit Hit Hit |
|||
15 Hit Hit Hit Hit Hit Hit Hit Hit Hit Hit |
|||
16 Hit Hit Hit Hit Hit Hit Hit Hit Hit Hit |
|||
17 Hit Hit Hit Hit Hit Hit Hit Hit Hit Hit |
|||
18 Stand Stand Stand Stand Stand Stand Stand Hit Hit Stand |
|||
19 Stand Stand Stand Stand Stand Stand Stand Stand Stand Stand |
|||
20 Stand Stand Stand Stand Stand Stand Stand Stand Stand Stand |
|||
21 Stand Stand Stand Stand Stand Stand Stand Stand Stand Stand |
|||
Pairs Chart - Player Expected Gains per unit (Stand) |
|||
P/D 2 3 4 5 6 7 8 9 T A |
|||
—————————————————————————————————————————————————————————————————————————— |
|||
AA -0.274 -0.232 -0.178 -0.130 -0.104 -0.452 -0.500 -0.511 -0.531 -0.663 |
|||
22 -0.291 -0.251 -0.192 -0.107 -0.125 -0.471 -0.515 -0.523 -0.547 -0.660 |
|||
33 -0.295 -0.246 -0.160 -0.101 -0.119 -0.467 -0.510 -0.542 -0.546 -0.660 |
|||
44 -0.290 -0.214 -0.152 -0.095 -0.114 -0.463 -0.529 -0.543 -0.547 -0.656 |
|||
55 -0.256 -0.206 -0.146 -0.090 -0.112 -0.484 -0.531 -0.541 -0.545 -0.653 |
|||
66 -0.262 -0.211 -0.152 -0.102 -0.165 -0.493 -0.536 -0.549 -0.552 -0.617 |
|||
77 -0.268 -0.219 -0.164 -0.156 -0.174 -0.502 -0.539 -0.555 -0.510 -0.631 |
|||
88 -0.275 -0.228 -0.215 -0.165 -0.178 -0.503 -0.551 -0.516 -0.518 -0.644 |
|||
99 0.137 0.123 0.167 0.203 0.265 0.401 0.065 -0.196 -0.133 -0.055 |
|||
TT 0.627 0.636 0.645 0.674 0.697 0.765 0.783 0.744 0.583 0.650 |
|||
Pairs Chart - Player Expected Gains per unit (Hit) |
|||
P/D 2 3 4 5 6 7 8 9 T A |
|||
—————————————————————————————————————————————————————————————————————————— |
|||
AA 0.095 0.120 0.142 0.182 0.200 0.158 0.093 -0.003 -0.048 -0.075 |
|||
22 -0.113 -0.082 -0.035 0.036 0.032 -0.092 -0.141 -0.222 -0.277 -0.395 |
|||
33 -0.153 -0.118 -0.047 0.008 0.014 -0.164 -0.231 -0.310 -0.346 -0.444 |
|||
44 -0.013 0.028 0.098 0.154 0.175 0.111 -0.055 -0.206 -0.246 -0.268 |
|||
55 0.224 0.254 0.295 0.347 0.362 0.279 0.207 0.119 0.032 0.042 |
|||
66 -0.253 -0.222 -0.190 -0.162 -0.194 -0.265 -0.322 -0.386 -0.386 -0.411 |
|||
77 -0.406 -0.388 -0.369 -0.370 -0.367 -0.389 -0.408 -0.475 -0.516 -0.510 |
|||
88 -0.454 -0.450 -0.461 -0.453 -0.397 -0.374 -0.426 -0.487 -0.512 -0.490 |
|||
99 -0.627 -0.638 -0.597 -0.590 -0.587 -0.566 -0.566 -0.595 -0.626 -0.621 |
|||
TT -0.847 -0.846 -0.846 -0.846 -0.845 -0.843 -0.843 -0.842 -0.840 -0.882 |
|||
Pairs Chart - Player Expected Gains per unit (Double) |
|||
P/D 2 3 4 5 6 7 8 9 T A |
|||
—————————————————————————————————————————————————————————————————————————— |
|||
AA -0.019 0.055 0.137 0.216 0.248 -0.137 -0.296 -0.421 -0.468 -0.591 |
|||
22 -0.582 -0.501 -0.384 -0.214 -0.249 -0.942 -1.030 -1.047 -1.094 -1.320 |
|||
33 -0.567 -0.472 -0.302 -0.184 -0.215 -0.871 -1.000 -1.065 -1.072 -1.298 |
|||
44 -0.185 -0.082 0.044 0.162 0.193 -0.108 -0.447 -0.701 -0.741 -0.802 |
|||
55 0.446 0.510 0.590 0.695 0.724 0.466 0.323 0.175 0.014 0.042 |
|||
66 -0.505 -0.444 -0.380 -0.325 -0.387 -0.599 -0.711 -0.817 -0.803 -0.823 |
|||
77 -0.813 -0.777 -0.738 -0.741 -0.734 -0.823 -0.858 -0.978 -1.035 -1.019 |
|||
88 -0.908 -0.900 -0.922 -0.906 -0.793 -0.747 -0.853 -0.974 -1.024 -0.980 |
|||
99 -1.255 -1.277 -1.194 -1.181 -1.173 -1.132 -1.133 -1.189 -1.252 -1.242 |
|||
TT -1.693 -1.693 -1.693 -1.691 -1.690 -1.686 -1.685 -1.684 -1.681 -1.764 |
|||
Pairs Chart - Player Expected Gains per unit (Split) |
|||
P/D 2 3 4 5 6 7 8 9 T A |
|||
—————————————————————————————————————————————————————————————————————————— |
|||
AA 1.192 1.223 1.265 1.321 1.344 1.308 1.201 1.039 0.860 0.921 |
|||
22 -0.128 -0.070 -0.007 0.128 0.126 -0.054 -0.213 -0.383 -0.463 -0.566 |
|||
33 -0.202 -0.128 0.009 0.117 0.112 -0.115 -0.265 -0.418 -0.509 -0.579 |
|||
44 -0.236 -0.127 -0.013 0.095 0.083 -0.223 -0.343 -0.493 -0.580 -0.623 |
|||
55 -0.232 -0.150 -0.038 0.068 0.056 -0.299 -0.448 -0.608 -0.685 -0.695 |
|||
66 -0.219 -0.135 -0.028 0.068 -0.011 -0.270 -0.413 -0.570 -0.652 -0.660 |
|||
77 -0.163 -0.084 0.016 0.039 0.053 -0.123 -0.423 -0.564 -0.634 -0.635 |
|||
88 0.017 0.077 0.106 0.188 0.234 0.202 -0.100 -0.430 -0.464 -0.378 |
|||
99 0.170 0.170 0.253 0.339 0.359 0.341 0.179 -0.112 -0.268 -0.109 |
|||
TT 0.412 0.465 0.518 0.596 0.619 0.576 0.447 0.276 0.146 0.140 |
|||
Pairs Chart - Player Strategy (Round 1) |
|||
P/D 2 3 4 5 6 7 8 9 T A |
|||
—————————————————————————————————————————————————————————————————————————— |
|||
AA Split Split Split Split Split Split Split Split Split Split |
|||
22 Hit Split Split Split Split Split Hit Hit Hit Hit |
|||
33 Hit Hit Split Split Split Split Hit Hit Hit Hit |
|||
44 Hit Hit Hit Double Double Hit Hit Hit Hit Hit |
|||
55 Double Double Double Double Double Double Double Double Hit Double |
|||
66 Split Split Split Split Split Hit Hit Hit Hit Hit |
|||
77 Split Split Split Split Split Split Hit Hit Stand Hit |
|||
88 Split Split Split Split Split Split Split Split Split Split |
|||
99 Split Split Split Split Split Stand Split Split Stand Stand |
|||
TT Stand Stand Stand Stand Stand Stand Stand Stand Stand Stand |
|||
Simulation for year 1: |
|||
After playing 50 times a day for 365 days: |
|||
Winning days: 179 |
|||
Losing days: 180 |
|||
Breakeven days: 6 |
|||
Biggest win: 33.0 |
|||
Biggest loss: 22.5 |
|||
Total win: 144.0 |
|||
Total staked: 20623.0 |
|||
Win % staked: 0.698 |
|||
Simulation for year 2: |
|||
After playing 50 times a day for 365 days: |
|||
Winning days: 168 |
|||
Losing days: 184 |
|||
Breakeven days: 13 |
|||
Biggest win: 25.5 |
|||
Biggest loss: 25.0 |
|||
Total loss: 233.0 |
|||
Total staked: 20553.0 |
|||
Loss % staked: 1.134 |
|||
Simulation for year 3: |
|||
After playing 50 times a day for 365 days: |
|||
Winning days: 177 |
|||
Losing days: 176 |
|||
Breakeven days: 12 |
|||
Biggest win: 25.5 |
|||
Biggest loss: 22.0 |
|||
Total loss: 18.5 |
|||
Total staked: 20646.0 |
|||
Loss % staked: 0.090 |
|||
Simulation for year 4: |
|||
After playing 50 times a day for 365 days: |
|||
Winning days: 193 |
|||
Losing days: 164 |
|||
Breakeven days: 8 |
|||
Biggest win: 26.5 |
|||
Biggest loss: 22.0 |
|||
Total win: 210.5 |
|||
Total staked: 20635.0 |
|||
Win % staked: 1.020 |
|||
Simulation for year 5: |
|||
After playing 50 times a day for 365 days: |
|||
Winning days: 161 |
|||
Losing days: 191 |
|||
Breakeven days: 13 |
|||
Biggest win: 25.0 |
|||
Biggest loss: 31.0 |
|||
Total loss: 270.0 |
|||
Total staked: 20502.0 |
|||
Loss % staked: 1.317 |
|||
Simulation for year 6: |
|||
After playing 50 times a day for 365 days: |
|||
Winning days: 182 |
|||
Losing days: 175 |
|||
Breakeven days: 8 |
|||
Biggest win: 23.0 |
|||
Biggest loss: 26.0 |
|||
Total win: 104.0 |
|||
Total staked: 20610.0 |
|||
Win % staked: 0.505 |
|||
Simulation for year 7: |
|||
After playing 50 times a day for 365 days: |
|||
Winning days: 178 |
|||
Losing days: 181 |
|||
Breakeven days: 6 |
|||
Biggest win: 19.0 |
|||
Biggest loss: 21.5 |
|||
Total loss: 86.0 |
|||
Total staked: 20546.0 |
|||
Loss % staked: 0.419 |
|||
Simulation for year 8: |
|||
After playing 50 times a day for 365 days: |
|||
Winning days: 178 |
|||
Losing days: 177 |
|||
Breakeven days: 10 |
|||
Biggest win: 26.5 |
|||
Biggest loss: 21.0 |
|||
Total loss: 127.5 |
|||
Total staked: 20522.0 |
|||
Loss % staked: 0.621 |
|||
Simulation for year 9: |
|||
After playing 50 times a day for 365 days: |
|||
Winning days: 173 |
|||
Losing days: 184 |
|||
Breakeven days: 8 |
|||
Biggest win: 25.0 |
|||
Biggest loss: 24.0 |
|||
Total loss: 14.5 |
|||
Total staked: 20551.0 |
|||
Loss % staked: 0.071 |
|||
Simulation for year 10: |
|||
After playing 50 times a day for 365 days: |
|||
Winning days: 170 |
|||
Losing days: 178 |
|||
Breakeven days: 17 |
|||
Biggest win: 20.0 |
|||
Biggest loss: 21.5 |
|||
Total loss: 93.0 |
|||
Total staked: 20516.0 |
|||
Loss % staked: 0.453</pre> |
|||
=={{header|Phix}}== |
=={{header|Phix}}== |