Blackjack strategy: Difference between revisions

m
→‎{{header|Wren}}: Changed to Wren S/H
m (→‎{{header|Wren}}: Changed to Wren S/H)
 
(6 intermediate revisions by 3 users not shown)
Line 1:
{{draft task}} [[Category:Games]]
{{draft task}} The objective of this task is to recreate and explore the following [https://web.archive.org/web/20130625120019/http://www.blackjacktactics.com/blackjack/strategy/charts/single-deck/ strategy charts] for the game of [[wp:Blackjack|blackjack]] (which is known by many other names as well).
 
Assume that my casino:
Line 25:
* What can I expect to be my biggest loss?
* What can I expect to win/lose over the year?
 
=={{header|Go}}==
As the dealer plays automatically, the first thing I did was to write a function which calculates the probabilities of the dealer ending up with various scores according to the Rules. I then checked the resulting table against a similar one on an 'active' online gambling site (which I'd better not link to here) and the results agreed to 6 decimal places.
Line 42 ⟶ 41:
 
Finally, I've done 10 years of simulations as the basic statistics can vary quite a bit from year to year. However, it will be seen that % loss varies over a narrower range - between about 0.3 and 1.8% for this particular run - which seems reasonable given the casino's edge even after basic strategy is utilized.
<langsyntaxhighlight lang="go">package main
 
import (
Line 950 ⟶ 949:
simulate(50, 365)
}
}</langsyntaxhighlight>
 
{{out}}
Line 1,318 ⟶ 1,317:
Loss % staked : 1.801
</pre>
 
=={{header|Nim}}==
{{trans|Go}}
<langsyntaxhighlight Nimlang="nim">import random, sequtils, strformat, strutils
 
type
Line 2,149 ⟶ 2,147:
simulate(50, 365)
 
main()</langsyntaxhighlight>
 
{{out}}
Line 2,514 ⟶ 2,512:
Total staked: 20516.0
Loss % staked: 0.453</pre>
 
=={{header|Phix}}==
{{trans|Go}}
<!--<langsyntaxhighlight Phixlang="phix">-->
<span style="color: #000080;font-style:italic;">-- demo/rosetta/blackjack.exw</span>
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
-- demo/rosetta/blackjack.exw
-- ==========================
--</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">NewDeck</span><span style="color: #0000FF;">()</span>
<span style="color: #008080;">return</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">4</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">4</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">4</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">4</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">4</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">4</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">4</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">4</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">4</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">16</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">52</span><span style="color: #0000FF;">}</span>
Line 2,554 ⟶ 2,550:
<span style="color: #008080;">elsif</span> <span style="color: #000000;">decks</span><span style="color: #0000FF;">[</span><span style="color: #000000;">lev</span><span style="color: #0000FF;">][</span><span style="color: #000000;">c</span><span style="color: #0000FF;">]!=</span><span style="color: #000000;">0</span> <span style="color: #008080;">then</span> <span style="color: #000080;font-style:italic;">-- card still present in deck
// temporary variables for current level</span>
<span style="color: #004080;">sequence</span> <span style="color: #000000;">deck</span> <span style="color: #0000FF;">:=</span> <span style="color: #7060A8;">deep_copy</span><span style="color: #0000FF;">(</span><span style="color: #000000;">decks</span><span style="color: #0000FF;">[</span><span style="color: #000000;">lev</span><span style="color: #0000FF;">])</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">score</span> <span style="color: #0000FF;">:=</span> <span style="color: #000000;">scores</span><span style="color: #0000FF;">[</span><span style="color: #000000;">lev</span><span style="color: #0000FF;">]</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">eleven</span> <span style="color: #0000FF;">:=</span> <span style="color: #000000;">elevens</span><span style="color: #0000FF;">[</span><span style="color: #000000;">lev</span><span style="color: #0000FF;">]</span>
Line 2,604 ⟶ 2,600:
<span style="color: #000000;">deck</span><span style="color: #0000FF;">[</span><span style="color: #000000;">11</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">51</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">uc</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">10</span> <span style="color: #008080;">do</span>
<span style="color: #004080;">sequence</span> <span style="color: #000000;">deck2</span> <span style="color: #0000FF;">:=</span> <span style="color: #7060A8;">deep_copy</span><span style="color: #0000FF;">(</span><span style="color: #000000;">deck</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">deck2</span><span style="color: #0000FF;">[</span><span style="color: #000000;">uc</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">-=</span> <span style="color: #000000;">1</span>
<span style="color: #004080;">sequence</span> <span style="color: #000000;">dp</span> <span style="color: #0000FF;">:=</span> <span style="color: #000000;">dealerProbs</span><span style="color: #0000FF;">(</span><span style="color: #000000;">uc</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">deck2</span><span style="color: #0000FF;">)</span>
Line 2,659 ⟶ 2,655:
<span style="color: #008080;">if</span> <span style="color: #000000;">deck</span><span style="color: #0000FF;">[</span><span style="color: #000000;">c</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">!=</span> <span style="color: #000000;">0</span> <span style="color: #008080;">then</span> <span style="color: #000080;font-style:italic;">// card still present in deck
// temporary variables for current card</span>
<span style="color: #004080;">sequence</span> <span style="color: #000000;">deck2</span> <span style="color: #0000FF;">:=</span> <span style="color: #7060A8;">deep_copy</span><span style="color: #0000FF;">(</span><span style="color: #000000;">deck</span><span style="color: #0000FF;">)</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">score2</span> <span style="color: #0000FF;">:=</span> <span style="color: #000000;">score</span>
<span style="color: #000080;font-style:italic;">--DEV shouldn't this be false?</span>
Line 2,709 ⟶ 2,705:
<span style="color: #008080;">elsif</span> <span style="color: #000000;">decks</span><span style="color: #0000FF;">[</span><span style="color: #000000;">lev</span><span style="color: #0000FF;">][</span><span style="color: #000000;">c</span><span style="color: #0000FF;">]!=</span><span style="color: #000000;">0</span> <span style="color: #008080;">then</span> <span style="color: #000080;font-style:italic;">-- card still present in deck
// temporary variables for current level</span>
<span style="color: #004080;">sequence</span> <span style="color: #000000;">deck</span> <span style="color: #0000FF;">:=</span> <span style="color: #7060A8;">deep_copy</span><span style="color: #0000FF;">(</span><span style="color: #000000;">decks</span><span style="color: #0000FF;">[</span><span style="color: #000000;">lev</span><span style="color: #0000FF;">])</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">score</span> <span style="color: #0000FF;">:=</span> <span style="color: #000000;">scores</span><span style="color: #0000FF;">[</span><span style="color: #000000;">lev</span><span style="color: #0000FF;">]</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">eleven</span> <span style="color: #0000FF;">:=</span> <span style="color: #000000;">elevens</span><span style="color: #0000FF;">[</span><span style="color: #000000;">lev</span><span style="color: #0000FF;">]</span>
Line 2,759 ⟶ 2,755:
<span style="color: #004080;">sequence</span> <span style="color: #000000;">egs</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">10</span><span style="color: #0000FF;">)</span> <span style="color: #000080;font-style:italic;">// results</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">uc</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">10</span> <span style="color: #008080;">do</span> <span style="color: #000080;font-style:italic;">// dealer's up-card</span>
<span style="color: #004080;">sequence</span> <span style="color: #000000;">deck2</span> <span style="color: #0000FF;">:=</span> <span style="color: #7060A8;">deep_copy</span><span style="color: #0000FF;">(</span><span style="color: #000000;">deck</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">deck2</span><span style="color: #0000FF;">[</span><span style="color: #000000;">uc</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">-=</span> <span style="color: #000000;">1</span>
<span style="color: #000000;">deck2</span><span style="color: #0000FF;">[</span><span style="color: #000000;">11</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">-=</span> <span style="color: #000000;">1</span>
Line 2,782 ⟶ 2,778:
<span style="color: #004080;">sequence</span> <span style="color: #000000;">egs</span> <span style="color: #0000FF;">=</span><span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">10</span><span style="color: #0000FF;">)</span> <span style="color: #000080;font-style:italic;">// results</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">uc</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">10</span> <span style="color: #008080;">do</span> <span style="color: #000080;font-style:italic;">// dealer's up-card</span>
<span style="color: #004080;">sequence</span> <span style="color: #000000;">deck2</span> <span style="color: #0000FF;">:=</span> <span style="color: #7060A8;">deep_copy</span><span style="color: #0000FF;">(</span><span style="color: #000000;">deck</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">deck2</span><span style="color: #0000FF;">[</span><span style="color: #000000;">uc</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">-=</span> <span style="color: #000000;">1</span>
<span style="color: #000000;">deck2</span><span style="color: #0000FF;">[</span><span style="color: #000000;">11</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">49</span>
Line 2,800 ⟶ 2,796:
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<span style="color: #008080;">function</span> <span style="color: #004080000000;">double</span><span style="color: #0000FF;">(</span><span style="color: #004080;">integer</span> <span style="color: #000000;">card1</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">card2</span><span style="color: #0000FF;">)</span>
<span style="color: #000080;font-style:italic;">// Returns player's expected gains per unit oiginally staked, for each dealer up-card, after
// doubling i.e. hitting once and then standing with a doubled stake.</span>
Line 2,838 ⟶ 2,834:
<span style="color: #008080;">for</span> <span style="color: #000000;">uc</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">10</span> <span style="color: #008080;">do</span> <span style="color: #000080;font-style:italic;">// collect results for each dealer up-card</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">deck</span><span style="color: #0000FF;">[</span><span style="color: #000000;">uc</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">!=</span> <span style="color: #000000;">0</span> <span style="color: #008080;">then</span> <span style="color: #000080;font-style:italic;">// card still present in deck</span>
<span style="color: #004080;">sequence</span> <span style="color: #000000;">deck2</span> <span style="color: #0000FF;">:=</span> <span style="color: #7060A8;">deep_copy</span><span style="color: #0000FF;">(</span><span style="color: #000000;">deck</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">deck2</span><span style="color: #0000FF;">[</span><span style="color: #000000;">uc</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">-=</span> <span style="color: #000000;">1</span>
<span style="color: #000000;">deck2</span><span style="color: #0000FF;">[</span><span style="color: #000000;">11</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">-=</span> <span style="color: #000000;">1</span>
Line 2,850 ⟶ 2,846:
<span style="color: #008080;">if</span> <span style="color: #000000;">deck2</span><span style="color: #0000FF;">[</span><span style="color: #000000;">c</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">!=</span> <span style="color: #000000;">0</span> <span style="color: #008080;">then</span> <span style="color: #000080;font-style:italic;">// card still present in deck</span>
<span style="color: #004080;">atom</span> <span style="color: #000000;">prob</span> <span style="color: #0000FF;">:=</span> <span style="color: #000000;">deck2</span><span style="color: #0000FF;">[</span><span style="color: #000000;">c</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">/</span> <span style="color: #000000;">deck2</span><span style="color: #0000FF;">[</span><span style="color: #000000;">11</span><span style="color: #0000FF;">]</span>
<span style="color: #004080;">sequence</span> <span style="color: #000000;">deck3</span> <span style="color: #0000FF;">:=</span> <span style="color: #7060A8;">deep_copy</span><span style="color: #0000FF;">(</span><span style="color: #000000;">deck2</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">deck3</span><span style="color: #0000FF;">[</span><span style="color: #000000;">c</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">-=</span> <span style="color: #000000;">1</span>
<span style="color: #000000;">deck3</span><span style="color: #0000FF;">[</span><span style="color: #000000;">11</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">-=</span> <span style="color: #000000;">1</span>
Line 2,895 ⟶ 2,891:
<span style="color: #008080;">function</span> <span style="color: #000000;">bestAction</span><span style="color: #0000FF;">(</span><span style="color: #004080;">sequence</span> <span style="color: #000000;">ags</span><span style="color: #0000FF;">)</span>
<span style="color: #000080;font-style:italic;">// Returns the action with the highest expected gain.</span>
<span style="color: #004080;">atom</span> <span style="color: #7060A8000000;">maxbest</span> <span style="color: #0000FF;">:=</span> <span style="color: #000000;">ags</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">][</span><span style="color: #000000;">2</span><span style="color: #0000FF;">]</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">maxibesti</span> <span style="color: #0000FF;">:=</span> <span style="color: #000000;">1</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">2</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">ags</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">ags</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">][</span><span style="color: #000000;">2</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">></span> <span style="color: #7060A8000000;">maxbest</span> <span style="color: #008080;">then</span>
<span style="color: #7060A8000000;">maxbest</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">ags</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">][</span><span style="color: #000000;">2</span><span style="color: #0000FF;">]</span>
<span style="color: #000000;">maxibesti</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">i</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #008080;">return</span> <span style="color: #000000;">ags</span><span style="color: #0000FF;">[</span><span style="color: #000000;">maxibesti</span><span style="color: #0000FF;">][</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
Line 3,180 ⟶ 3,176:
<span style="color: #004080;">sequence</span> <span style="color: #000000;">degs</span> <span style="color: #0000FF;">:=</span> <span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">10</span><span style="color: #0000FF;">),</span><span style="color: #000000;">15</span><span style="color: #0000FF;">)</span> <span style="color: #000080;font-style:italic;">// if doubles</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">t</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">tuples</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
<span style="color: #7060A8008080;">progressif</span><span style="color: #0000FF;">(</span><span style="color: #0080007060A8;">"%d/%d\r"platform</span><span style="color: #0000FF;">,{</span><span style()!="color: #000000;">t</span><span style="color: #0000FF004600;">,JS</span><span style="color: #7060A8;">length</span><span style="color: #0000FF008080;">(</span><span style="color: #000000;">tuples</span><span style="color: #0000FF;">)})then</span>
<span style="color: #7060A8;">progress</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"%d/%d\r"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">t</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">tuples</span><span style="color: #0000FF;">)})</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #004080;">sequence</span> <span style="color: #000000;">tuple</span> <span style="color: #0000FF;">:=</span> <span style="color: #000000;">tuples</span><span style="color: #0000FF;">[</span><span style="color: #000000;">t</span><span style="color: #0000FF;">]</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">i</span> <span style="color: #0000FF;">:=</span> <span style="color: #000000;">tuple</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">+</span> <span style="color: #000000;">tuple</span><span style="color: #0000FF;">[</span><span style="color: #000000;">2</span><span style="color: #0000FF;">]</span>
<span style="color: #004080;">sequence</span> <span style="color: #000000;">sg</span> <span style="color: #0000FF;">:=</span> <span style="color: #000000;">stand</span><span style="color: #0000FF;">(</span><span style="color: #000000;">tuple</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">],</span> <span style="color: #000000;">tuple</span><span style="color: #0000FF;">[</span><span style="color: #000000;">2</span><span style="color: #0000FF;">])</span>
<span style="color: #004080;">sequence</span> <span style="color: #000000;">hg</span> <span style="color: #0000FF;">:=</span> <span style="color: #000000;">hit</span><span style="color: #0000FF;">(</span><span style="color: #000000;">tuple</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">],</span> <span style="color: #000000;">tuple</span><span style="color: #0000FF;">[</span><span style="color: #000000;">2</span><span style="color: #0000FF;">],</span> <span style="color: #004600;">false</span><span style="color: #0000FF;">)</span>
<span style="color: #004080;">sequence</span> <span style="color: #000000;">dg</span> <span style="color: #0000FF;">:=</span> <span style="color: #004080000000;">double</span><span style="color: #0000FF;">(</span><span style="color: #000000;">tuple</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">],</span> <span style="color: #000000;">tuple</span><span style="color: #0000FF;">[</span><span style="color: #000000;">2</span><span style="color: #0000FF;">])</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">j</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">10</span> <span style="color: #008080;">do</span>
<span style="color: #000000;">segs</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">-</span><span style="color: #000000;">4</span><span style="color: #0000FF;">][</span><span style="color: #000000;">j</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">sg</span><span style="color: #0000FF;">[</span><span style="color: #000000;">j</span><span style="color: #0000FF;">]</span>
Line 3,192 ⟶ 3,190:
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #008080;">if</span> <span style="color: #7060A8;">progressplatform</span><span style="color: #0000FF;">()!=</span><span style="color: #008000004600;">""JS</span> <span style="color: #0000FF008080;">)then</span>
<span style="color: #7060A8;">progress</span><span style="color: #0000FF;">(</span><span style="color: #008000;">""</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #000080;font-style:italic;">// calculate the average per tuple for each score</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">15</span> <span style="color: #008080;">do</span>
Line 3,284:
<span style="color: #004080;">sequence</span> <span style="color: #000000;">sg</span> <span style="color: #0000FF;">:=</span> <span style="color: #000000;">stand</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">c</span><span style="color: #0000FF;">),</span>
<span style="color: #000000;">hg</span> <span style="color: #0000FF;">:=</span> <span style="color: #000000;">hit</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">c</span><span style="color: #0000FF;">,</span> <span style="color: #004600;">false</span><span style="color: #0000FF;">),</span>
<span style="color: #000000;">dg</span> <span style="color: #0000FF;">:=</span> <span style="color: #004080000000;">double</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">c</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">j</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">10</span> <span style="color: #008080;">do</span>
<span style="color: #000000;">segs3</span><span style="color: #0000FF;">[</span><span style="color: #000000;">c</span><span style="color: #0000FF;">-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">][</span><span style="color: #000000;">j</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">sg</span><span style="color: #0000FF;">[</span><span style="color: #000000;">j</span><span style="color: #0000FF;">]</span>
Line 3,370:
<span style="color: #000000;">pegs5</span> <span style="color: #0000FF;">:=</span> <span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">10</span><span style="color: #0000FF;">),</span><span style="color: #000000;">10</span><span style="color: #0000FF;">)</span> <span style="color: #000080;font-style:italic;">// if splits</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">c</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">10</span> <span style="color: #008080;">do</span>
<span style="color: #7060A8008080;">progressif</span><span style="color: #0000FF;">(</span><span style="color: #0080007060A8;">"%d/10"platform</span><span style="color: #0000FF;">,{()!=</span><span style="color: #000000004600;">cJS</span> <span style="color: #0000FF008080;">})then</span>
<span style="color: #7060A8;">progress</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"%d/10"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">c</span><span style="color: #0000FF;">})</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #004080;">sequence</span> <span style="color: #000000;">sg</span> <span style="color: #0000FF;">:=</span> <span style="color: #000000;">stand</span><span style="color: #0000FF;">(</span><span style="color: #000000;">c</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">c</span><span style="color: #0000FF;">),</span>
<span style="color: #000000;">hg</span> <span style="color: #0000FF;">:=</span> <span style="color: #000000;">hit</span><span style="color: #0000FF;">(</span><span style="color: #000000;">c</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">c</span><span style="color: #0000FF;">,</span> <span style="color: #004600;">false</span><span style="color: #0000FF;">),</span>
<span style="color: #000000;">dg</span> <span style="color: #0000FF;">:=</span> <span style="color: #004080000000;">double</span><span style="color: #0000FF;">(</span><span style="color: #000000;">c</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">c</span><span style="color: #0000FF;">),</span>
<span style="color: #000000;">pg</span> <span style="color: #0000FF;">:=</span> <span style="color: #000000;">splitt</span><span style="color: #0000FF;">(</span><span style="color: #000000;">c</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">j</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">10</span> <span style="color: #008080;">do</span>
Line 3,382 ⟶ 3,384:
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #008080;">if</span> <span style="color: #7060A8;">progressplatform</span><span style="color: #0000FF;">()!=</span><span style="color: #008000004600;">""JS</span> <span style="color: #0000FF008080;">)then</span>
<span style="color: #7060A8;">progress</span><span style="color: #0000FF;">(</span><span style="color: #008000;">""</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #000000;">printHeader</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"\nPairs Chart - Player Expected Gains per unit (Stand)"</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">c</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">10</span> <span style="color: #008080;">do</span>
Line 3,439 ⟶ 3,443:
<span style="color: #008080;">end</span> <span style="color: #008080;">procedure</span>
<span style="color: #000000;">main</span><span style="color: #0000FF;">()</span>
<span style="color: #0000FF;">?</span><span style="color: #008000;">"done"</span>
<!--</lang>-->
<span style="color: #0000FF;">{}</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">wait_key</span><span style="color: #0000FF;">()</span>
<!--</syntaxhighlight>-->
{{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 original 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
Line 3,740 ⟶ 3,812:
Total staked :20436.00
Loss % staked : 0.073
</pre>
=={{header|Wren}}==
{{trans|Go}}
{{libheader|Wren-array}}
{{libheader|Wren-dynamic}}
{{libheader|Wren-fmt}}
{{libheader|Wren-iterate}}
<br>
This runs OK but takes a long time to do so - 6 minutes 21 seconds compared to less than 3 seconds for the Go example. As I also wrote the latter I'm confident it's a faithful translation.
 
The bottleneck seems to be the ''dealerProbs'' method which is called around 300,000 times during the course of the program and contains several arrays (heap allocated in Wren) plus a recursive closure and so is not cheap to run. Making the arrays global and resetting them each time the method is called doesn't help and memoization is out of the question as there are just too many parameter combinations.
 
So interpreted languages such as Wren are probably stuck with slow times for this task.
<syntaxhighlight lang="wren">import "random" for Random
import "./array" for Array, ArrayType
import "./dynamic" for Struct
import "./fmt" for Fmt
import "./iterate" for Indexed
 
var Rand = Random.new()
 
// 0: deck size, 1 to 10: number of cards of that denomination
var Deck = ArrayType.create("Deck", 11, 0)
 
var ActionGain = Struct.create("ActionGain", ["action", "gain"])
 
var NewDeck = Fn.new { Deck.fit([52, 4, 4, 4, 4, 4, 4, 4, 4, 4, 16]) }
 
// Computed strategy tables
var HTable = List.filled(15, null) // hard strategy table (round 1)
var STable = List.filled( 8, null) // soft strategy table (round 1)
var PTable = List.filled(10, null) // pairs strategy table (round 1)
var HTable2 = List.filled(18, null) // hard strategy table (round >= 2, no doubling)
var STable2 = List.filled(10, null) // soft strategy table (round >= 2, no doubling)
 
for (i in 0..14) HTable[i] = List.filled(10, null)
for (i in 0..7) STable[i] = List.filled(10, null)
for (i in 0..9) PTable[i] = List.filled(10, null)
for (i in 0..17) HTable2[i] = List.filled(10, null)
for (i in 0..9) STable2[i] = List.filled(10, null)
 
class Blackjack {
// 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.
static dealerProbs(upCard, startDeck) {
var res = List.filled(7, 0) // results
var decks = List.filled(9, null) // decks for each level
var scores = List.filled(9, 0) // scores for each level
var elevens = List.filled(9, 0) // number of aces for each level scored as 11
var probs = List.filled(9, 0) // probs for each level
decks[0] = startDeck.toList
scores[0] = upCard
if (upCard == 1) { // an ace
scores[0] = 11
elevens[0] = 1
}
probs[0] = 1
var f // recursive closure
f = Fn.new { |lev|
for (c in 1..10) {
if (decks[lev][c] == 0) continue // card no longer present in deck
// temporary variables for current level
var deck = decks[lev].toList
var score = scores[lev]
var eleven = elevens[lev]
var prob = probs[lev]
score = score + c // add card to score
if (c == 1) { // score all aces initially as 11
score = score + 10
eleven = eleven + 1
}
prob = prob * deck[c] / deck[0]
if (score > 21 && eleven > 0) {
score = score - 10 // bust but can demote an ace
eleven = eleven - 1
}
if (lev == 0 && ((upCard == 1 && c == 10) || (upCard == 10 && c == 1))) {
res[5] = res[5] + prob // blackjack, allow for now
} else if (score >= 17 && score <= 21) {
res[score-17] = res[score-17] + prob // 17 to (non-blackjack) 21
} else if (score > 21 && eleven == 0) {
res[6] = res[6] + prob // bust
} else {
deck[c] = deck[c] - 1 // remove card from deck
deck[0] = deck[0] - 1 // decrement deck size
var lev2 = lev + 1
decks[lev2] = deck
scores[lev2] = score
elevens[lev2] = eleven
probs[lev2] = prob
f.call(lev2) // get another card
}
}
}
f.call(0)
// but can't have blackjack, so adjust probabilities accordingly
var pnbj = 1 - res[5]
for (i in 0..6) res[i] = res[i] / pnbj
res[5] = 0
return res
}
 
// Prints chart of dealer probabilities (as a check against an external source).
static dealerChart() {
System.print("Dealer Probabilities, Stands on Soft 17, 1 Deck, U.S Rules")
System.print("Up Card 17 18 19 20 21 Bust")
System.print("-------------------------------------------------------------------")
var deck = NewDeck.call()
deck[0] = 51
for (uc in 1..10) {
var deck2 = deck.toList
deck2[uc] = deck2[uc] - 1
var dp = dealerProbs(uc, deck2)
if (uc > 1) {
Fmt.write("$3d ", uc)
} else {
System.write("Ace ")
}
Fmt.lprint("$f $f $f $f $f $f", [dp[0], dp[1], dp[2], dp[3], dp[4], dp[6]])
}
}
 
// Returns player's expected gain per unit staked after hitting once and then standing.
static playerGain(card1, card2, uc, startDeck) {
var eg = 0
var deck = startDeck.toList
var score = card1 + card2
var eleven = false
if (card1 == 1 || card2 == 1) { // an ace
score = score + 10
eleven = true
}
for (c in 1..10) { // get another card
if (deck[c] == 0) continue // card no longer present in deck
// temporary variables for current card
var deck2 = deck.toList
var score2 = score
var eleven2 = eleven
score2 = score2 + c // add card to score
if (c == 1) { // score all aces initially as 11
score2 = score2 + 10
eleven2 = true
}
var prob = deck2[c] / deck2[0]
deck2[c] = deck2[c] - 1 // remove card from deck
deck2[0] = deck2[0] - 1 // decrement deck size
if (score2 > 21 && eleven2) {
score2 = score2 - 10 // bust but can demote an ace
}
if (score2 <= 21) {
var dp = dealerProbs(uc, deck2)
eg = eg + calcGain(score2, dp) * prob
} else { // bust
eg = eg - prob
}
}
return eg
}
 
// Returns player's expected gain per unit staked after hitting once and then continuing
// in accordance with the tables for rounds >= 2.
static playerGain2(card1, card2, uc, startDeck) {
var eg = 0 // result
var decks = List.filled(9, null) // decks for each level
var scores = List.filled(9, 0) // scores for each level
var elevens = List.filled(9, 0) // number of aces for each level scored as 11
var probs = List.filled(9, 0) // probs for each level
decks[0] = startDeck.toList
scores[0] = card1 + card2
if (card1 == 1 || card2 == 1) { // an ace
scores[0] = scores[0] + 10
elevens[0] = 1
}
probs[0] = 1
var f // recursive closure
f = Fn.new { |lev|
for (c in 1..10) {
if (decks[lev][c] == 0) continue // card no longer present in deck
// temporary variables for current level
var deck = decks[lev].toList
var score = scores[lev]
var eleven = elevens[lev]
var prob = probs[lev]
score = score + c // add card to score
if (c == 1) { // score all aces initially as 11
score = score + 10
eleven = eleven + 1
}
prob = prob * deck[c] / deck[0]
if (score > 21 && eleven > 0) {
score = score - 10 // bust but can demote an ace
eleven = eleven - 1
}
deck[c] = deck[c] - 1 // remove card from deck
deck[0] = deck[0] - 1 // decrement deck size
if ((eleven == 0 && (score >= 17 || (score >= 13 && uc < 7)) ||
(eleven == 0 && score == 12 && uc >= 4 && uc <= 6) ||
(eleven > 0 && score == 18 && uc != 9 && uc != 10) ||
(eleven > 0 && score >= 19)) && score <= 21) {
var dp = dealerProbs(uc, deck)
eg = eg + calcGain(score, dp) * prob
} else if (score > 21 && eleven == 0) { // bust
eg = eg - prob
} else {
var lev2 = lev + 1
decks[lev2] = deck
scores[lev2] = score
elevens[lev2] = eleven
probs[lev2] = prob
f.call(lev2) // get another card
}
}
}
f.call(0)
return eg
}
 
// Calculates gain per unit staked for a given scenario (helper function).
static calcGain(pscore, dp) {
var eg = 0
if (pscore == 17) {
eg = eg + dp[6] // dealer is bust
eg = eg - dp[1] - dp[2] - dp[3] - dp[4] // dealer has 18 to 21
} else if (pscore == 18) {
eg = eg + dp[0] + dp[6] // dealer has 17 or is bust
eg = eg - dp[2] - dp[3] - dp[4] // dealer has 19 to 21
} else if (pscore == 19) {
eg = eg + dp[0] + dp[1] + dp[6] // dealer has 17, 18 or is bust
eg = eg - dp[3] - dp[4] // dealer has 20 or 21
} else if (pscore == 20) {
eg = eg + dp[0] + dp[1] + dp[2] + dp[6] // dealer has 17 to 19 or is bust
eg = eg - dp[4] // dealer has (non-blackjack) 21
} else if (pscore == 21) {
eg = eg + dp[0] + dp[1] + dp[2] + dp[3] + dp[6] // dealer has 17 to 20 or is bust
} else if (pscore == 22) { // notional
eg = eg + 1.5 // player blackjack
} else if (pscore == 23) { // notional
eg = eg - 1 // player bust, loses stake irrespective of what dealer has
} else { // player has less than 17
eg = eg + dp[6] // dealer is bust
eg = eg - (1 - dp[6]) // dealer isn't bust
}
return eg
}
 
// Returns player's expected gains per unit staked, for each dealer up-card, after standing.
static stand(card1, card2) {
var deck = NewDeck.call()
deck[card1] = deck[card1] - 1
deck[card2] = deck[card2] - 1
deck[0] = 50
var pscore = card1 + card2 // player score
if (card1 == 1 || card2 == 1) pscore = pscore + 10
var egs = List.filled(10, 0) // results
for (uc in 1..10) { // dealer's up-card
var deck2 = deck.toList
deck2[uc] = deck2[uc] - 1
deck2[0] = deck2[0] - 1
var dp = dealerProbs(uc, deck2)
var eg = calcGain(pscore, dp) // expected gain for this up-card
if (uc > 1) {
egs[uc-2] = eg
} else { // dealer has Ace
egs[9] = eg // ace comes last in tables
}
}
return egs
}
 
// Returns 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).
static hit(card1, card2, once) {
var deck = NewDeck.call()
deck[card1] = deck[card1] - 1
deck[card2] = deck[card2] - 1
deck[0] = 50
var egs = List.filled(10, 0) // results
for (uc in 1..10) { // dealer's up-card
var deck2 = deck.toList
deck2[uc] = deck2[uc] - 1
deck2[0] = 49
var peg = once ? playerGain (card1, card2, uc, deck2) :
playerGain2(card1, card2, uc, deck2)
if (uc > 1) {
egs[uc-2] = peg
} else { // dealer has Ace
egs[9] = peg
}
}
return egs
}
 
// Returns player's expected gains per unit oiginally staked, for each dealer up-card,
// after doubling i.e. hitting once and then standing with a doubled stake.
static double(card1, card2) {
var egs = hit(card1, card2, true) // hit once and then stand
for (i in 0..9) egs[i] = egs[i] * 2
return egs
}
 
// Returns 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.
static split(card) {
var deck = NewDeck.call()
deck[card] = deck[card] - 2 // must be a pair
deck[0] = 50
var egs = List.filled(10, 0) // overall results
 
// now play a single hand
var score = card
var eleven = 0
if (card == 1) { // an ace
score = 11
eleven = 1
}
for (uc in 1..10) { // collect results for each dealer up-card
if (deck[uc] == 0) continue // card no longer present in deck
var deck2 = deck.toList
deck2[uc] = deck2[uc] - 1
deck2[0] = deck2[0] - 1
var ix = uc - 2
if (ix == -1) ix = 9 // in tables ace comes last
var peg = 0 // player expected gain for this up-card
// get second player card
for (c in 1..10) {
if (deck2[c] == 0) continue // card no longer present in deck
var prob = deck2[c] / deck2[0]
var deck3 = deck2.toList
deck3[c] = deck3[c] - 1
deck3[0] = deck3[0] - 1
var score2 = score + c
var eleven2 = eleven
if (c == 1) { // score all aces initially as 11
score2 = score2 + 10
eleven2 = eleven2 + 1
}
if (score2 == 21) { // player has blackjack & we know dealer hasn't
peg = peg + 1.5 * prob
continue
}
if (score2 > 21 && eleven2 > 0) {
score2 = score2 - 10 // bust but can demote an ace
eleven2 = eleven2 - 1
}
var action
if (eleven2 > 0) {
action = STable2[score2-12][ix] // use soft strategy table, no doubling
} else { // including pairs as no re-splitting
action = HTable2[score2-4][ix] // use hard strategy table, no doubling
}
var peg2
if (action == "S") {
var dp = dealerProbs(uc, deck3)
peg2 = calcGain(score2, dp)
} else {
peg2 = playerGain2(card, c, uc, deck3)
}
peg = peg + peg2 * prob
}
if (uc > 1) {
egs[uc-2] = peg * 2 // allow for both hands in overall results
} else {
egs[9] = peg * 2 // ditto
}
}
return egs
}
 
// Returns the action with the highest expected gain.
static bestAction(ags) {
var max = ags[0].gain
var maxi = 0
for (i in 1...ags.count) {
if (ags[i].gain > max) {
max = ags[i].gain
maxi = i
}
}
return ags[maxi].action
}
 
// Prints title and header for a given chart.
static printHeader(title) {
System.print(title)
System.print("P/D 2 3 4 5 6 7 8 9 T A")
System.print("--------------------------------------------------------------------------")
}
 
// Prints header for a pair of cards.
static printPair(c) {
if (c == 1) {
System.write("AA ")
} else if (c == 10) {
System.write("TT ")
} else {
Fmt.write("$d$d ", c, c)
}
}
 
// Simulates 'perDay' blackjack games for 'days' days.
static simulate(perDay, days) {
var winDays = 0
var loseDays = 0
var evenDays = 0
var bigWin = 0
var bigLoss = 0
var totGain = 0
var totStake = 0
for (d in 1..days) {
var dailyGain = 0
var dailyStake = 0
for (p in 1..perDay) {
var gs = playerPlay()
dailyGain = dailyGain + gs[0]
dailyStake = dailyStake + gs[1]
}
if (dailyGain > 0) {
winDays = winDays + 1
} else if (dailyGain < 0) {
loseDays = loseDays + 1
} else {
evenDays = evenDays + 1
}
if (dailyGain > bigWin) {
bigWin = dailyGain
} else if (-dailyGain > bigLoss) {
bigLoss = -dailyGain
}
totGain = totGain + dailyGain
totStake = totStake + dailyStake
}
Fmt.print("\nAfter playing $d times a day for $d days:", perDay, days)
Fmt.print("Winning days : $d", winDays)
Fmt.print("Losing days : $d", loseDays)
Fmt.print("Breakeven days : $d", evenDays)
Fmt.print("Biggest win : $h", bigWin)
Fmt.print("Biggest loss : $h", bigLoss)
if (totGain < 0) {
Fmt.print("Total loss : $h", -totGain)
Fmt.print("Total staked : $h", totStake)
Fmt.print("Loss \% staked : $0.3f", -totGain/totStake*100)
} else {
Fmt.print("Total win : $h", totGain)
Fmt.print("Total staked : $h", totStake)
Fmt.print("Win \% staked : $0.3f", totGain/totStake*100)
}
}
 
// Simulates a dealer's play for a given player's hand and state of deck.
// Returns the player's gain (positive or negative) per unit staked.
static dealerPlay(pscore, next, cards, d) {
var dscore = d[0] + d[1]
var aces = 0
if (d[0] == 1 || d[1] == 1) { // dealer has an ace
dscore = dscore + 10
aces = aces + 1
}
while (true) {
if (dscore > 21 && aces > 0) {
dscore = dscore - 10 // bust but we can demote an ace
aces = aces - 1
}
if (dscore > 21) {
return [1, next] // 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, next] // dealer wins and player loses stake
} else if (dscore == pscore) {
break // player breaks even
} else {
return [1, next] // dealer loses and player gains stake
}
}
var nc = cards[next] // get new card from pack
next = next + 1
dscore = dscore + nc
if (nc == 1) { // count aces initially as 11
dscore = dscore + 10
aces = aces + 1
}
}
return [0, next]
}
 
// Simulates the playing of a random player's hand according to the strategy tables.
// Returns both the gain (positive or negative) and the stake (1 or 2).
static playerPlay() {
var perm = (0..51).toList
Rand.shuffle(perm) // randomizes integers from 0 to 51 inclusive
var cards = List.filled(52, 0)
for (se in Indexed.new(perm)) {
var card = (se.value/4).floor + 1
if (card > 10) card = 10
cards[se.index] = card
}
var p = [] // player hand
var d = [] // dealer hand
// initial deal
for (se in Indexed.new(cards[0..3])) {
if (se.index < 2) {
p.add(se.value)
} else {
d.add(se.value)
}
}
var next = 4 // index of next card to be dealt
 
// check if dealer and/or player have blackjack
var dbj = (d[0] == 1 && d[1] == 10) || (d[0] == 10 && d[1] == 1)
var pbj = (p[0] == 1 && p[1] == 10) || (p[0] == 10 && p[1] == 1)
if (dbj) {
if (pbj) return [0, 1] // player neither wins nor loses
return [-1, 1] // player loses stake
}
if (pbj) return [1.5, 1] // player wins 1.5 x stake
var uc = d[0] // dealer's up-card for accessing tables
if (uc == 0) {
uc = 9 // move ace to last place
} else {
uc = uc - 1 // move others down 1
}
var stake = 1 // player's initial stake
var fscores = List.filled(2, 0) // final player scores (one or, after split, two hands)
var action = ""
var score = 0
var aces = 0
 
var h = Fn.new { |hand| // processes a 'hit'
while (true) {
var nc = cards[next] // get new card from pack
next = next + 1
score = score + nc
if (nc == 1) { // count aces initially as 11
score = score + 10
aces= aces + 1
}
if (score > 21 && aces > 0) {
score = score - 10 // bust but we can demote an ace
aces = aces - 1
}
if (score > 21) {
fscores[hand] = 22 // player is bust and loses stake
return
}
if (action == "D") {
fscores[hand] = score
return
}
// get further strategy and act accordingly
if (aces == 0) {
action = HTable2[score-4][uc]
} else {
action = STable2[score-12][uc]
}
if (action == "S") { // stand
fscores[hand] = score
return
}
}
}
 
score = p[0] + p[1]
// get kind of player hand: hard, soft, pair
var kind
if (p[0] == p[1]) {
kind = "pair"
} else if (p[0] == 1 || p[1] == 1) {
kind = "soft"
} else {
kind = "hard"
}
if (kind == "hard") {
action = HTable[score-5][uc]
} else if (kind == "soft") { // includes one ace
var otherCard = p[0]
if (otherCard == 1) otherCard = p[1]
score = score + 10
aces = 1
action = STable[otherCard-2][uc]
} else if (kind == "pair") {
if (p[0] == 1) { // pair of aces
score = score + 10
aces = 2
}
action = PTable[p[0]-1][uc]
}
if (action == "S") { // stand
fscores[0] = score
} else if (action == "H") { // hit
h.call(0)
} else if (action == "D") { // double
h.call(0)
stake = 2
} else if (action == "P") { // split
for (hand in 0..1) {
score = p[0]
aces = 0
if (score == 1) { // count aces initially as 11
score = 11
aces = aces + 1
}
h.call(hand)
}
}
var sum = 0
if (fscores[0] < 22) {
var res = dealerPlay(fscores[0], next, cards, d)
sum = sum + res[0] * stake
next = res[1]
} else {
sum = sum - stake // this hand is bust
}
if (fscores[1] > 0) { // pair
if (fscores[1] < 22) {
var res = dealerPlay(fscores[1], next, cards, d)
sum = sum + res[0]
next = res[1]
} else {
sum = sum - 1 // this hand is bust
}
stake = 2
}
return [sum, stake]
}
 
static main() {
// print dealer probabilities chart
dealerChart()
 
// for hard scores (i.e. different cards, no aces)
var 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
var counts = Array.from([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 = List.filled(15, null) // if stands
var hegs = List.filled(15, null) // if hits
var degs = List.filled(15, null) // if doubles
for (i in 0..14) {
segs[i] = List.filled(10, 0)
hegs[i] = List.filled(10, 0)
degs[i] = List.filled(10, 0)
}
for (tuple in tuples) {
var i = tuple[0] + tuple[1]
var sg = stand(tuple[0], tuple[1])
var hg = hit(tuple[0], tuple[1], false)
var dg = double(tuple[0], tuple[1])
for (j in 0..9) {
segs[i-5][j] = segs[i-5][j] + sg[j]
hegs[i-5][j] = hegs[i-5][j] + hg[j]
degs[i-5][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] = segs[i][j] / counts[i]
hegs[i][j] = hegs[i][j] / counts[i]
degs[i][j] = degs[i][j] / counts[i]
}
}
 
printHeader("\nHard Chart - Player Expected Gains per unit (Stand)")
for (i in 5..19) {
Fmt.write("$2d ", i)
for (j in 0..9) Fmt.write("$6.3f ", segs[i-5][j])
System.print()
}
 
printHeader("\nHard Chart - Player Expected Gains per unit (Hit)")
for (i in 5..19) {
Fmt.write("$2d ", i)
for (j in 0..9) Fmt.write("$6.3f ", hegs[i-5][j])
System.print()
}
 
printHeader("\nHard Chart - Player Expected Gains per original unit (Double)")
for (i in 5..19) {
Fmt.write("$2d ", i)
for (j in 0..9) Fmt.write("$6.3f ", degs[i-5][j])
System.print()
}
 
printHeader("\nHard Chart - Player Strategy (Round 1)")
for (i in 5..19) {
Fmt.write("$2d ", i)
for (j in 0..9) {
var ags = [
ActionGain.new("S", segs[i-5][j]),
ActionGain.new("H", hegs[i-5][j]),
ActionGain.new("D", degs[i-5][j])
]
var action = bestAction(ags)
HTable[i-5][j] = action
Fmt.write("$4s ", action)
}
System.print()
}
 
// 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 = List.filled(18, null) // expected gains if stands
var hegs2 = List.filled(18, null) // expected gains if hits
for (i in 0..17) {
segs2[i] = List.filled(10, 0)
hegs2[i] = List.filled(10, 0)
}
for (i in 5..19) {
segs2[i-4] = segs[i-5]
hegs2[i-4] = hegs[i-5]
}
var sg4 = stand(2, 2)
var hg4 = hit(2, 2, false)
var sg20 = stand(10, 10)
var hg20 = hit(10, 10, false)
var sg21 = stand(1, 10)
var hg21 = hit(1, 10, false)
for (j in 0..9) {
segs2[0][j] = segs2[0][j] + sg4[j]
hegs2[0][j] = hegs2[0][j] + hg4[j]
segs2[16][j] = segs2[16][j] + sg20[j]
hegs2[16][j] = hegs2[16][j] + hg20[j]
segs2[17][j] = segs2[17][j] + sg21[j]
hegs2[17][j] = hegs2[17][j] + hg21[j]
}
 
printHeader("\nHard Chart - Player Strategy (Round >= 2, No Doubling)")
for (i in 4..21) {
Fmt.write("$2d ", i)
for (j in 0..9) {
var action = "S"
if (hegs2[i-4][j] > segs2[i-4][j]) action = "H"
HTable2[i-4][j] = action
Fmt.write("$4s ", action)
}
System.print()
}
 
/* 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 = List.filled(8, null) // if stands
var hegs3 = List.filled(8, null) // if hits
var degs3 = List.filled(8, null) // if doubles
for (i in 0..7) {
segs3[i] = List.filled(10, 0)
hegs3[i] = List.filled(10, 0)
degs3[i] = List.filled(10, 0)
}
for (c in 2..9) {
var sg = stand(1, c)
var hg = hit(1, c, false)
var dg = double(1, c)
for (j in 0..9) {
segs3[c-2][j] = segs3[c-2][j] + sg[j]
hegs3[c-2][j] = hegs3[c-2][j] + hg[j]
degs3[c-2][j] = degs3[c-2][j] + dg[j]
}
}
 
printHeader("\nSoft Chart - Player Expected Gains per unit (Stand)")
for (c in 2..9) {
Fmt.write("A$d ", c)
for (j in 0..9) Fmt.write("$6.3f ", segs3[c-2][j])
System.print()
}
 
printHeader("\nSoft Chart - Player Expected Gains per unit (Hit)")
for (c in 2..9) {
Fmt.write("A$d ", c)
for (j in 0..9) Fmt.write("$6.3f ", hegs3[c-2][j])
System.print()
}
 
printHeader("\nSoft Chart - Player Expected Gains per unit (Double)")
for (c in 2..9) {
Fmt.write("A$d ", c)
for (j in 0..9) Fmt.write("$6.3f ", degs3[c-2][j])
System.print()
}
 
printHeader("\nSoft Chart - Player Strategy (Round 1)")
for (c in 2..9) {
Fmt.write("A$d ", c)
for (j in 0..9) {
var ags = [
ActionGain.new("S", segs3[c-2][j]),
ActionGain.new("H", hegs3[c-2][j]),
ActionGain.new("D", degs3[c-2][j])
]
var action = bestAction(ags)
STable[c-2][j] = action
Fmt.write("$4s ", action)
}
System.print()
}
 
// 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 = List.filled(10, null) // expected gains if stands
var hegs4 = List.filled(10, null) // expected gains if hits
for (i in 0..9) {
segs4[i] = List.filled(10, 0)
hegs4[i] = List.filled(10, 0)
}
for (i in 1..8) {
segs4[i] = segs3[i-1]
hegs4[i] = hegs3[i-1]
}
var sg12 = stand(1, 1)
var hg12 = hit(1, 1, false)
for (j in 0..9) {
segs4[0][j] = segs4[0][j] + sg12[j]
hegs4[0][j] = hegs4[0][j] + hg12[j]
segs4[9][j] = segs4[9][j] + sg21[j]
hegs4[9][j] = hegs4[9][j] + hg21[j]
}
 
printHeader("\nSoft Chart - Player Strategy (Round >= 2, No Doubling)")
for (i in 12..21) {
Fmt.write("$2d ", i)
for (j in 0..9) {
var action = "S"
if (hegs4[i-12][j] > segs4[i-12][j]) action = "H"
STable2[i-12][j] = action
Fmt.write("$4s ", action)
}
System.print()
}
 
/* for pairs */
 
// expected gains for each pair (A to 10) & for each dealer up-card
var segs5 = List.filled(10, null) // if stands
var hegs5 = List.filled(10, null) // if hits
var degs5 = List.filled(10, null) // if doubles
var pegs5 = List.filled(10, null) // if splits
for (i in 0..9) {
segs5[i] = List.filled(10, 0)
hegs5[i] = List.filled(10, 0)
degs5[i] = List.filled(10, 0)
pegs5[i] = List.filled(10, 0)
}
for (c in 1..10) {
var sg = stand(c, c)
var hg = hit(c, c, false)
var dg = double(c, c)
var pg = split(c)
for (j in 0..9) {
segs5[c-1][j] = segs5[c-1][j] + sg[j]
hegs5[c-1][j] = hegs5[c-1][j] + hg[j]
degs5[c-1][j] = degs5[c-1][j] + dg[j]
pegs5[c-1][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) Fmt.write("$6.3f ", segs5[c-1][j])
System.print()
}
 
printHeader("\nPairs Chart - Player Expected Gains per unit (Hit)")
for (c in 1..10) {
printPair(c)
for (j in 0..9) Fmt.write("$6.3f ", hegs5[c-1][j])
System.print()
}
 
printHeader("\nPairs Chart - Player Expected Gains per unit (Double)")
for (c in 1..10) {
printPair(c)
for (j in 0..9) Fmt.write("$6.3f ", degs5[c-1][j])
System.print()
}
 
printHeader("\nPairs Chart - Player Expected Gains per unit (Split)")
for (c in 1..10) {
printPair(c)
for (j in 0..9) Fmt.write("$6.3f ", pegs5[c-1][j])
System.print()
}
 
printHeader("\nPairs Chart - Player Strategy (Round 1)")
for (c in 1..10) {
printPair(c)
for (j in 0..9) {
var ags = [
ActionGain.new("S", segs5[c-1][j]),
ActionGain.new("H", hegs5[c-1][j]),
ActionGain.new("D", degs5[c-1][j]),
ActionGain.new("P", pegs5[c-1][j]),
]
var action = bestAction(ags)
PTable[c-1][j] = action
Fmt.write("$4s ", action)
}
System.print()
}
 
// do 10 years of simulations
for (i in 1..10) {
Fmt.print("\nSimulation for Year $d:", i)
simulate(50, 365)
}
}
}
 
Blackjack.main()</syntaxhighlight>
 
{{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 original 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 H H H H H H H H H H
6 H H H H H H H H H H
7 H H H H H H H H H H
8 H H H D D H H H H H
9 D D D D D H H H H H
10 D D D D D D D D H H
11 D D D D D D D D D D
12 H H S S S H H H H H
13 S S S S S H H H H H
14 S S S S S H H H H H
15 S S S S S H H H H H
16 S S S S S H H H H H
17 S S S S S S S S S S
18 S S S S S S S S S S
19 S S S S S S S S S S
 
Hard Chart - Player Strategy (Round >= 2, No Doubling)
P/D 2 3 4 5 6 7 8 9 T A
--------------------------------------------------------------------------
4 H H H H H H H H H H
5 H H H H H H H H H H
6 H H H H H H H H H H
7 H H H H H H H H H H
8 H H H H H H H H H H
9 H H H H H H H H H H
10 H H H H H H H H H H
11 H H H H H H H H H H
12 H H S S S H H H H H
13 S S S S S H H H H H
14 S S S S S H H H H H
15 S S S S S H H H H H
16 S S S S S H H H H H
17 S S S S S S S S S S
18 S S S S S S S S S S
19 S S S S S S S S S S
20 S S S S S S S S S S
21 S S S S S S S S S S
 
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 H H D D D H H H H H
A3 H H D D D H H H H H
A4 H H D D D H H H H H
A5 H H D D D H H H H H
A6 D D D D D H H H H H
A7 S D D D D S S H H S
A8 S S S S D S S S S S
A9 S S S S S S S S S S
 
Soft Chart - Player Strategy (Round >= 2, No Doubling)
P/D 2 3 4 5 6 7 8 9 T A
--------------------------------------------------------------------------
12 H H H H H H H H H H
13 H H H H H H H H H H
14 H H H H H H H H H H
15 H H H H H H H H H H
16 H H H H H H H H H H
17 H H H H H H H H H H
18 S S S S S S S H H S
19 S S S S S S S S S S
20 S S S S S S S S S S
21 S S S S S S S S S S
 
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 P P P P P P P P P P
22 H P P P P P H H H H
33 H H P P P P H H H H
44 H H H D D H H H H H
55 D D D D D D D D H D
66 P P P P P H H H H H
77 P P P P P P H H S H
88 P P P P P P P P P P
99 P P P P P S P P S S
TT S S S S S S S S S S
 
Simulation for Year 1:
 
After playing 50 times a day for 365 days:
Winning days : 180
Losing days : 176
Breakeven days : 9
Biggest win : 23.5
Biggest loss : 24.5
Total loss : 263
Total staked : 20482
Loss % staked : 1.284
 
Simulation for Year 2:
 
After playing 50 times a day for 365 days:
Winning days : 176
Losing days : 174
Breakeven days : 15
Biggest win : 20.5
Biggest loss : 20
Total loss : 60.5
Total staked : 20514
Loss % staked : 0.295
 
Simulation for Year 3:
 
After playing 50 times a day for 365 days:
Winning days : 163
Losing days : 195
Breakeven days : 7
Biggest win : 20.5
Biggest loss : 26
Total loss : 297
Total staked : 20501
Loss % staked : 1.449
 
Simulation for Year 4:
 
After playing 50 times a day for 365 days:
Winning days : 163
Losing days : 190
Breakeven days : 12
Biggest win : 21.5
Biggest loss : 20.5
Total loss : 144.5
Total staked : 20507
Loss % staked : 0.705
 
Simulation for Year 5:
 
After playing 50 times a day for 365 days:
Winning days : 153
Losing days : 203
Breakeven days : 9
Biggest win : 19
Biggest loss : 24.5
Total loss : 485.5
Total staked : 20501
Loss % staked : 2.368
 
Simulation for Year 6:
 
After playing 50 times a day for 365 days:
Winning days : 176
Losing days : 177
Breakeven days : 12
Biggest win : 21
Biggest loss : 29.5
Total loss : 4
Total staked : 20536
Loss % staked : 0.019
 
Simulation for Year 7:
 
After playing 50 times a day for 365 days:
Winning days : 161
Losing days : 195
Breakeven days : 9
Biggest win : 25.5
Biggest loss : 24.5
Total loss : 316.5
Total staked : 20568
Loss % staked : 1.539
 
Simulation for Year 8:
 
After playing 50 times a day for 365 days:
Winning days : 168
Losing days : 189
Breakeven days : 8
Biggest win : 21
Biggest loss : 28
Total loss : 240
Total staked : 20524
Loss % staked : 1.169
 
Simulation for Year 9:
 
After playing 50 times a day for 365 days:
Winning days : 181
Losing days : 174
Breakeven days : 10
Biggest win : 22
Biggest loss : 26
Total loss : 17
Total staked : 20494
Loss % staked : 0.083
 
Simulation for Year 10:
 
After playing 50 times a day for 365 days:
Winning days : 156
Losing days : 198
Breakeven days : 11
Biggest win : 22
Biggest loss : 21
Total loss : 346.5
Total staked : 20438
Loss % staked : 1.695
</pre>
9,476

edits