<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Betkyo Research</title>
    <description>The latest articles on DEV Community by Betkyo Research (@betkyo).</description>
    <link>https://dev.to/betkyo</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4121818%2F5507dc9d-30ad-405a-a708-d12c050e190e.png</url>
      <title>DEV Community: Betkyo Research</title>
      <link>https://dev.to/betkyo</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/betkyo"/>
    <language>en</language>
    <item>
      <title>How many dice rolls until a result repeats? The birthday problem on a 9,999-result engine</title>
      <dc:creator>Betkyo Research</dc:creator>
      <pubDate>Thu, 12 Nov 2026 01:19:34 +0000</pubDate>
      <link>https://dev.to/betkyo/how-many-dice-rolls-until-a-result-repeats-the-birthday-problem-on-a-9999-result-engine-2p6c</link>
      <guid>https://dev.to/betkyo/how-many-dice-rolls-until-a-result-repeats-the-birthday-problem-on-a-9999-result-engine-2p6c</guid>
      <description>&lt;p&gt;A Betkyo dice roll can land on any of 9,999 results, so seeing the same one twice, say 41.07 on roll 30 and again on roll 95, feels like a glitch. It is the birthday problem, and it makes a repeat more likely than not by roll 119.&lt;/p&gt;

&lt;p&gt;Where 9,999 comes from: the engine takes a 52-bit fraction 0 ≤ u &amp;lt; 1 from an HMAC-SHA256 keyed by the server seed (its SHA-256 hash is shown before you bet) over your client seed and a counting nonce, and returns (floor(u × 9,999) + 1) / 100, one of 0.01, 0.02, …, 99.99. The 2^52 possible values of u fall into 9,999 bins whose sizes differ by at most one (one part in 450 billion):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;divmod&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="mi"&gt;52&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;9999&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;   &lt;span class="c1"&gt;# (450405003237, 3733): 3,733 bins get one extra value&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The chance that n rolls are all different is the product of (1 − i/N) for i = 0 … n − 1. With exact fractions:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="n"&gt;fractions&lt;/span&gt; &lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nc"&gt;Fraction&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;rolls_for&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;N&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="s2"&gt;"""Fewest rolls with P(some result repeats) &amp;gt;= p, exact."""&lt;/span&gt;
    &lt;span class="n"&gt;distinct&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Fraction&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
    &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;distinct&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;distinct&lt;/span&gt; &lt;span class="o"&gt;*=&lt;/span&gt; &lt;span class="nc"&gt;Fraction&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;N&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;N&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;   &lt;span class="c1"&gt;# roll n+1 misses the n results before it&lt;/span&gt;
        &lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;distinct&lt;/span&gt;

&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="no"&gt;N&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;365&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;37&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;9999&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;row&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nf"&gt;rolls_for&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;N&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Fraction&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;k&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;k&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;90&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;99&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;N&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;"{float(prob):.1%}"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;prob&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;# 365 [(23, '50.7%'), (41, '90.3%'), (57, '99.0%')]&lt;/span&gt;
&lt;span class="c1"&gt;# 37 [(8, '55.7%'), (13, '90.9%'), (18, '99.3%')]&lt;/span&gt;
&lt;span class="c1"&gt;# 9999 [(119, '50.6%'), (215, '90.1%'), (303, '99.0%')]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The first row is the classic birthday answer, 23 people. A single-zero roulette wheel (37 pockets) repeats within 8 spins more often than not, and within 18 spins 99.3% of the time. The dice engine has 270 times as many results but needs only about 15 times as many rolls, because what collides is pairs: n rolls hold n(n − 1)/2 of them, each matching with probability 1/N. The shortcut sqrt(2N·ln 2) ≈ 117.7 says 118; at 118 rolls the exact chance is 49.997%, so the answer is 119.&lt;/p&gt;

&lt;p&gt;Twice in a row is a different question: each roll matches the previous one with probability 1/N, independently, so the first back-to-back pair arrives on roll N + 1 on average. Printed: chance per roll, average wait, and the chance that 1,000 rolls (100 spins) contain one:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="n"&gt;fractions&lt;/span&gt; &lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nc"&gt;Fraction&lt;/span&gt;

&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="no"&gt;N&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;session&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;9999&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;37&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;seen&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nc"&gt;Fraction&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;N&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;session&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;N&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;"{1 / N:.2%}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;N&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;"{float(seen):.1%}"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;# 9999 0.01% 10000 9.5%&lt;/span&gt;
&lt;span class="c1"&gt;# 37 2.70% 38 93.4%&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Why none of this is a signal: the formula's inputs are the two seeds and a nonce that counts up by one per bet. No earlier result enters it, so a number that just repeated is neither hot nor used up: the formula gives it the same one-in-9,999 share of the next roll as every other result. What grows with each roll is the number of earlier results a new one can collide with, so a repeat within a few hundred rolls is expected, and 300 rolls without one would be the rare event (1.08%). For any random source the meaningful test is a count, not a reaction: n rolls should hold about n(n − 1)/(2N) matching pairs, 49.95 in 1,000 dice rolls. Far fewer would be as odd as far more.&lt;/p&gt;

&lt;p&gt;The longer version is on the Betkyo Journal: &lt;a href="https://betkyo.com/en/blog/that-number-again-priced-119-dice-rolls-8-roulette-spins-and-the-birthday-problem/?utm_source=devto&amp;amp;utm_medium=referral&amp;amp;utm_campaign=journal" rel="noopener noreferrer"&gt;https://betkyo.com/en/blog/that-number-again-priced-119-dice-rolls-8-roulette-spins-and-the-birthday-problem/?utm_source=devto&amp;amp;utm_medium=referral&amp;amp;utm_campaign=journal&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;18+. Written with AI assistance and checked against the sources cited in the article.&lt;/p&gt;

</description>
      <category>probability</category>
      <category>python</category>
      <category>math</category>
      <category>statistics</category>
    </item>
    <item>
      <title>The AI reads the sentence, the server says the number: a pattern for chat bots near money</title>
      <dc:creator>Betkyo Research</dc:creator>
      <pubDate>Mon, 09 Nov 2026 00:07:36 +0000</pubDate>
      <link>https://dev.to/betkyo/the-ai-reads-the-sentence-the-server-says-the-number-a-pattern-for-chat-bots-near-money-4i75</link>
      <guid>https://dev.to/betkyo/the-ai-reads-the-sentence-the-server-says-the-number-a-pattern-for-chat-bots-near-money-4i75</guid>
      <description>&lt;p&gt;Language models are very good at the part of a chat bot that used to be the worst part: working out what someone meant. "put two bucks on the dice, 3x", "$2 dice 3×" and "dice 2 at three times" are one request. A menu needs three screens to collect what that sentence says in one line.&lt;/p&gt;

&lt;p&gt;They are bad at a different part: numbers nobody handed them. Ask a model for a balance or a payout and it can answer fluently and wrongly, in the same tone either way. That's fine in a trivia bot. Next to money it disqualifies the model.&lt;/p&gt;

&lt;p&gt;When we built the Telegram chat for Betkyo (@BetkyoPlayBot), we split the job along exactly that line.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 1: the model returns a reading, not an answer
&lt;/h2&gt;

&lt;p&gt;The model sees the player's message and returns a small structured reading, plus one line of prose in a host's voice:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"intent"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"dice_bet"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"stake"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2.00"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"target"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"multiplier"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"reply_line"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Three times it is."&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's all it produces, and nothing it writes is shown to the player as a figure.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 2: the server prices it
&lt;/h2&gt;

&lt;p&gt;Everything with a number in it is looked up again by the system that owns it: the balance, the per-bet and per-day limits for chat money, the roll-under target that gives ×3, the exact payout. If the reading doesn't survive that (the stake is over the limit, the game doesn't exist, the match isn't on the board), there's no bet, just a reply.&lt;/p&gt;

&lt;p&gt;The host's line is checked too. If it contains a figure, it's dropped, so the model can't slip a number in through the prose.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 3: a card, not a bet
&lt;/h2&gt;

&lt;p&gt;What the player gets back is a card: "Dice · $2.00 USDT · Under 33.00 pays $6.00 (×3)", with &lt;em&gt;Place bet&lt;/em&gt; and &lt;em&gt;Cancel&lt;/em&gt;. The card works once and expires after 60 seconds. Nothing is placed until the tap.&lt;/p&gt;

&lt;p&gt;Sports use the same flow, and there the card does a second job: it turns the bet into words. "lots of goals in the Red Lions game" comes back as "you win if 3 or more goals in the match". If the price moves between the card and the tap, nothing is taken and a new card shows the new price.&lt;/p&gt;

&lt;h2&gt;
  
  
  What this buys
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;A misread sentence costs one cancelled card, never money.&lt;/li&gt;
&lt;li&gt;A message, however clever, can only lead to a card, and only the account owner's tap places it.&lt;/li&gt;
&lt;li&gt;The model can be swapped or upgraded without touching anything that handles money.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The rule fits in one sentence: the model understands, the server decides what's true, and the player decides what happens.&lt;/p&gt;

&lt;p&gt;The longer write-up, with the sports flow and the chat's limits: &lt;a href="https://betkyo.com/en/blog/an-ai-host-that-is-not-allowed-to-say-a-number-how-betkyos-telegram-chat-turns-a-sentence-into-a-bet/?utm_source=devto&amp;amp;utm_medium=referral&amp;amp;utm_campaign=journal" rel="noopener noreferrer"&gt;https://betkyo.com/en/blog/an-ai-host-that-is-not-allowed-to-say-a-number-how-betkyos-telegram-chat-turns-a-sentence-into-a-bet/?utm_source=devto&amp;amp;utm_medium=referral&amp;amp;utm_campaign=journal&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;18+. Written with AI assistance and reviewed by the Betkyo team.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>chatbot</category>
      <category>architecture</category>
      <category>telegram</category>
    </item>
    <item>
      <title>When a lottery ticket is worth more than it costs: pricing a roll-down in 20 lines of Python</title>
      <dc:creator>Betkyo Research</dc:creator>
      <pubDate>Thu, 05 Nov 2026 02:47:30 +0000</pubDate>
      <link>https://dev.to/betkyo/when-a-lottery-ticket-is-worth-more-than-it-costs-pricing-a-roll-down-in-20-lines-of-python-5f10</link>
      <guid>https://dev.to/betkyo/when-a-lottery-ticket-is-worth-more-than-it-costs-pricing-a-roll-down-in-20-lines-of-python-5f10</guid>
      <description>&lt;p&gt;Most lottery arithmetic is depressing. A 6-of-46 game with a $2 ticket, $4,000 for five numbers, $150 for four, $5 for three and a free ticket for two returns about 74 cents on the dollar before you even think about the jackpot. But one game, Massachusetts' Cash WinFall (2004–2012), had a cap: when the jackpot reached $2 million and nobody won it, the money "rolled down" into the smaller prizes. On 8 February 2010 the match-five paid $22,096 and the match-four $807.52. The question is what a ticket was worth that night, and how sure a big buyer could be of collecting it.&lt;/p&gt;

&lt;p&gt;The odds are hypergeometric: the chance of matching k of 6 drawn numbers from 46 is C(6,k)·C(40,6−k)/C(46,6).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;math&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;comb&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;sqrt&lt;/span&gt;
&lt;span class="n"&gt;N&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;comb&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;46&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;                      &lt;span class="c1"&gt;# 9,366,819
&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;k&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;comb&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;k&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nf"&gt;comb&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;40&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;6&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;k&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="n"&gt;N&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;k&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;
&lt;span class="n"&gt;std&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;4000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;150&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="n"&gt;roll&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;22096&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;807.52&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;26.85&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;   &lt;span class="c1"&gt;# 8 Feb 2010, Inspector General's letter
&lt;/span&gt;&lt;span class="n"&gt;ev&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;lambda&lt;/span&gt; &lt;span class="n"&gt;prizes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;prizes&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;k&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;k&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;k&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;prizes&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;ev&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="nf"&gt;ev&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;roll&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;              &lt;span class="c1"&gt;# 0.395 vs 2.141 cash per $2 ticket
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So the same ticket, at the same odds, went from 40 cents of cash to $2.14. Buy 200,000 of them ($400,000) and the expectation is $428,000 in cash plus about 29,000 free tickets. That is the edge the syndicates in the story were collecting.&lt;/p&gt;

&lt;p&gt;Two things the expectation hides. First, variance. Each prize tier's count is approximately Poisson, so the standard deviation of the cash is the square root of the sum of (count × prize^2):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;200000&lt;/span&gt;
&lt;span class="n"&gt;mean&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nf"&gt;ev&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;roll&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;sd&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;sqrt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;k&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;roll&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;k&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;k&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;roll&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;round&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;mean&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="nf"&gt;round&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sd&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;         &lt;span class="c1"&gt;# 428247, 51652
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A $28,000 expected profit with a $52,000 standard deviation ends behind about 29% of the time, even when the roll-down happens.&lt;/p&gt;

&lt;p&gt;Second, whether it happens. The roll-down only fires if nobody matches all six, and the more tickets in the drawing, the likelier someone does:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;sold&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;470_000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1_300_000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2_500_000&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sold&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;round&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="n"&gt;N&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt; &lt;span class="n"&gt;sold&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;%&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;# 4.9 %, 13.0 %, 23.4 %
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;By 2007 the syndicates themselves had pushed sales past 1.3 million tickets a roll-down, so each of them was carrying a 13% chance per drawing that the jackpot would be hit and the prizes would revert to standard. It happened once in 45 roll-downs, on 10 July 2008, and every big bettor lost hundreds of thousands that night.&lt;/p&gt;

&lt;p&gt;Where the surplus came from is the real point: every ticket bought while the jackpot was small funded a jackpot that 44 times out of 45 nobody won, and the cap handed that money to whoever held tickets on the night. A casino game has no such pool; a provably fair dice round pays out of its own stake by a fixed formula, so its edge is a constant that never changes sign. That is the whole difference between an edge you can read in a brochure and one that cannot exist.&lt;/p&gt;

&lt;p&gt;The full case, with the Inspector General's figures and the syndicates' totals, is on the Betkyo Journal: &lt;a href="https://betkyo.com/en/blog/jerry-and-marge-selbee-27-million-in-tickets-the-2-million-roll-down-and-the-lottery-ticket-worth-more-than-it-cost/?utm_source=devto&amp;amp;utm_medium=referral&amp;amp;utm_campaign=journal" rel="noopener noreferrer"&gt;https://betkyo.com/en/blog/jerry-and-marge-selbee-27-million-in-tickets-the-2-million-roll-down-and-the-lottery-ticket-worth-more-than-it-cost/?utm_source=devto&amp;amp;utm_medium=referral&amp;amp;utm_campaign=journal&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;18+. Written with AI assistance and checked against the sources cited in the article.&lt;/p&gt;

</description>
      <category>probability</category>
      <category>python</category>
      <category>math</category>
      <category>statistics</category>
    </item>
    <item>
      <title>How many bets until a 1% house edge is visible? The (k·σ/e)^2 rule, with the numbers</title>
      <dc:creator>Betkyo Research</dc:creator>
      <pubDate>Tue, 03 Nov 2026 01:00:05 +0000</pubDate>
      <link>https://dev.to/betkyo/how-many-bets-until-a-1-house-edge-is-visible-the-kse2-rule-with-the-numbers-2pli</link>
      <guid>https://dev.to/betkyo/how-many-bets-until-a-1-house-edge-is-visible-the-kse2-rule-with-the-numbers-2pli</guid>
      <description>&lt;p&gt;A 1% house edge is the headline number on every casino game, and it is a number no player ever sees. Not because it is hidden, but because it is small next to the thing it sits inside. Here is the arithmetic, with the numbers for a coin-flip bet.&lt;/p&gt;

&lt;h2&gt;
  
  
  One bet, two numbers
&lt;/h2&gt;

&lt;p&gt;Take a bet that wins with probability p and pays m times the stake (profit m − 1), otherwise loses the stake. Per unit staked:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;expected return: &lt;code&gt;p · m&lt;/code&gt;, so the edge is &lt;code&gt;e = 1 − p·m&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;standard deviation: &lt;code&gt;σ = sqrt(p · m² − (p·m)²)&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For a roll-under-50 dice bet on a 9,999-result engine, p = 4,999 ÷ 9,999 and m = 1.98:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;m&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;4999&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;9999&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;1.98&lt;/span&gt;
&lt;span class="n"&gt;mean&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;m&lt;/span&gt;              &lt;span class="c1"&gt;# 0.98990
&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;mean&lt;/span&gt;            &lt;span class="c1"&gt;# 0.01010  (1.01 cents per dollar)
&lt;/span&gt;&lt;span class="n"&gt;sigma&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;m&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;mean&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt; &lt;span class="mf"&gt;0.5&lt;/span&gt;   &lt;span class="c1"&gt;# 0.990  (99 cents per dollar)
&lt;/span&gt;&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sigma&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;        &lt;span class="c1"&gt;# 98.0
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The swing is 98 times the cost. That ratio is the whole story.&lt;/p&gt;

&lt;h2&gt;
  
  
  The square-root rule
&lt;/h2&gt;

&lt;p&gt;Over N independent bets the expected loss is &lt;code&gt;N·e&lt;/code&gt; (linear) and the standard deviation of the total is &lt;code&gt;σ·√N&lt;/code&gt;. Their ratio grows as √N, so the expected loss clears k standard deviations at&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;N = (k · σ / e)²
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With σ/e = 98 and k = 2 (the usual "this is not noise" line), N ≈ 38,400. For a clean ×2 bet at exactly 1% it is 39,996. Call it forty thousand bets.&lt;/p&gt;

&lt;h2&gt;
  
  
  What the player sees before that
&lt;/h2&gt;

&lt;p&gt;The chance of being ahead after N bets is a binomial tail: you are ahead when &lt;code&gt;wins · m &amp;gt; N&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;math&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;comb&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;p_ahead&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;N&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;4999&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;9999&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mf"&gt;1.98&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;k&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;int&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;N&lt;/span&gt; &lt;span class="o"&gt;//&lt;/span&gt; &lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;          &lt;span class="c1"&gt;# wins needed to be above break-even
&lt;/span&gt;    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;comb&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;N&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;w&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;N&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;w&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nf"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;k&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;N&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;N&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;10000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;40000&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;N&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;round&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;p_ahead&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;N&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="c1"&gt;# 100 0.460 · 1000 0.363 · 10000 0.154 · 40000 0.020
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After a hundred bets, 46% of players are up. After a thousand, more than a third. The edge does not reach one standard deviation until about 9,600 bets and two until about 38,000.&lt;/p&gt;

&lt;h2&gt;
  
  
  Higher payouts hide it longer
&lt;/h2&gt;

&lt;p&gt;Because σ grows with the payout and e does not, every setting has its own crossing. For a "limbo" style bet that wins with chance 0.99/T and pays T, the variance per unit is &lt;code&gt;0.99·T − 0.9801&lt;/code&gt;, so the two-sigma crossing is &lt;code&gt;39,600·T − 39,204&lt;/code&gt; rounds: about 40,000 at ×2, 357,000 at ×10, 3.9 million at ×100. At 900 rounds an hour the ×100 figure is about 545 eight-hour days. Same price, hidden for longer.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why the house never waits
&lt;/h2&gt;

&lt;p&gt;The house adds everyone up. A thousand players making forty bets each are forty thousand bets in one ledger, two standard deviations below zero on a day when none of them has seen anything. The law of large numbers favours whoever makes the most bets, and the house makes all of them.&lt;/p&gt;

&lt;p&gt;Two practical readings. A session proves nothing about a game, in either direction. And the swing is the thing to size a bankroll for: &lt;code&gt;σ · √N · stake&lt;/code&gt; is what you should expect to be up or down by, two sessions in three.&lt;/p&gt;

&lt;p&gt;The full per-setting tables, with the exact binomial figures, are in the Betkyo Journal piece this note summarises: &lt;a href="https://betkyo.com/en/blog/how-many-bets-before-the-edge-shows-priced-the-40000-rolls-that-hide-a-1-percent-house-edge/" rel="noopener noreferrer"&gt;https://betkyo.com/en/blog/how-many-bets-before-the-edge-shows-priced-the-40000-rolls-that-hide-a-1-percent-house-edge/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;18+. Written with AI assistance; every figure above is a calculation you can rerun from the snippets.&lt;/p&gt;

</description>
      <category>probability</category>
      <category>math</category>
      <category>python</category>
    </item>
    <item>
      <title>The denominator problem: pricing an hour of a fixed-pool airdrop</title>
      <dc:creator>Betkyo Research</dc:creator>
      <pubDate>Thu, 22 Oct 2026 02:46:32 +0000</pubDate>
      <link>https://dev.to/betkyo/the-denominator-problem-pricing-an-hour-of-a-fixed-pool-airdrop-9l7</link>
      <guid>https://dev.to/betkyo/the-denominator-problem-pricing-an-hour-of-a-fixed-pool-airdrop-9l7</guid>
      <description>&lt;p&gt;Every "play-to-airdrop" game has the same hidden variable, and it is not the token price. It is the number of other players.&lt;/p&gt;

&lt;p&gt;Here is the arithmetic with one real example. Hamster Kombat announced 300 million players on 30 July 2024 and a whitepaper giving 60% of its token to them. The airdrop landed on 26 September 2024: 131 million accounts qualified. Sixty percent of a 100 billion supply is 60 billion tokens, so the average share was&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;60_000_000_000 / 131_000_000 ≈ 458 tokens
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;At the listing price (about $0.011) that is $5.04. The token fell about 30% on day one and reached $0.0025 by 1 November, which makes the average share $1.15. If a player tapped ten minutes a day for the six months between launch and airdrop, that is 30 hours, so:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;5.04 / 30 ≈ $0.17 per hour at listing
1.15 / 30 ≈ $0.04 per hour six weeks later
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The part people miss is the direction of the growth term. In a casino game the payout rule is per bet and does not depend on how many other people are playing: a dice roll that pays 1.98× at a 50% chance pays that whether a thousand people or a hundred million are rolling. In a fixed-pool airdrop the payout is &lt;code&gt;pool / N&lt;/code&gt;, so every announcement of "more players" is an announcement that your share got smaller. A player who tapped twice as much did not double their hourly rate; they raised the denominator for everyone, themselves included.&lt;/p&gt;

&lt;p&gt;A small function makes the comparison concrete:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;per_hour_fixed_pool&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pool_tokens&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;players&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;price&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;hours&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;pool_tokens&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="n"&gt;players&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;price&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="n"&gt;hours&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;per_hour_fixed_edge&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;edge&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;stake&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;hands_per_hour&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="c1"&gt;# expected cost (negative return) per hour, known before you play
&lt;/span&gt;    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;edge&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;stake&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;hands_per_hour&lt;/span&gt;

&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;per_hour_fixed_pool&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;60e9&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;131e6&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;0.011&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;   &lt;span class="c1"&gt;# 0.168
&lt;/span&gt;&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;per_hour_fixed_pool&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;60e9&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;131e6&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;0.0025&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;  &lt;span class="c1"&gt;# 0.038
&lt;/span&gt;&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;per_hour_fixed_edge&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;0.01&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;1.0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;600&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;           &lt;span class="c1"&gt;# -6.0  (1% edge, $1 bets, 600 rolls/h)
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Neither number is a recommendation. The second one is negative, as every house-edge game is. But the second one is known before the first roll, and the first one is known only after the pool, the headcount and the price are all fixed, which in this case was six months after people started playing. The mini-app's own monthly counter, readable by anyone, went from over 100 million in late September to about 41 million by early November. That curve is what "finding out the price of an hour" looks like at scale.&lt;/p&gt;

&lt;p&gt;I work on the Betkyo Journal, where we publish this kind of derivation for casino games with the engine source as the reference. The full write-up, with the sources (Decrypt, Cointelegraph, ForkLog, BitPinas, CoinGecko), is here: &lt;a href="https://betkyo.com/en/blog/hamster-kombat-300-million-players-a-60-billion-token-airdrop-and-the-month-they-left/" rel="noopener noreferrer"&gt;https://betkyo.com/en/blog/hamster-kombat-300-million-players-a-60-billion-token-airdrop-and-the-month-they-left/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;18+. Not financial advice.&lt;/p&gt;

</description>
      <category>crypto</category>
      <category>math</category>
      <category>python</category>
      <category>web3</category>
    </item>
    <item>
      <title>Parlay math: why four coin flips pay 13-to-1, and what an insider does to that number</title>
      <dc:creator>Betkyo Research</dc:creator>
      <pubDate>Mon, 19 Oct 2026 02:26:49 +0000</pubDate>
      <link>https://dev.to/betkyo/parlay-math-why-four-coin-flips-pay-13-to-1-and-what-an-insider-does-to-that-number-5d30</link>
      <guid>https://dev.to/betkyo/parlay-math-why-four-coin-flips-pay-13-to-1-and-what-an-insider-does-to-that-number-5d30</guid>
      <description>&lt;p&gt;A parlay is a bet that several outcomes all happen. The payout multiplies, which is why it feels like a lottery ticket, and the pricing is simple enough to put in one function.&lt;/p&gt;

&lt;p&gt;American odds of −110 mean you risk 110 to win 100: a winning ticket returns 210/110 ≈ 1.909 × the stake. A four-leg parlay of −110 legs returns 1.909⁴ ≈ 13.3× — close to the $80,000 → $1.1 million (13.75×) ticket in the Jontay Porter case.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;decimal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;american&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;float&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;american&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;american&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;american&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;parlay&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;legs_american&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;p_each&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;payout multiple and true win probability for independent legs&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;
    &lt;span class="n"&gt;mult&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mf"&gt;1.0&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;legs_american&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;mult&lt;/span&gt; &lt;span class="o"&gt;*=&lt;/span&gt; &lt;span class="nf"&gt;decimal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mf"&gt;1.0&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;q&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;p_each&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="o"&gt;*=&lt;/span&gt; &lt;span class="n"&gt;q&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;mult&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;mult&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt;   &lt;span class="c1"&gt;# multiple, hit rate, expected return per $1
&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;parlay&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;110&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mf"&gt;0.5&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;          &lt;span class="c1"&gt;# (13.28, 0.0625, 0.83)
&lt;/span&gt;&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;parlay&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;110&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mf"&gt;0.9999&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;       &lt;span class="c1"&gt;# (13.28, 0.9996, 13.28)
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Two things to read off the numbers.&lt;/p&gt;

&lt;p&gt;First, the honest case. Four genuine coin-flips at −110 hit 6.25% of the time and return about 83 cents per dollar: the sportsbook's ~4.5% edge per leg compounds to ~17% over the parlay. Parlays are expensive because the vig is charged four times, not because the multiplier is dishonest.&lt;/p&gt;

&lt;p&gt;Second, the dishonest case. The multiplier does not change when one participant can make the legs certain. If a player can sit after three minutes, every "under" on his card resolves in his favour, each leg's probability goes to ~1, and the same 13.3× ticket returns ~13 dollars per dollar. The sportsbook's price assumed a coin; the insider was betting on a chair.&lt;/p&gt;

&lt;p&gt;That asymmetry is specific to unders. An over needs minutes, the ball and made shots — nobody can guarantee it. An under needs only the player to stop. Which is why the NBA's fix in October 2026 was not a better line but no line: single-player under parlays, unders on low-minute players, opening-tip and missed-shot bets are gone from its sportsbook partners.&lt;/p&gt;

&lt;p&gt;A general rule falls out of it: a market can be priced only when every participant watches the outcome from outside. Provably fair casino games get that property by construction (the result is a committed function nobody can touch after the bet); sports can only get it by withdrawing the bets an insider can decide.&lt;/p&gt;

&lt;p&gt;The full write-up, with the NBA's findings and the court record: &lt;a href="https://betkyo.com/en/blog/jontay-porter-the-under-only-the-player-can-guarantee-and-the-bets-the-nba-just-removed/" rel="noopener noreferrer"&gt;https://betkyo.com/en/blog/jontay-porter-the-under-only-the-player-can-guarantee-and-the-bets-the-nba-just-removed/&lt;/a&gt;&lt;/p&gt;

</description>
      <category>probability</category>
      <category>python</category>
      <category>statistics</category>
      <category>math</category>
    </item>
    <item>
      <title>"Provably fair" is a claim about one function. Here is what it does and doesn't cover</title>
      <dc:creator>Betkyo Research</dc:creator>
      <pubDate>Sat, 17 Oct 2026 01:52:03 +0000</pubDate>
      <link>https://dev.to/betkyo/provably-fair-is-a-claim-about-one-function-here-is-what-it-does-and-doesnt-cover-4og3</link>
      <guid>https://dev.to/betkyo/provably-fair-is-a-claim-about-one-function-here-is-what-it-does-and-doesnt-cover-4og3</guid>
      <description>&lt;p&gt;Every crypto casino says "provably fair". After the Stake hack of September 2023 — about $41 million out of hot wallets in minutes, games untouched, FBI naming Lazarus a few days later — it is worth being precise about what the phrase proves, because it is a claim about exactly one function and nothing else.&lt;/p&gt;

&lt;p&gt;The function is a commitment scheme. Before you bet, the server publishes &lt;code&gt;hash(serverSeed)&lt;/code&gt;. You contribute a &lt;code&gt;clientSeed&lt;/code&gt;. Each round derives its result from &lt;code&gt;(serverSeed, clientSeed, nonce)&lt;/code&gt; through a public algorithm. When the server seed rotates, the old one is revealed, and you check two things: that it hashes to the commitment you saw, and that re-running the public derivation reproduces every result you were paid on.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;hashlib&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;hmac&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;result&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;server_seed&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;client_seed&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;nonce&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;float&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;digest&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;hmac&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;server_seed&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;encode&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;client_seed&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;:&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;nonce&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;encode&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;hashlib&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sha256&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;hexdigest&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;int&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;digest&lt;/span&gt;&lt;span class="p"&gt;[:&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mh"&gt;0x100000000&lt;/span&gt;   &lt;span class="c1"&gt;# uniform in [0, 1)
&lt;/span&gt;
&lt;span class="c1"&gt;# after rotation:
&lt;/span&gt;&lt;span class="k"&gt;assert&lt;/span&gt; &lt;span class="n"&gt;hashlib&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sha256&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;server_seed&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;encode&lt;/span&gt;&lt;span class="p"&gt;()).&lt;/span&gt;&lt;span class="nf"&gt;hexdigest&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;committed_hash&lt;/span&gt;
&lt;span class="k"&gt;assert&lt;/span&gt; &lt;span class="nf"&gt;result&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;server_seed&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;client_seed&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;17&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;what_the_site_paid_on_round_17&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;(The exact derivation differs per site — ours is published with each game — but the shape is always this.)&lt;/p&gt;

&lt;p&gt;What that proves, if both asserts pass:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The house could not have chosen this round's result after seeing your bet. The seed was fixed before you played.&lt;/li&gt;
&lt;li&gt;The house did not pay you on a different result than the one the seed produced.&lt;/li&gt;
&lt;li&gt;Across the whole seed's life, the results were what the algorithm says, so the house edge was the published one.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;What it does not prove — and what no amount of hashing can prove:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;That the site is solvent.&lt;/strong&gt; The commitment is about results, not balances.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;That your balance can be spent only by you.&lt;/strong&gt; Custody is a question of keys, signing services and who has access to them. Stake's games verified perfectly on the day its signing service signed for a stranger.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;That the client seed you see is the one used.&lt;/strong&gt; You should set it yourself; a default you did not choose is still fair but gives you nothing to check against.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;That tomorrow's seed will be honest.&lt;/strong&gt; Each commitment covers one seed's lifetime. Verification is something you keep doing, not something you did once.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So the sentence "the games are provably fair" has a precise truth value you can check with a dozen lines of Python, and the sentence "your money is safe" has none you can check at all. The second is a trust decision, and the only lever you hold on it is exposure: what you leave on a site is a loan to its hot wallet.&lt;/p&gt;

&lt;p&gt;Longer version, with the Stake timeline and the FBI attribution: &lt;a href="https://betkyo.com/en/blog/the-stake-hack-41-million-in-nine-hours-and-the-vault-provably-fair-does-not-cover/" rel="noopener noreferrer"&gt;https://betkyo.com/en/blog/the-stake-hack-41-million-in-nine-hours-and-the-vault-provably-fair-does-not-cover/&lt;/a&gt;&lt;/p&gt;

</description>
      <category>security</category>
      <category>cryptography</category>
      <category>webdev</category>
      <category>cryptocurrency</category>
    </item>
    <item>
      <title>What a random scratch ticket should look like (and why the 2003 one didn't)</title>
      <dc:creator>Betkyo Research</dc:creator>
      <pubDate>Tue, 13 Oct 2026 01:39:35 +0000</pubDate>
      <link>https://dev.to/betkyo/what-a-random-scratch-ticket-should-look-like-and-why-the-2003-one-didnt-1am2</link>
      <guid>https://dev.to/betkyo/what-a-random-scratch-ticket-should-look-like-and-why-the-2003-one-didnt-1am2</guid>
      <description>&lt;p&gt;In 2003 a Toronto geostatistician, Mohan Srivastava, noticed that an Ontario tic-tac-toe scratch ticket could be read before it was scratched. The ticket printed eight tic-tac-toe boards on its face, 72 visible numbers from 1 to 39. Numbers that appeared exactly once on the ticket — he called them singletons — were almost always the hidden numbers under the latex, and three singletons in a line marked a winner about 90% of the time. He reported it and the game was pulled.&lt;/p&gt;

&lt;p&gt;The interesting engineering question is the inverse one: what would a ticket look like if its face really were random? If you know that, you know what a leak looks like.&lt;/p&gt;

&lt;p&gt;Draw 72 numbers independently and uniformly from 1..39. The chance that a given visible number appears exactly once on the ticket is the chance none of the other 71 cells repeat it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;p_single&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;38&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;39&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt; &lt;span class="mi"&gt;71&lt;/span&gt;        &lt;span class="c1"&gt;# ≈ 0.158
&lt;/span&gt;&lt;span class="n"&gt;expected_singletons&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;72&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;p_single&lt;/span&gt;   &lt;span class="c1"&gt;# ≈ 11.4
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So a random ticket carries about eleven singletons, scattered with no relation to anything. Here is the same thing by simulation, plus the count of three-singleton lines on the eight boards (a 3×3 board has 8 lines):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;random&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;collections&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Counter&lt;/span&gt;

&lt;span class="n"&gt;LINES&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;),(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;),(&lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;),(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;),(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="p"&gt;),(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;),(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;),(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;ticket&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;random&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;randint&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;39&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nf"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;72&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;singleton_lines&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Counter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;single&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="n"&gt;boards&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;single&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="p"&gt;:(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nf"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;all&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;line&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;boards&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;line&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;LINES&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;N&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;100_000&lt;/span&gt;
&lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nc"&gt;Counter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;values&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;t&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;ticket&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nf"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;N&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="n"&gt;N&lt;/span&gt;
&lt;span class="n"&gt;l&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;singleton_lines&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;ticket&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nf"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;N&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="n"&gt;N&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;singletons per ticket ≈ &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="si"&gt;:&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;, three-singleton lines per ticket ≈ &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;l&lt;/span&gt;&lt;span class="si"&gt;:&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;On my run (100,000 tickets): 11.37 singletons and 0.236 three-singleton lines per ticket, with 20.6% of tickets showing at least one such line. So on a genuinely random face, one ticket in five would show a line of singletons by pure chance, and it would mean nothing — the hidden numbers would have no reason to match it.&lt;/p&gt;

&lt;p&gt;The 2003 ticket was not that. Its face was written by the same program that decided which tickets win, and a program that has to print a fixed number of winners per pack has to coordinate the face with the latex. Srivastava's singletons were not a statistical accident; they were the generator's fingerprints. The lesson generalises to anything that promises randomness but must also hit a quota: the quota is information, and information leaks.&lt;/p&gt;

&lt;p&gt;The full story, including what a scratch card drawn from a committed seed does differently (no pack, no quota, each card an independent draw you can recompute afterwards), is on the Betkyo Journal: &lt;a href="https://betkyo.com/en/blog/mohan-srivastava-the-statistician-who-read-scratch-tickets-without-scratching-them/" rel="noopener noreferrer"&gt;https://betkyo.com/en/blog/mohan-srivastava-the-statistician-who-read-scratch-tickets-without-scratching-them/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Figures from Wired ("Cracking the Scratch Lottery Code", 2011) and NPR (2011); the simulation is mine.&lt;/p&gt;

</description>
      <category>statistics</category>
      <category>python</category>
      <category>probability</category>
      <category>math</category>
    </item>
    <item>
      <title>Doubling $100, priced: the chance of doubling before busting at every stake, every edge and every odds</title>
      <dc:creator>Betkyo Research</dc:creator>
      <pubDate>Mon, 12 Oct 2026 08:00:40 +0000</pubDate>
      <link>https://dev.to/betkyo/doubling-100-priced-the-chance-of-doubling-before-busting-at-every-stake-every-edge-and-every-2mdj</link>
      <guid>https://dev.to/betkyo/doubling-100-priced-the-chance-of-doubling-before-busting-at-every-stake-every-edge-and-every-2mdj</guid>
      <description>&lt;p&gt;&lt;em&gt;Originally published on the &lt;a href="https://betkyo.com/en/blog/doubling-100-dollars-priced-the-chance-of-doubling-before-busting-at-every-stake-and-edge/" rel="noopener noreferrer"&gt;Betkyo Journal&lt;/a&gt;. Drafted with AI assistance; every figure was checked against the game engine source and approved by a human editor.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Walk in with $100 and leave with $200 or nothing: a single all-in bet at ×1.98 gets you to $198 just under half the time. The same game at $1 a bet reaches $200 11% of the time, and at Chinchiro’s 2.6% edge, half a percent. Here is the whole table — why small bets lose more often than big ones, why a 1-in-100 long shot doubles you more often than a coin flip at the same stake, and what the house edge really buys the house.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;In short:&lt;/strong&gt; With a &lt;strong&gt;1% edge&lt;/strong&gt; even-money bet (our dice at 50%, ×1.98) one all-in bet reaches $198 &lt;strong&gt;49.995%&lt;/strong&gt; of the time; betting to reach &lt;strong&gt;$200&lt;/strong&gt; at a fixed stake, the chance is &lt;strong&gt;42.2%&lt;/strong&gt; at $10 a bet, &lt;strong&gt;25.9%&lt;/strong&gt; at $2, &lt;strong&gt;11.2%&lt;/strong&gt; at $1 and &lt;strong&gt;1.6%&lt;/strong&gt; at 50 cents. The house edge is paid per bet, so the more bets a session takes, the more of it you pay: at $1 a bet the session lasts about &lt;strong&gt;7,600 bets&lt;/strong&gt; on average. At a &lt;strong&gt;2.6% edge&lt;/strong&gt; (Chinchiro) $1 bets double you &lt;strong&gt;0.55%&lt;/strong&gt; of the time; at &lt;strong&gt;2.78%&lt;/strong&gt; (Sic Bo Big/Small) &lt;strong&gt;0.41%&lt;/strong&gt;. Odds matter too: at $1 a bet on dice, a &lt;strong&gt;1-in-100 shot at ×100&lt;/strong&gt; doubles you &lt;strong&gt;41%&lt;/strong&gt; of the time against the coin flip’s 11%, because it settles the question in far fewer bets. The only number that does not change is the average: every path returns 99 cents on the dollar wagered.&lt;/p&gt;

&lt;h2&gt;
  
  
  The question
&lt;/h2&gt;

&lt;p&gt;Most sessions have an unspoken target: double it, or go home. Put a number on it and the question becomes exact — with $100, a fixed stake and a known edge, what is the chance of reaching $200 before reaching $0? This is the gambler’s-ruin problem, and because our games publish their win chances and multipliers, it can be answered for each of them without a single assumption.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Engine-verified.&lt;/strong&gt; Win chances and payouts are read from the engines. Dice (OriginalBaseDiceService.kt): 9,999 equally likely results, multiplier = (1 − house edge) ÷ win chance floored to two decimals, so “over 50.00” wins 4,999 of 9,999 (49.995%) and pays ×1.98, “over 66.67” wins 33.32% at ×2.97, “over 90.00” wins 9.99% at ×9.90 and “over 99.00” wins 0.99% at ×100.00. Koban Flip pays ×1.96 on a fair coin. Sic Bo Big and Small (SicboEngine.kt) pay ×2 on 105 of 216 rolls. Chinchiro (ChinchiroDerivation.kt) returns 97.38% and is treated as an even-money bet won 48.69% of the time. Doubling chances come from replaying 200,000 sessions per cell with the engine’s exact steps — a win adds stake × (multiplier − 1), a loss removes the stake — until the bankroll is $200 or more, or too small for the next bet (±0.1 point). The fair coin and the Chinchiro model use the even-money gambler’s-ruin closed form, (1 − (q/p)ᴺ) ÷ (1 − (q/p)²ᴺ), which the replay reproduces.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  The stake is the lever
&lt;/h2&gt;

&lt;p&gt;Take the simplest case: dice at a 50% target, ×1.98, a 1% edge. Bet the whole $100 once and you are at $198 or $0 with the chance of winning, 49.995% — as close to doubling as a ×1.98 bet can get in one step. Bet smaller, aiming for $200, and two things happen — the session takes more bets, and every bet hands over 1% of the stake on average. The edge is a toll per bet, and small stakes pay it more often.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Dice at 50% (×1.98, 1% edge): $100, bet until $200 or $0&lt;/strong&gt;&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;STAKE&lt;/th&gt;
&lt;th&gt;STAKE AS % OF $100&lt;/th&gt;
&lt;th&gt;CHANCE OF DOUBLING&lt;/th&gt;
&lt;th&gt;BETS ON AVERAGE&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;$100, one bet&lt;/td&gt;
&lt;td&gt;100%&lt;/td&gt;
&lt;td&gt;49.995% (to $198)&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;$10&lt;/td&gt;
&lt;td&gt;10%&lt;/td&gt;
&lt;td&gt;42.18%&lt;/td&gt;
&lt;td&gt;100&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;$5&lt;/td&gt;
&lt;td&gt;5%&lt;/td&gt;
&lt;td&gt;38.62%&lt;/td&gt;
&lt;td&gt;399&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;$2&lt;/td&gt;
&lt;td&gt;2%&lt;/td&gt;
&lt;td&gt;25.92%&lt;/td&gt;
&lt;td&gt;2,343&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;$1&lt;/td&gt;
&lt;td&gt;1%&lt;/td&gt;
&lt;td&gt;11.22%&lt;/td&gt;
&lt;td&gt;7,634&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;$0.50&lt;/td&gt;
&lt;td&gt;0.5%&lt;/td&gt;
&lt;td&gt;1.64%&lt;/td&gt;
&lt;td&gt;19,137&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;em&gt;Target $200 or more; bust when the bankroll can no longer cover the stake. On a fair coin paying ×2 every row would read 50%. The gap between 50% and each figure is what the 1% edge costs over the number of bets the session takes to resolve.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Read the last two rows twice. At $1 a bet, $100 doubles about one time in nine; at 50 cents, about one time in sixty. Nothing about the game changed between the rows — only how many times you let the house take its 1%. “Play small to make it last” is true: the session lasts 7,600 bets at $1. It just almost never ends at $200.&lt;/p&gt;

&lt;h2&gt;
  
  
  The edge compounds through the bets
&lt;/h2&gt;

&lt;p&gt;A bigger edge does the same thing faster. Here are our even-money-style games at two stakes, with the chance of doubling $100.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Doubling $100, by game and stake&lt;/strong&gt;&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;GAME&lt;/th&gt;
&lt;th&gt;EDGE&lt;/th&gt;
&lt;th&gt;$10 A BET&lt;/th&gt;
&lt;th&gt;$1 A BET&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Fair coin (for reference)&lt;/td&gt;
&lt;td&gt;0%&lt;/td&gt;
&lt;td&gt;50.00%&lt;/td&gt;
&lt;td&gt;50.00%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Dice at 50%, ×1.98&lt;/td&gt;
&lt;td&gt;1.00%&lt;/td&gt;
&lt;td&gt;42.18%&lt;/td&gt;
&lt;td&gt;11.22%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Koban Flip, ×1.96&lt;/td&gt;
&lt;td&gt;2.00%&lt;/td&gt;
&lt;td&gt;37.63%&lt;/td&gt;
&lt;td&gt;1.51%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Chinchiro (97.38% return)&lt;/td&gt;
&lt;td&gt;2.62%&lt;/td&gt;
&lt;td&gt;37.28%&lt;/td&gt;
&lt;td&gt;0.55%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Sic Bo Big / Small, ×2&lt;/td&gt;
&lt;td&gt;2.78%&lt;/td&gt;
&lt;td&gt;36.53%&lt;/td&gt;
&lt;td&gt;0.41%&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;em&gt;Chinchiro’s payouts are not all even money (×3, ×4, ×6 for specials); it is modelled here as an even-money bet with the same return, which is slightly pessimistic for the long-shot payouts and does not change the picture.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;At $10 a bet the games are a few points apart. At $1 a bet a 1% game gives you one chance in nine and a 2.8% game one in 240. The difference between a 1% and a 2.8% edge looks like 1.8 points on a payout table; over a session of a thousand bets it is the difference between a long shot and no shot. This is also why the question “which game has the lowest edge?” matters far more to a small-stakes player than to someone making one bet.&lt;/p&gt;

&lt;h2&gt;
  
  
  The odds change the answer
&lt;/h2&gt;

&lt;p&gt;Everything above is even money. Dice lets you pick the odds at the same 1% edge, and that changes the doubling chance in a way most players would not guess.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Dice at a 1% edge: doubling $100 at different odds&lt;/strong&gt;&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;TARGET&lt;/th&gt;
&lt;th&gt;WIN CHANCE&lt;/th&gt;
&lt;th&gt;PAYS&lt;/th&gt;
&lt;th&gt;$10 A BET&lt;/th&gt;
&lt;th&gt;$1 A BET&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Over 50.00&lt;/td&gt;
&lt;td&gt;49.995%&lt;/td&gt;
&lt;td&gt;×1.98&lt;/td&gt;
&lt;td&gt;42.18%&lt;/td&gt;
&lt;td&gt;11.22%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Over 66.67&lt;/td&gt;
&lt;td&gt;33.32%&lt;/td&gt;
&lt;td&gt;×2.97&lt;/td&gt;
&lt;td&gt;43.47%&lt;/td&gt;
&lt;td&gt;25.86%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Over 90.00&lt;/td&gt;
&lt;td&gt;9.99%&lt;/td&gt;
&lt;td&gt;×9.90&lt;/td&gt;
&lt;td&gt;40.76%&lt;/td&gt;
&lt;td&gt;42.93%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Over 99.00&lt;/td&gt;
&lt;td&gt;0.99%&lt;/td&gt;
&lt;td&gt;×100.00&lt;/td&gt;
&lt;td&gt;9.54%&lt;/td&gt;
&lt;td&gt;41.47%&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;em&gt;Replayed with the engine’s multipliers; at $1 a bet the 1% target reaches $200 with two hits (the second one landing before 100 straight misses) and busts after 100 misses in a row.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;At $1 a bet the coin flip doubles you 11% of the time and the 1-in-100 shot 41% of the time — nearly four times as often, at the same edge. The reason is the same toll: a long shot settles the question in far fewer bets, so the house collects its 1% far fewer times before you are at $200 or $0. At $10 a bet the order flips, because ten misses at ×100 is a bust before the first hit is likely.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;None of this moves the average. Every row of every table returns 99 cents per dollar wagered; the long shot only changes how the loss is distributed — many sessions that end at $0 and a few that end at $200, instead of a slow grind to the same place. If the goal is “double or nothing”, the long shot is the better tool. If the goal is time at the table, it is the worst.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  What this is not
&lt;/h2&gt;

&lt;p&gt;It is not a strategy. There is no stake, odds or game in these tables that reaches 50%, because the edge is paid on every bet and no sequence of bets avoids it — &lt;a href="https://betkyo.com/en/blog/the-martingale-priced-doubling-on-a-single-zero-wheel/" rel="noopener noreferrer"&gt;the martingale&lt;/a&gt; and its cousins only move the loss into a rare large one. What the tables do is make the trade visible: betting bigger buys a better chance of the target at the cost of a shorter session; betting a long shot buys the same thing at the cost of a wilder one.&lt;/p&gt;

&lt;p&gt;The honest use of the numbers is to pick the session you actually want before it starts. A player who wants an hour of play at $1 should know that the hour is the product and $200 is not; a player who wants to double should know that one bet at 49.995% to $198 is the best price on the board and anything slower is paying for the privilege of waiting. Our &lt;a href="https://betkyo.com/en/blog/risk-of-ruin/" rel="noopener noreferrer"&gt;risk of ruin&lt;/a&gt; piece covers the same trade in prose; this one puts the figures on it, game by game, from the engines that pay them.&lt;/p&gt;

&lt;h2&gt;
  
  
  FAQ
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;What are the odds of doubling $100 at a casino?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;At a 1% edge on dice (×1.98 at 50%): one all-in bet reaches $198 49.995% of the time; betting to $200 at a fixed stake, 42% at $10 a bet, 11% at $1, 1.6% at 50 cents. The edge is paid per bet, so the more bets the session takes, the lower the chance. At a 2.6–2.8% edge the $1-a-bet chance falls below 1%.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Is it better to bet big or small to double my money?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;To reach a target, bigger: one bet at 49.995% beats any sequence of smaller bets at the same edge, because every extra bet pays the house again. Smaller bets buy time at the table, not a better chance of the target.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Do long-shot bets give a better chance of doubling?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;At small stakes, yes. On dice at $1 a bet from $100, a 1-in-100 target at ×100 doubles you 41% of the time against 11% for the 50% target, because it settles in far fewer bets. At $10 a bet the order reverses. The average return is 99% either way.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How many bets does a session take?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;On dice at 50% with $100: one bet all in, about 100 bets at $10, about 7,600 at $1 and about 19,000 at 50 cents before the bankroll reaches $200 or can no longer cover a bet.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Which game gives the best chance of doubling?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The lowest edge at the stake you intend to use: our 1% games (dice, limbo) ahead of Koban Flip at 2%, Chinchiro at 2.6% and Sic Bo Big/Small at 2.8%. At $1 a bet the gap is one chance in nine against one in 240.&lt;/p&gt;

&lt;h2&gt;
  
  
  Sources
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Betkyo engine sources for the win chances and multipliers: OriginalBaseDiceService.kt (9,999 results; multiplier = (1 − edge) ÷ chance floored to 2dp), Koban Flip (×1.96), SicboEngine.kt (Big/Small ×2 on 105 of 216 rolls), ChinchiroDerivation.kt (97.38% return)&lt;/li&gt;
&lt;li&gt;Calculation written for this article: 200,000 replayed sessions per cell with the engine’s exact win chances and multipliers (win +stake × (multiplier − 1), loss −stake; stop at ≥ $200 or when the next bet cannot be placed), giving the doubling chance to ±0.1 point and the mean session length; the even-money gambler’s-ruin closed form for the fair coin and the Chinchiro model (Sic Bo: closed form 36.45% / 0.38% vs replay 36.53% / 0.41%)&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>math</category>
      <category>probability</category>
      <category>statistics</category>
      <category>gamedev</category>
    </item>
    <item>
      <title>The price of an hour: what each casino game costs per hour at your stake and pace</title>
      <dc:creator>Betkyo Research</dc:creator>
      <pubDate>Mon, 12 Oct 2026 07:34:45 +0000</pubDate>
      <link>https://dev.to/betkyo/the-price-of-an-hour-what-each-casino-game-costs-per-hour-at-your-stake-and-pace-4ppk</link>
      <guid>https://dev.to/betkyo/the-price-of-an-hour-what-each-casino-game-costs-per-hour-at-your-stake-and-pace-4ppk</guid>
      <description>&lt;p&gt;&lt;em&gt;Originally published on the &lt;a href="https://betkyo.com/en/blog/the-price-of-an-hour-what-each-game-costs-per-hour-at-your-stake-and-pace/" rel="noopener noreferrer"&gt;Betkyo Journal&lt;/a&gt;. Drafted with AI assistance; every figure was checked against the game engine source and approved by a human editor.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;A house edge is a price per bet. Multiply it by your stake and by how many bets an hour you make and you get the only number that compares games honestly: dollars per hour. At $10 a bet, a 1% game at a steady pace costs about the same as a coffee; the same stake on Double costs a dinner. Here is the table, with the communal games’ round timers read from the engines.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;In short:&lt;/strong&gt; Expected cost per hour = &lt;strong&gt;stake × bets per hour × house edge&lt;/strong&gt;. Per 100 bets of $10 that is &lt;strong&gt;$10 on dice, limbo, plinko, hi-lo and crash targets (1%)&lt;/strong&gt;, &lt;strong&gt;$10.60 on baccarat Banker&lt;/strong&gt;, &lt;strong&gt;$15 on RPS&lt;/strong&gt;, &lt;strong&gt;$20 on Koban Flip&lt;/strong&gt;, &lt;strong&gt;$26–28 on Chinchiro, roulette and Sic Bo Big/Small&lt;/strong&gt;, &lt;strong&gt;$33–42 on the slots&lt;/strong&gt; (Bingo, Tairyō, Hanabi) and &lt;strong&gt;$67 on Double&lt;/strong&gt;. The communal games set the pace for you: a Crash round averages &lt;strong&gt;28 s&lt;/strong&gt; (10 s betting, ~14 s flight, 3 s break), so $10 a round costs about &lt;strong&gt;$13 an hour&lt;/strong&gt;; Wheel runs ~183 spins an hour (&lt;strong&gt;$19&lt;/strong&gt;), a Dragon Road seat ~141 hands (&lt;strong&gt;$16&lt;/strong&gt;), and Double ~193 spins — &lt;strong&gt;$128 an hour&lt;/strong&gt; at the same stake, because its 6.67% edge is paid every 19 seconds. Self-paced games cost whatever pace you set: dice at one bet every four seconds is 900 bets an hour, &lt;strong&gt;$90 an hour at $10&lt;/strong&gt; and &lt;strong&gt;$9 at $1&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  A price per bet is not a price
&lt;/h2&gt;

&lt;p&gt;Every game on this site publishes its house edge, and we have spent a month computing them exactly. But an edge is a price per bet, and nobody plays one bet. What a session costs depends on three things — the edge, the stake and the number of bets — and the third one is where the games differ most. A 1% edge paid 900 times an hour is a bigger bill than a 2.7% edge paid 100 times. This article puts the three together.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Engine-verified.&lt;/strong&gt; Edges are the exact figures from the game articles in this series (dice, limbo and crash targets 1.00%; wheel 1.04%; baccarat Banker 1.06%; Dragon Road Banker 1.16%; RPS 1.50% per decided round; Koban Flip 2.00%; Casino Hold’em about 2.2% of the ante; Chinchiro 2.616%; roulette 2.70%; Sic Bo Big/Small 2.78%; Bingo 3.34%; Tairyō about 3.7%; Hanabi 4.19%; Double 6.67%; blackjack basic strategy 0.57%). Round timers are read from the engines: CrashEngine.kt grows the multiplier as 2^(t ÷ 10 s) with a 10-second betting window, a 0.9-second lock and a 3-second intermission; DoubleEngine.kt 12 s betting + 0.7 s lock + 6 s result; WheelEngine.kt 10 s betting + 0.7 s lock + 9 s spin; SbacFleetEngine.kt 20 s betting + 1.5 s lock + 4 s result per table. The average Crash flight is E[ln bust] ÷ ln 2 × 10 s with P(bust &amp;gt; x) = 0.99 ÷ x, which is 0.99 ÷ 0.0693 ≈ 14.3 s.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Per hundred bets
&lt;/h2&gt;

&lt;p&gt;Start with the stake-and-edge part and leave pace out: what 100 bets of $10 cost on average, which is simply the edge times $1,000.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Expected cost of 100 bets at $10&lt;/strong&gt;&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;GAME&lt;/th&gt;
&lt;th&gt;HOUSE EDGE&lt;/th&gt;
&lt;th&gt;PER 100 BETS&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Blackjack, basic strategy&lt;/td&gt;
&lt;td&gt;0.57%&lt;/td&gt;
&lt;td&gt;$5.70&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Dice · Limbo · Crash targets · Plinko · Hi-Lo · Pagoda (Hard)&lt;/td&gt;
&lt;td&gt;1.00%&lt;/td&gt;
&lt;td&gt;$10.00&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Wheel&lt;/td&gt;
&lt;td&gt;1.04%&lt;/td&gt;
&lt;td&gt;$10.40&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Baccarat, Banker&lt;/td&gt;
&lt;td&gt;1.06%&lt;/td&gt;
&lt;td&gt;$10.60&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Keno (all 40 tables)&lt;/td&gt;
&lt;td&gt;0.93–1.35%&lt;/td&gt;
&lt;td&gt;$9.30–13.50&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;RPS (per decided round)&lt;/td&gt;
&lt;td&gt;1.50%&lt;/td&gt;
&lt;td&gt;$15.00&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Koban Flip&lt;/td&gt;
&lt;td&gt;2.00%&lt;/td&gt;
&lt;td&gt;$20.00&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Casino Hold’em (of the ante)&lt;/td&gt;
&lt;td&gt;≈2.2%&lt;/td&gt;
&lt;td&gt;≈$22&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Chinchiro&lt;/td&gt;
&lt;td&gt;2.62%&lt;/td&gt;
&lt;td&gt;$26.20&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Roulette (single zero)&lt;/td&gt;
&lt;td&gt;2.70%&lt;/td&gt;
&lt;td&gt;$27.00&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Video poker 8/5, best hold&lt;/td&gt;
&lt;td&gt;2.70%&lt;/td&gt;
&lt;td&gt;$27.00&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Sic Bo, Big / Small&lt;/td&gt;
&lt;td&gt;2.78%&lt;/td&gt;
&lt;td&gt;$27.80&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Bingo&lt;/td&gt;
&lt;td&gt;3.34%&lt;/td&gt;
&lt;td&gt;$33.40&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Tairyō&lt;/td&gt;
&lt;td&gt;≈3.7%&lt;/td&gt;
&lt;td&gt;≈$37&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Hanabi&lt;/td&gt;
&lt;td&gt;4.19%&lt;/td&gt;
&lt;td&gt;$41.90&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Double, any colour&lt;/td&gt;
&lt;td&gt;6.67%&lt;/td&gt;
&lt;td&gt;$66.70&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;em&gt;Mines runs 1.0–2.5% depending on the rung (small multipliers cost more); dice between its round targets runs up to 1.97%. Expected cost is the average over many sessions — any one hour can land far from it, which is the subject of the risk-of-ruin and doubling pieces.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Read down the column and the games sort into four groups: the 1% originals and blackjack, the 1.5–2% streak games, the 2.6–2.8% table classics, and the 3–7% slots and Double. The gap between the top and bottom of the table is a factor of twelve at the same stake. That gap is the whole point of knowing the edge — and it is still only half the price.&lt;/p&gt;

&lt;h2&gt;
  
  
  The communal games set the pace
&lt;/h2&gt;

&lt;p&gt;Four games run on the house’s clock, not yours: Crash, Wheel, Double and Dragon Road. Their round lengths are constants in the engines, so their hourly cost at a flat stake is fixed too.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Communal games: round length and cost per hour at $10 a round&lt;/strong&gt;&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;GAME&lt;/th&gt;
&lt;th&gt;ROUND&lt;/th&gt;
&lt;th&gt;ROUNDS / HOUR&lt;/th&gt;
&lt;th&gt;EDGE&lt;/th&gt;
&lt;th&gt;COST / HOUR&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Crash&lt;/td&gt;
&lt;td&gt;10 s betting + 0.9 s lock + ~14.3 s flight + 3 s break ≈ 28 s&lt;/td&gt;
&lt;td&gt;≈128&lt;/td&gt;
&lt;td&gt;1.00%&lt;/td&gt;
&lt;td&gt;≈$13&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Dragon Road (one table)&lt;/td&gt;
&lt;td&gt;20 s betting + 1.5 s lock + 4 s result = 25.5 s&lt;/td&gt;
&lt;td&gt;≈141&lt;/td&gt;
&lt;td&gt;1.16% (Banker)&lt;/td&gt;
&lt;td&gt;≈$16&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Wheel&lt;/td&gt;
&lt;td&gt;10 s betting + 0.7 s lock + 9 s spin = 19.7 s&lt;/td&gt;
&lt;td&gt;≈183&lt;/td&gt;
&lt;td&gt;1.04%&lt;/td&gt;
&lt;td&gt;≈$19&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Double&lt;/td&gt;
&lt;td&gt;12 s betting + 0.7 s lock + 6 s result = 18.7 s&lt;/td&gt;
&lt;td&gt;≈193&lt;/td&gt;
&lt;td&gt;6.67%&lt;/td&gt;
&lt;td&gt;≈$128&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;em&gt;Crash’s flight is the only variable: the multiplier doubles every 10 seconds and the round busts at a point with P(bust &amp;gt; x) = 0.99 ÷ x, so the average flight is ≈14.3 s; one round in a hundred busts instantly. Dragon Road Player is 1.37%, Tie 14.3%.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Double is the outlier and worth saying plainly: at $10 a spin it costs about ten times what Crash costs at $10 a round, because it has six times the edge and runs half again as fast. Nothing about that is hidden — both numbers are printed — but neither is printed as dollars per hour, and that is the figure that matters to a wallet.&lt;/p&gt;

&lt;h2&gt;
  
  
  The self-paced games cost what you set
&lt;/h2&gt;

&lt;p&gt;Dice, limbo, plinko, mines, keno, the card games and the slots have no round timer; the pace is yours. The arithmetic is the same — stake × bets per hour × edge — and the pace term is the one that moves most.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Dice at a 50% target (1% edge): cost per hour by stake and pace&lt;/strong&gt;&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;PACE&lt;/th&gt;
&lt;th&gt;BETS / HOUR&lt;/th&gt;
&lt;th&gt;$1 A BET&lt;/th&gt;
&lt;th&gt;$10 A BET&lt;/th&gt;
&lt;th&gt;$100 A BET&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;One bet every 30 s&lt;/td&gt;
&lt;td&gt;120&lt;/td&gt;
&lt;td&gt;$1.20&lt;/td&gt;
&lt;td&gt;$12&lt;/td&gt;
&lt;td&gt;$120&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;One bet every 10 s&lt;/td&gt;
&lt;td&gt;360&lt;/td&gt;
&lt;td&gt;$3.60&lt;/td&gt;
&lt;td&gt;$36&lt;/td&gt;
&lt;td&gt;$360&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;One bet every 4 s&lt;/td&gt;
&lt;td&gt;900&lt;/td&gt;
&lt;td&gt;$9.00&lt;/td&gt;
&lt;td&gt;$90&lt;/td&gt;
&lt;td&gt;$900&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Auto-bet, one per second&lt;/td&gt;
&lt;td&gt;3,600&lt;/td&gt;
&lt;td&gt;$36&lt;/td&gt;
&lt;td&gt;$360&lt;/td&gt;
&lt;td&gt;$3,600&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;em&gt;Multiply any cell by the edge ratio for another game: ×2.7 for roulette, ×4.19 for Hanabi, ×6.67 for Double. Auto-bet at $10 on Double would be about $2,400 an hour.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Two things fall out of the table. First, pace is a bigger lever than game choice: moving from one bet every 10 seconds to auto-bet multiplies the hourly cost by ten, more than the gap between dice and Double. Second, the stake lever is linear and honest — $1 bets cost a tenth of $10 bets per hour — which is why &lt;a href="https://betkyo.com/en/blog/doubling-100-dollars-priced-the-chance-of-doubling-before-busting-at-every-stake-and-edge/" rel="noopener noreferrer"&gt;the doubling piece&lt;/a&gt; found the opposite about reaching a target: small bets are cheap per hour and expensive per goal.&lt;/p&gt;

&lt;h2&gt;
  
  
  What to do with the number
&lt;/h2&gt;

&lt;p&gt;Decide what an hour is worth to you before it starts, and pick the stake and pace that price it there. At $1 a bet and a relaxed pace, every game on the site costs less than $10 an hour in expectation; at $10 and auto-bet, none costs less than $36 and several cost hundreds. The games that feel the same — a chip on red, a chip on a colour in Double — are a factor of 2.5 apart per bet and nearly 4 apart per hour.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Expected cost is not a guarantee in either direction. In one hour the variance dwarfs the edge — on dice at 360 bets of $10 the standard deviation of the hour’s result is about $190 against an expected loss of $36 — which is exactly why the edge is easy to ignore and expensive to ignore. Over many hours the expectation is what you pay.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  FAQ
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;How much does an hour of casino play cost?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Stake × bets per hour × house edge. At $10 a bet and 360 bets an hour: about $36 on a 1% game (dice, limbo, crash), $97 on roulette, $151 on Hanabi, $240 on Double. At $1 a bet, a tenth of that.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Which game is cheapest per hour?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Per bet, blackjack at basic strategy (0.57%) and the 1% originals. Per hour it depends on pace: the communal games are fixed — Crash about $13 an hour at $10 a round, Wheel $19, Dragon Road $16, Double $128 — and self-paced games cost whatever pace you set.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How long is a Crash round?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;About 28 seconds on average: a 10-second betting window, a 0.9-second lock, a flight that averages 14.3 seconds (the multiplier doubles every 10 seconds; one round in 100 busts instantly) and a 3-second intermission. About 128 rounds an hour.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why is Double so much more expensive than Crash?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Six times the edge (6.67% against 1%) and a faster round (18.7 s against about 28 s). At $10 a round that is roughly $128 an hour against $13.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Does betting slower change the house edge?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;No — it changes how many times you pay it. The edge per bet is fixed; bets per hour is the lever. Halving the pace halves the expected hourly cost at the same stake.&lt;/p&gt;

&lt;h2&gt;
  
  
  Sources
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Betkyo engine sources: CrashEngine.kt (GROWTH_R = ln 2 ÷ 10; betting-seconds 10; lock-ms 900; intermission-seconds 3), DoubleEngine.kt (betting-seconds 12; lock-ms 700; result-seconds 6), WheelEngine.kt (betting-seconds 10; lock-ms 700; spin-seconds 9), SbacFleetEngine.kt (bettingMs 20,000; lockMs 1,500; resultMs 4,000)&lt;/li&gt;
&lt;li&gt;House edges: the exact figures computed in this series’ game articles (dice, limbo, crash, wheel, plinko, hi-lo, pagoda, keno, RPS, Koban Flip, Chinchiro, roulette, Sic Bo, baccarat, Casino Hold’em, video poker, blackjack, Bingo, Tairyō, Hanabi, Double, Dragon Road); Crash average flight = E[ln bust] ÷ r with P(bust &amp;gt; x) = 0.99 ÷ x on [1, 9,999.99]&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>math</category>
      <category>probability</category>
      <category>statistics</category>
      <category>gamedev</category>
    </item>
    <item>
      <title>Dice, priced exactly: the true win chance and return behind every target</title>
      <dc:creator>Betkyo Research</dc:creator>
      <pubDate>Mon, 28 Sep 2026 03:42:46 +0000</pubDate>
      <link>https://dev.to/betkyo/dice-priced-exactly-the-true-win-chance-and-return-behind-every-target-abl</link>
      <guid>https://dev.to/betkyo/dice-priced-exactly-the-true-win-chance-and-return-behind-every-target-abl</guid>
      <description>&lt;p&gt;&lt;em&gt;Originally published in the &lt;a href="https://betkyo.com/en/blog/dice-odds-priced-the-true-win-chance-and-return-behind-every-target/" rel="noopener noreferrer"&gt;Betkyo Journal&lt;/a&gt;. Drafted with AI assistance; every figure was checked against the game engine source and approved by a human editor.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;A dice screen shows two numbers, a win chance and a multiplier, and multiplying them gives 99% — at some targets. The roll has 9,999 possible results, not 10,000, and the multiplier is cut to two decimals, so the real return moves between 98.03% and 99.00% depending on where the target sits. Here is the exact price of every setting, and the one habit that avoids nearly all of the difference.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Quick answer:&lt;/strong&gt; Each roll is one of &lt;strong&gt;9,999 equally likely results, 0.01 to 99.99&lt;/strong&gt;. Roll under 50 wins on 4,999 of them, so the true chance is &lt;strong&gt;49.995%&lt;/strong&gt;, not 50%, and a result of exactly 50.00 loses both Under and Over. The multiplier is 0.99 ÷ the shown chance &lt;strong&gt;floored to two decimals&lt;/strong&gt;. Where that division lands exactly, as at 50 (×1.98), 25 (×3.96) or 10 (×9.90), the true return is &lt;strong&gt;98.91–99.00%&lt;/strong&gt;; where it does not, the floor adds cost — &lt;strong&gt;target 80 pays ×1.23 and returns 98.40%&lt;/strong&gt;, and &lt;strong&gt;97.06 pays ×1.01 and returns 98.03%&lt;/strong&gt;, the worst setting on the slider. Across all 9,601 slider positions from 2.00 to 98.00 the average return is &lt;strong&gt;98.72%&lt;/strong&gt;. &lt;strong&gt;Typing the multiplier instead of dragging the slider&lt;/strong&gt; picks the target that prices cleanly: ×2 returns &lt;strong&gt;98.99%&lt;/strong&gt;, ×10 &lt;strong&gt;98.91%&lt;/strong&gt;, ×49.5 &lt;strong&gt;98.51%&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  One roll, 9,999 results
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://betkyo.com/en/dice/" rel="noopener noreferrer"&gt;Dice&lt;/a&gt; is the simplest game on the site: choose a target, choose Under or Over, and the roll either lands on your side of it or does not. The screen quotes a win chance and a multiplier for every target, and the two look like they multiply to exactly 99% — the stake back, less a 1% house edge. The engine is a little more particular than the screen, in two ways that both cost the player, and this article prices them exactly.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Verified in the engine:&lt;/strong&gt; OriginalBaseDiceService.kt: getResult() draws nextIntBelow(9999) + 1 and divides by 100, so the result is one of the 9,999 values 0.01 to 99.99 — 0.00 excluded, 99.99 included. getWinChance() is target ÷ 100 for Under and (100 − target) ÷ 100 for Over. checkAndGetMultiplier() is (1 − house edge) ÷ win chance, floored to two decimals. getEarned() compares strictly: Under wins when the result is below the target, Over when it is above. The random number is the first 13 hex digits of HMAC-SHA256 over “clientSeed-nonce-0”, keyed by the server seed, divided by 2⁵²; the client mirror is payoutMultiplier() in dice/diceApi.ts, and diceGame.tsx limits the slider to targets 2.00–98.00.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The house service carries its own test of this arithmetic, DiceHouseEdgeTest, which checks that no target ever returns more than 99% and that the floor never takes more than one rounding step. Both hold. What the test does not print is how much each target actually returns, and that is the table a player needs.&lt;/p&gt;

&lt;h2&gt;
  
  
  The shown chance and the true chance
&lt;/h2&gt;

&lt;p&gt;The win chance on screen is computed as if the roll were a continuous number from 0 to 100. It is not: it is one of 9,999 steps. Roll under a target T wins on the results 0.01 up to T − 0.01, which is 100 × T − 1 of them, so the true chance is (100T − 1) ÷ 9,999. At most targets the difference is invisible; at the smallest ones it is not.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Roll under a target: winning results, shown chance and true chance&lt;/em&gt;&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;TARGET (UNDER)&lt;/th&gt;
&lt;th&gt;WINNING RESULTS OF 9,999&lt;/th&gt;
&lt;th&gt;SHOWN CHANCE&lt;/th&gt;
&lt;th&gt;TRUE CHANCE&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;2.00&lt;/td&gt;
&lt;td&gt;199&lt;/td&gt;
&lt;td&gt;2.00%&lt;/td&gt;
&lt;td&gt;1.9902%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;5.00&lt;/td&gt;
&lt;td&gt;499&lt;/td&gt;
&lt;td&gt;5.00%&lt;/td&gt;
&lt;td&gt;4.9905%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;10.00&lt;/td&gt;
&lt;td&gt;999&lt;/td&gt;
&lt;td&gt;10.00%&lt;/td&gt;
&lt;td&gt;9.9910%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;25.00&lt;/td&gt;
&lt;td&gt;2,499&lt;/td&gt;
&lt;td&gt;25.00%&lt;/td&gt;
&lt;td&gt;24.9925%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;50.00&lt;/td&gt;
&lt;td&gt;4,999&lt;/td&gt;
&lt;td&gt;50.00%&lt;/td&gt;
&lt;td&gt;49.9950%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;75.00&lt;/td&gt;
&lt;td&gt;7,499&lt;/td&gt;
&lt;td&gt;75.00%&lt;/td&gt;
&lt;td&gt;74.9975%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;90.00&lt;/td&gt;
&lt;td&gt;8,999&lt;/td&gt;
&lt;td&gt;90.00%&lt;/td&gt;
&lt;td&gt;89.9990%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;98.00&lt;/td&gt;
&lt;td&gt;9,799&lt;/td&gt;
&lt;td&gt;98.00%&lt;/td&gt;
&lt;td&gt;97.9998%&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;em&gt;True chance = (100 × target − 1) ÷ 9,999. Roll over a target T wins on 9,999 − 100T results, so Over T is priced exactly like Under (100 − T): Over 50 also wins on 4,999 results.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The gap is always one result. At a 50% target it costs 0.005 percentage points of chance, a hundredth of a percent of return; at the 2% target, the tightest the slider allows, one result out of 200 is about half a percent of the win chance, and the return drops from 99.00% to 98.51% for that reason alone. The same fact explains a small curiosity: a roll of exactly 50.00 loses Under 50 and Over 50 alike, because neither comparison includes the target. It happens once in 9,999 rolls.&lt;/p&gt;

&lt;h2&gt;
  
  
  The two-decimal floor
&lt;/h2&gt;

&lt;p&gt;The second cost is the multiplier. The engine divides 0.99 by the win chance and keeps two decimals, always rounding down. When the division comes out exact — 0.99 ÷ 0.50 = 1.98, 0.99 ÷ 0.25 = 3.96 — nothing is lost. When it does not, the player is paid the truncated figure: 0.99 ÷ 0.80 = 1.2375, paid as ×1.23. At a high win chance the multiplier is close to 1, the hundredth that gets dropped is a large share of the profit, and the return falls much further than at the low end.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;What a roll-under target pays and returns, 1% house edge&lt;/em&gt;&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;TARGET (UNDER)&lt;/th&gt;
&lt;th&gt;PAYS&lt;/th&gt;
&lt;th&gt;SHOWN CHANCE × PAYS&lt;/th&gt;
&lt;th&gt;TRUE RETURN&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;2.00&lt;/td&gt;
&lt;td&gt;×49.50&lt;/td&gt;
&lt;td&gt;99.00%&lt;/td&gt;
&lt;td&gt;98.51%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;5.00&lt;/td&gt;
&lt;td&gt;×19.80&lt;/td&gt;
&lt;td&gt;99.00%&lt;/td&gt;
&lt;td&gt;98.81%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;7.00&lt;/td&gt;
&lt;td&gt;×14.14&lt;/td&gt;
&lt;td&gt;98.98%&lt;/td&gt;
&lt;td&gt;98.85%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;10.00&lt;/td&gt;
&lt;td&gt;×9.90&lt;/td&gt;
&lt;td&gt;99.00%&lt;/td&gt;
&lt;td&gt;98.91%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;13.00&lt;/td&gt;
&lt;td&gt;×7.61&lt;/td&gt;
&lt;td&gt;98.93%&lt;/td&gt;
&lt;td&gt;98.86%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;25.00&lt;/td&gt;
&lt;td&gt;×3.96&lt;/td&gt;
&lt;td&gt;99.00%&lt;/td&gt;
&lt;td&gt;98.97%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;40.00&lt;/td&gt;
&lt;td&gt;×2.47&lt;/td&gt;
&lt;td&gt;98.80%&lt;/td&gt;
&lt;td&gt;98.79%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;50.00&lt;/td&gt;
&lt;td&gt;×1.98&lt;/td&gt;
&lt;td&gt;99.00%&lt;/td&gt;
&lt;td&gt;98.99%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;70.00&lt;/td&gt;
&lt;td&gt;×1.41&lt;/td&gt;
&lt;td&gt;98.70%&lt;/td&gt;
&lt;td&gt;98.70%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;80.00&lt;/td&gt;
&lt;td&gt;×1.23&lt;/td&gt;
&lt;td&gt;98.40%&lt;/td&gt;
&lt;td&gt;98.40%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;90.00&lt;/td&gt;
&lt;td&gt;×1.10&lt;/td&gt;
&lt;td&gt;99.00%&lt;/td&gt;
&lt;td&gt;99.00%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;95.00&lt;/td&gt;
&lt;td&gt;×1.04&lt;/td&gt;
&lt;td&gt;98.80%&lt;/td&gt;
&lt;td&gt;98.80%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;97.06&lt;/td&gt;
&lt;td&gt;×1.01&lt;/td&gt;
&lt;td&gt;98.03%&lt;/td&gt;
&lt;td&gt;98.03%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;98.00&lt;/td&gt;
&lt;td&gt;×1.01&lt;/td&gt;
&lt;td&gt;98.98%&lt;/td&gt;
&lt;td&gt;98.98%&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;em&gt;True return = multiplier × (100 × target − 1) ÷ 9,999. At 90.00 it is 98.999%, the highest on the slider; at 97.06 it is 98.030%, the lowest. Over targets mirror these rows: Over T returns what Under (100 − T) returns.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Read the two right-hand columns together and the two costs separate cleanly. At low targets the multiplier usually divides exactly and the whole shortfall is the missing result; at high targets the missing result is negligible and the shortfall is almost all floor. Target 80 is the clearest case: 0.99 ÷ 0.8 needs ×1.2375, the table pays ×1.23, and the return is 98.40% — a house edge of 1.6%, not 1%. Every target between 97.06 and 98.00 pays the same ×1.01, so the chance you give up by moving to 97.06 buys nothing.&lt;/p&gt;

&lt;p&gt;Over the whole slider — every target from 2.00 to 98.00 in steps of 0.01, 9,601 settings — the true return averages 98.72%. Only 585 of those settings, 6.1%, return 98.95% or more; 1,453, 15.1%, return less than 98.50%.&lt;/p&gt;

&lt;h2&gt;
  
  
  Type the multiplier, not the percentage
&lt;/h2&gt;

&lt;p&gt;The game has a second way to set a bet: type the multiplier you want, and it works out the target. It chooses the target whose floored payout is at least what you typed, so a typed multiplier always lands on a setting where 0.99 ÷ chance divides cleanly. That removes the floor cost entirely; only the one-result gap remains.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Typed multipliers and the targets they resolve to&lt;/em&gt;&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;TYPED&lt;/th&gt;
&lt;th&gt;TARGET (UNDER)&lt;/th&gt;
&lt;th&gt;TRUE CHANCE&lt;/th&gt;
&lt;th&gt;TRUE RETURN&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;×1.10&lt;/td&gt;
&lt;td&gt;90.00&lt;/td&gt;
&lt;td&gt;89.9990%&lt;/td&gt;
&lt;td&gt;99.00%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;×1.20&lt;/td&gt;
&lt;td&gt;82.50&lt;/td&gt;
&lt;td&gt;82.4982%&lt;/td&gt;
&lt;td&gt;99.00%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;×1.50&lt;/td&gt;
&lt;td&gt;66.00&lt;/td&gt;
&lt;td&gt;65.9966%&lt;/td&gt;
&lt;td&gt;98.99%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;×2&lt;/td&gt;
&lt;td&gt;49.50&lt;/td&gt;
&lt;td&gt;49.4949%&lt;/td&gt;
&lt;td&gt;98.99%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;×3&lt;/td&gt;
&lt;td&gt;33.00&lt;/td&gt;
&lt;td&gt;32.9933%&lt;/td&gt;
&lt;td&gt;98.98%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;×5&lt;/td&gt;
&lt;td&gt;19.80&lt;/td&gt;
&lt;td&gt;19.7920%&lt;/td&gt;
&lt;td&gt;98.96%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;×10&lt;/td&gt;
&lt;td&gt;9.90&lt;/td&gt;
&lt;td&gt;9.8910%&lt;/td&gt;
&lt;td&gt;98.91%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;×20&lt;/td&gt;
&lt;td&gt;4.95&lt;/td&gt;
&lt;td&gt;4.9405%&lt;/td&gt;
&lt;td&gt;98.81%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;×49.50&lt;/td&gt;
&lt;td&gt;2.00&lt;/td&gt;
&lt;td&gt;1.9902%&lt;/td&gt;
&lt;td&gt;98.51%&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;em&gt;targetForMultiplier() in dice/diceApi.ts floors the Under target (or ceils the Over target) so the chance never rises above the one the typed multiplier implies. Returns rounded to two decimals; ×1.10 is 98.999% and ×1.20 98.998%.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The practical rule is short. If you care about the last half-point, set the multiplier rather than the percentage, and prefer round multipliers at the low end of the payout range. A target chosen because it looks round as a percentage — 80, 70, 40 — is often a worse price than the target one tick away. None of this changes the long-run direction: every setting returns less than the stake, and &lt;a href="https://betkyo.com/en/blog/the-martingale-priced-doubling-on-a-single-zero-wheel/" rel="noopener noreferrer"&gt;the martingale, priced&lt;/a&gt; and &lt;a href="https://betkyo.com/en/blog/risk-of-ruin/" rel="noopener noreferrer"&gt;risk of ruin&lt;/a&gt; explain why no sequence of bets fixes that.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;a href="https://betkyo.com/en/blog/limbo-odds-priced-the-win-chance-behind-every-target-multiplier/" rel="noopener noreferrer"&gt;Limbo&lt;/a&gt; avoids the floor by construction: the player names the payout directly and the drawn number is compared against that same figure, so there is no second rounding to pay for. Dice quotes a chance and derives the payout from it, and that derivation is where the floor enters.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Checking a roll yourself
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Before you play, the fairness panel shows the SHA-256 fingerprint of the server seed. Rotate your seed pair afterwards to reveal the seed and confirm the fingerprint.&lt;/li&gt;
&lt;li&gt;Compute HMAC-SHA256 with the server seed as the key and “clientSeed-nonce-0” as the message; a roll uses cursor 0 only.&lt;/li&gt;
&lt;li&gt;Read the first 13 hex digits of the digest as an integer and divide by 2⁵² to get u. The result is (floor(u × 9,999) + 1) ÷ 100. Compare it with your target, strictly, and the multiplier on your ticket with 0.99 ÷ chance floored to two decimals.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If the result matches, it was fixed before you chose a target — which, as &lt;a href="https://betkyo.com/en/blog/what-a-hash-commitment-proves/" rel="noopener noreferrer"&gt;what a hash commitment proves&lt;/a&gt; explains, is what the commitment guarantees and all it guarantees. The price of the target is not in the hash. It is in the two lines of arithmetic above, which is why this article exists.&lt;/p&gt;

&lt;h2&gt;
  
  
  FAQ
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;What are the real odds in a dice game that rolls 0 to 100?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Here the roll is one of 9,999 results from 0.01 to 99.99. Roll under T wins on 100 × T − 1 of them, so roll under 50 is 49.995%, roll under 10 is 9.991% and roll under 2 is 1.990%.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What is the house edge on dice?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The stated edge is 1%, but the true return depends on the target: from 99.00% at a target of 90 to 98.03% at 97.06. Averaged over every slider setting from 2.00 to 98.00 it is 98.72%, an effective edge of 1.28%.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why does my dice multiplier look rounded down?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The engine pays 0.99 ÷ win chance floored to two decimals. At an 80% target that is 1.2375, paid as ×1.23, which returns 98.40% instead of 99%.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What is the best target to pick in dice?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Any target where 0.99 ÷ chance divides exactly, such as 50 (×1.98), 25 (×3.96), 90 (×1.10) or 66 (×1.50). Typing the multiplier instead of the percentage finds one automatically. No target returns more than 99%.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What happens if the dice roll lands exactly on my target?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;It loses. Under wins only below the target and Over only above it, so a roll of exactly 50.00 loses both Under 50 and Over 50. It happens once in 9,999 rolls.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Can I verify a dice roll?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Yes. HMAC-SHA256 of “clientSeed-nonce-0” keyed by the revealed server seed; the first 13 hex digits over 2⁵² give u, and (floor(u × 9,999) + 1) ÷ 100 is the result.&lt;/p&gt;

&lt;h2&gt;
  
  
  Sources
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Betkyo engine source, house service: OriginalBaseDiceService.kt — getResult() (nextIntBelow(9999) + 1, over 100), getWinChance() (4-decimal floor), checkAndGetMultiplier() ((1 − house edge) ÷ win chance, 2-decimal floor), getEarned() (strict comparison); SeedPairRandom and PfHashUtils.normalize() (first 13 hex digits ÷ 2⁵²); DiceHouseEdgeTest.kt&lt;/li&gt;
&lt;li&gt;Betkyo engine source, client mirror: payoutMultiplier() and targetForMultiplier() in dice/diceApi.ts; the 2.00–98.00 slider bounds in diceGame.tsx&lt;/li&gt;
&lt;li&gt;Exact calculation written for this article: (100T − 1) ÷ 9,999 win chances and floored multipliers for all 9,601 slider targets, their true returns and distribution; cross-checked by replaying 400,000 rolls of the HMAC stream through the result derivation (roll under 50: 49.88% simulated vs 49.995% exact; results spanned 0.01 to 99.99)&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>math</category>
      <category>probability</category>
      <category>statistics</category>
    </item>
    <item>
      <title>Roulette hit rates, priced: how long a number takes and what a streak is worth</title>
      <dc:creator>Betkyo Research</dc:creator>
      <pubDate>Wed, 23 Sep 2026 02:35:36 +0000</pubDate>
      <link>https://dev.to/betkyo/roulette-hit-rates-priced-how-long-a-number-takes-and-what-a-streak-is-worth-3lao</link>
      <guid>https://dev.to/betkyo/roulette-hit-rates-priced-how-long-a-number-takes-and-what-a-streak-is-worth-3lao</guid>
      <description>&lt;p&gt;&lt;em&gt;Originally published in the &lt;a href="https://betkyo.com/en/blog/roulette-hit-rates-priced-how-long-a-number-takes-and-what-a-streak-is-worth/" rel="noopener noreferrer"&gt;Betkyo Journal&lt;/a&gt;. Drafted with AI assistance; every figure was checked against the game engine source and approved by a human editor.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Every bet on this single-zero wheel costs the same 2.7%, so the interesting questions are the ones the price does not answer: how many spins a number usually takes, how often a colour runs eight deep, how long zero can stay away, and how far a session can drift from its expected loss. Here are the answers, computed from the engine’s 37 pockets.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Quick answer:&lt;/strong&gt; On this engine’s European roulette every pocket lands &lt;strong&gt;1 in 37&lt;/strong&gt; per spin. A straight-up number takes &lt;strong&gt;37 spins on average but only 26 to have a 50% chance of appearing&lt;/strong&gt;; it is absent from &lt;strong&gt;100 spins 6.5% of the time&lt;/strong&gt; and from 200 spins 0.4%. Red comes up &lt;strong&gt;five times in a row 2.7%&lt;/strong&gt; of the time and &lt;strong&gt;ten times in a row 0.07%&lt;/strong&gt;; an even-money bet loses &lt;strong&gt;eight in a row 0.48%&lt;/strong&gt;, roughly once every 207 spins. Zero has landed at least once in 37 spins &lt;strong&gt;63.7%&lt;/strong&gt; of the time — so it is absent from a full wheel’s worth of spins more than a third of the time. Every bet returns &lt;strong&gt;97.30%&lt;/strong&gt;, but the swing is not the same: over 100 one-unit spins the expected loss is 2.7 units on every bet, while the standard deviation is about &lt;strong&gt;10 units on red&lt;/strong&gt;, 14 on a dozen and &lt;strong&gt;58 on a straight-up number&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  One spin, thirty-seven pockets
&lt;/h2&gt;

&lt;p&gt;Roulette on this site is a single-zero wheel, and the whole of its arithmetic rests on one fact: each spin lands on one of 37 pockets with equal chance. &lt;a href="https://betkyo.com/en/blog/a-roulette-bet-is-a-string-self-describing-keys-and-the-36-table/" rel="noopener noreferrer"&gt;A roulette bet is a string&lt;/a&gt; walked through the consequence for price — every bet returns 36 ÷ 37 = 97.30%. This article is about everything the price leaves out: how long things take, how often they cluster, and how much a session can wander.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Verified in the engine:&lt;/strong&gt; deriveRouletteSpin() in roulette/derive.ts: the pocket is floor(u × 37) from cursor 0 of the round’s HMAC, u = hi ÷ 2³² + lo ÷ 2⁶⁴ (u64()); the server port RouletteEngine.derivePocket() uses U64SeedStream(...).intBelow(37). Settlement pays stake × multiplier per covering key (×36 straight, ×18 split, ×12 street, ×9 corner and first four, ×6 six line, ×3 dozen and column, ×2 even chances); the multipliers are whole numbers, so nothing is lost to rounding. One nonce settles the whole table in one spin.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Two things follow from the derivation. Each spin is a fresh HMAC of a fresh nonce, so spins are independent: the wheel has no memory, and every figure below is a plain power or a binomial count. And the 37 pockets are equally likely to within one part in 2⁶⁴, so the physical wheel-bias stories from &lt;a href="https://betkyo.com/en/blog/wheel-bias-jagger-and-garcia-pelayo/" rel="noopener noreferrer"&gt;Jaggers and Garcia-Pelayo&lt;/a&gt; have no counterpart here: there is no worn fret to find.&lt;/p&gt;

&lt;h2&gt;
  
  
  How long a number takes
&lt;/h2&gt;

&lt;p&gt;A straight-up number wins 1 in 37 per spin, so the average wait between hits is 37 spins. Averages mislead on waiting times, because the distribution is lopsided: most gaps are shorter than 37 and a few are very long. The useful figures are the chances of seeing the number within a given stretch, which is 1 − (36 ÷ 37)ᴺ.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Chance that a chosen number lands at least once, betting it every spin&lt;/em&gt;&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;SPINS&lt;/th&gt;
&lt;th&gt;AT LEAST ONE HIT&lt;/th&gt;
&lt;th&gt;NO HIT AT ALL&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;10&lt;/td&gt;
&lt;td&gt;23.97%&lt;/td&gt;
&lt;td&gt;76.03%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;26&lt;/td&gt;
&lt;td&gt;50.95%&lt;/td&gt;
&lt;td&gt;49.05%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;37&lt;/td&gt;
&lt;td&gt;63.71%&lt;/td&gt;
&lt;td&gt;36.29%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;50&lt;/td&gt;
&lt;td&gt;74.59%&lt;/td&gt;
&lt;td&gt;25.41%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;100&lt;/td&gt;
&lt;td&gt;93.54%&lt;/td&gt;
&lt;td&gt;6.46%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;150&lt;/td&gt;
&lt;td&gt;98.36%&lt;/td&gt;
&lt;td&gt;1.64%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;200&lt;/td&gt;
&lt;td&gt;99.58%&lt;/td&gt;
&lt;td&gt;0.42%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;300&lt;/td&gt;
&lt;td&gt;99.97%&lt;/td&gt;
&lt;td&gt;0.03%&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;em&gt;No hit in N spins = (36 ÷ 37)ᴺ. The median wait is 26 spins, the first N at which the chance of a hit passes one half; the mean is 37. In 37 spins the number lands exactly once 37.3% of the time and two or more times 26.4%.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The row that surprises people is the third one: play your number for a full wheel’s worth of spins, 37 of them, and more than a third of the time it never comes. That is not bad luck; it is the ordinary shape of a 1-in-37 event. A hundred spins leaves a 6.5% chance of an empty run, one session in fifteen, and each of those sessions costs 100 units for nothing back.&lt;/p&gt;

&lt;p&gt;The same table describes zero, which is just another pocket. Zero lands at least once in 37 spins 63.7% of the time, in 74 spins 86.8%, in 10 spins 24.0%. A table that has not shown zero for fifty spins is not “due” — the next spin is 1 ÷ 37 exactly as it was — and a table that showed it twice in ten is not “hot”. &lt;a href="https://betkyo.com/en/blog/gamblers-fallacy/" rel="noopener noreferrer"&gt;The gambler’s fallacy&lt;/a&gt; is the belief that the wheel keeps a ledger; the hash does not.&lt;/p&gt;

&lt;h2&gt;
  
  
  What a streak is worth
&lt;/h2&gt;

&lt;p&gt;Colour runs are the streaks players remember, and on a single-zero wheel they are less rare than they feel. Red wins 18 ÷ 37 of spins; the chance of k reds in a row is (18 ÷ 37)ᵏ. The losing side of an even-money bet is 19 ÷ 37, because zero counts against it, so losing runs are slightly likelier than winning ones of the same length.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Runs on an even-money bet, single-zero wheel&lt;/em&gt;&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;RUN LENGTH&lt;/th&gt;
&lt;th&gt;SAME COLOUR (WIN) RUN&lt;/th&gt;
&lt;th&gt;LOSING RUN (INCL. ZERO)&lt;/th&gt;
&lt;th&gt;A LOSING RUN THIS LONG STARTS ABOUT ONCE IN&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;11.51%&lt;/td&gt;
&lt;td&gt;13.54%&lt;/td&gt;
&lt;td&gt;15 spins&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;2.72%&lt;/td&gt;
&lt;td&gt;3.57%&lt;/td&gt;
&lt;td&gt;58 spins&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;8&lt;/td&gt;
&lt;td&gt;0.31%&lt;/td&gt;
&lt;td&gt;0.48%&lt;/td&gt;
&lt;td&gt;425 spins&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;10&lt;/td&gt;
&lt;td&gt;0.074%&lt;/td&gt;
&lt;td&gt;0.128%&lt;/td&gt;
&lt;td&gt;1,610 spins&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;13&lt;/td&gt;
&lt;td&gt;0.009%&lt;/td&gt;
&lt;td&gt;0.017%&lt;/td&gt;
&lt;td&gt;12,000 spins&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;15&lt;/td&gt;
&lt;td&gt;0.002%&lt;/td&gt;
&lt;td&gt;0.005%&lt;/td&gt;
&lt;td&gt;45,000 spins&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;em&gt;Win run = (18 ÷ 37)ᵏ, losing run = (19 ÷ 37)ᵏ. The last column is 1 ÷ ((19 ÷ 37)ᵏ × (18 ÷ 37)), the average spacing between the starts of losing runs of at least k. A dozen or column misses five times in a row 14.1% of the time and ten times 1.98%.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Eight losses in a row is the number that matters to anyone doubling up, because it is where a martingale started at one unit needs a 256-unit stake and 255 units already on the table. It arrives about once every 425 spins — an evening, at a live pace, or twenty minutes at the pace of a demo table. &lt;a href="https://betkyo.com/en/blog/the-martingale-priced-doubling-on-a-single-zero-wheel/" rel="noopener noreferrer"&gt;The martingale, priced&lt;/a&gt; works through what that costs; the short version is that the streak is not the risk, the table limit is.&lt;/p&gt;

&lt;p&gt;Streaks are also worth nothing as information. A run of eight reds changes the next spin’s red chance from 18 ÷ 37 to 18 ÷ 37. The reason streaks feel meaningful is that a 0.48% event is rare enough to remember and common enough to see, and memory keeps the streaks and discards the thousands of unremarkable spins between them.&lt;/p&gt;

&lt;h2&gt;
  
  
  The same price, different swings
&lt;/h2&gt;

&lt;p&gt;Because tiles × multiplier equals 36 for every kind of bet, every bet on this wheel returns 97.30% and costs 2.7 units per 100 units staked. What differs, and differs enormously, is the swing — how far a session of a given length can end from that expected loss.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Every bet kind, priced and measured for swing&lt;/em&gt;&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;BET&lt;/th&gt;
&lt;th&gt;POCKETS&lt;/th&gt;
&lt;th&gt;WIN CHANCE&lt;/th&gt;
&lt;th&gt;PAYS&lt;/th&gt;
&lt;th&gt;RETURN&lt;/th&gt;
&lt;th&gt;SWING PER SPIN&lt;/th&gt;
&lt;th&gt;SWING OVER 100 SPINS&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Straight&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;2.70%&lt;/td&gt;
&lt;td&gt;×36&lt;/td&gt;
&lt;td&gt;97.30%&lt;/td&gt;
&lt;td&gt;5.84&lt;/td&gt;
&lt;td&gt;58&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Split&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;5.41%&lt;/td&gt;
&lt;td&gt;×18&lt;/td&gt;
&lt;td&gt;97.30%&lt;/td&gt;
&lt;td&gt;4.07&lt;/td&gt;
&lt;td&gt;41&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Street&lt;/td&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;8.11%&lt;/td&gt;
&lt;td&gt;×12&lt;/td&gt;
&lt;td&gt;97.30%&lt;/td&gt;
&lt;td&gt;3.28&lt;/td&gt;
&lt;td&gt;33&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Corner / first four&lt;/td&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;10.81%&lt;/td&gt;
&lt;td&gt;×9&lt;/td&gt;
&lt;td&gt;97.30%&lt;/td&gt;
&lt;td&gt;2.79&lt;/td&gt;
&lt;td&gt;28&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Six line&lt;/td&gt;
&lt;td&gt;6&lt;/td&gt;
&lt;td&gt;16.22%&lt;/td&gt;
&lt;td&gt;×6&lt;/td&gt;
&lt;td&gt;97.30%&lt;/td&gt;
&lt;td&gt;2.21&lt;/td&gt;
&lt;td&gt;22&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Dozen / column&lt;/td&gt;
&lt;td&gt;12&lt;/td&gt;
&lt;td&gt;32.43%&lt;/td&gt;
&lt;td&gt;×3&lt;/td&gt;
&lt;td&gt;97.30%&lt;/td&gt;
&lt;td&gt;1.40&lt;/td&gt;
&lt;td&gt;14&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Red, black, odd, even, low, high&lt;/td&gt;
&lt;td&gt;18&lt;/td&gt;
&lt;td&gt;48.65%&lt;/td&gt;
&lt;td&gt;×2&lt;/td&gt;
&lt;td&gt;97.30%&lt;/td&gt;
&lt;td&gt;1.00&lt;/td&gt;
&lt;td&gt;10&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;em&gt;Swing per spin is the standard deviation of one spin’s result per unit staked, √(payout² × chance − 0.973²); over N spins it grows as √N. Expected loss over 100 one-unit spins is 2.7 units on every row.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Read the last two columns together. A hundred one-unit spins on red lose 2.7 units on average with a standard deviation of 10, so ending anywhere between about 20 down and 15 up is unremarkable and the expected loss is a quarter of the noise. The same hundred spins on a single number lose the same 2.7 units on average with a standard deviation of 58: the typical outcome is either a loss of most of the hundred or one or two 36-unit hits that leave the session well ahead. The price is identical; the experience is not. &lt;a href="https://betkyo.com/en/blog/risk-of-ruin/" rel="noopener noreferrer"&gt;Risk of ruin&lt;/a&gt; turns this into how long a given bankroll lasts on each bet.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Roulette here is a solo table with no server clock — you spin when you press Spin — so “per hour” depends entirely on the player. At a spin every ten seconds, 100 spins is under twenty minutes; the table above is the honest unit.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Checking a spin yourself
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Before you play, the fairness panel shows the SHA-256 fingerprint of the server seed. Rotate your seed pair afterwards to reveal the seed and confirm the fingerprint.&lt;/li&gt;
&lt;li&gt;Compute HMAC-SHA256 with the server seed as the key and “clientSeed-nonce-0” as the message; a spin uses cursor 0 only.&lt;/li&gt;
&lt;li&gt;Take the first eight bytes of the digest as hi ÷ 2³² + lo ÷ 2⁶⁴ to get u, then floor(u × 37). That is the pocket, and every bet on the table settles from it.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The open-source verifier does the three steps in one command, &lt;code&gt;betkyo-verify roulette &amp;lt;serverSeed&amp;gt; &amp;lt;clientSeed&amp;gt; &amp;lt;nonce&amp;gt;&lt;/code&gt;, and prints the pocket. If it matches the spin you were paid on, the pocket was fixed before you placed a chip — which, as &lt;a href="https://betkyo.com/en/blog/what-a-hash-commitment-proves/" rel="noopener noreferrer"&gt;what a hash commitment proves&lt;/a&gt; explains, is what the commitment guarantees and all it guarantees. The 1-in-37 is guaranteed by the published derivation, not by the hash.&lt;/p&gt;

&lt;h2&gt;
  
  
  FAQ
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;What are the odds of hitting a single number in roulette?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;1 in 37 per spin on this single-zero wheel, 2.70%. The number lands at least once in 37 spins 63.7% of the time and in 100 spins 93.5% of the time; the median wait is 26 spins and the mean is 37.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How many spins does it take for a number to come up?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;On average 37, but half of all waits are 26 spins or fewer and a few are very long: no hit in 100 spins happens 6.5% of the time, no hit in 200 spins 0.4%.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What are the odds of red coming up 10 times in a row?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;(18 ÷ 37)¹⁰ = 0.074%, about 1 in 1,350. A losing run of ten on an even-money bet, which includes zero, is 0.128%, about 1 in 780. Neither changes the next spin, which is 18 ÷ 37 red regardless.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How often does zero come up in roulette?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Once in 37 spins on average. Zero appears at least once in 37 spins 63.7% of the time and in 74 spins 86.8%; it is absent from a full 37-spin cycle more than a third of the time.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Is a straight-up bet worse than red?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Not in price: both return 97.30% on this wheel. A straight-up bet is far more volatile — a standard deviation of 5.84 stakes a spin against 1.00 for red — so it produces long dry runs and occasional ×36 wins rather than a steady drift.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Can I verify a roulette spin?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Yes. HMAC-SHA256 of “clientSeed-nonce-0” keyed by the revealed server seed, first eight bytes as a fraction of 2⁶⁴, times 37 and floored, gives the pocket; the verifier’s roulette command does it in one step.&lt;/p&gt;

&lt;h2&gt;
  
  
  Sources
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Betkyo engine source: deriveRouletteSpin(), rouletteNumbersOf() and rouletteMultOf() in roulette/derive.ts (pocket = floor(u × 37) at cursor 0; integer total-return multipliers ×36 … ×2); demoRouletteSpin() in _shared/demoLocal.ts; RouletteEngine.derivePocket() and settle() in the house service (U64SeedStream intBelow(37); stake × multiplier per covering key)&lt;/li&gt;
&lt;li&gt;Exact calculations written for this article: (36 ÷ 37)ᴺ waiting times and the binomial counts for 37 spins, (18 ÷ 37)ᵏ and (19 ÷ 37)ᵏ run probabilities and their mean spacing, per-spin standard deviation for every bet kind and its √N growth&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/betkyo-open-labs/provably-fair-verifier" rel="noopener noreferrer"&gt;Betkyo provably-fair verifier (GitHub, MIT): the roulette command reproduces the pocket from serverSeed, clientSeed and nonce&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>math</category>
      <category>probability</category>
      <category>statistics</category>
    </item>
  </channel>
</rss>
