透明性

このルーレットは本当にランダム?

はい。結果はアニメーションが始まる前に、ブラウザの暗号論的乱数で決まっています。サーバーが結果を操作することはなく、自分で確率を設定しない限り、どの項目も当たる確率は同じです。

実際に動いているコード
const MAX = 2 ** 32

function randomInt(n) {
  // 割り切れない端数を捨て、n 通りすべてを完全に同じ確率にする
  const limit = MAX - (MAX % n)
  let value
  do {
    value = crypto.getRandomValues(new Uint32Array(1))[0]
  } while (value >= limit)
  // これで剰余に偏りがなくなる
  return value % n
}

当サイト共通の乱数モジュールにある randomInt 関数です。ブラウザの開発者ツールの「ソース」パネルで全文を確認できます。

試してみよう:10,000 回シミュレーション

同じ大きさの項目が 8 個。公平なルーレットなら各項目に約 1,250 回ずつ当たり、自然な小さなぶれが出ます。

回数
項目数
確率

点線:完全に公平なルーレットでの、その項目の期待回数

期待値からの最大のずれ–
カイ二乗値(自由度 7)–14.07 未満なら有意水準 5% で合格
判定–

均等モードでは、左に載せた randomInt 関数を1回ごとに呼び出しています。すべてブラウザ内で動きます。 カイ二乗検定は、各棒が期待値からどれだけ離れているかを合計したものです。公平な乱数でも約20回に1回は 5% の基準を超えるので、1回の不合格は想定内。毎回不合格になるなら問題があるということです。

  • プレゼント企画や配信の抽選当選者がどう選ばれるかを事前に見せれば、「出来レースでは」という疑いを減らせます。
  • 授業での指名先生にも結果を操作できないと分かれば、指名された生徒も納得しやすくなります。
  • グループでの決めごとランチ、掃除当番、誰がおごるか。「仕込みでしょ」と言われたらこのページを見せてください。
  • 確率設定の確認30% の項目が長い目で見て10回に3回ほど当たる理由と、短期ではぶれる理由が分かります。
使い方

「回す」を押したときに起きていること

  1. 「回す」を押す

    ページがブラウザの crypto.getRandomValues に新しい 32 ビットの乱数を要求します。OS の安全な乱数源から作られる値です。

  2. 止まる位置がその場で決まる

    乱数で何周回るかと最終的な角度が決まります。この時点で結果は確定済み。止まったときに針の下にある項目が当選です。

  3. それからアニメーション

    回転、減速、カチカチ音は演出だけ。長く見ても、速い端末で回しても、決まっている停止角度は変わりません。

  4. データは端末の外に出ない

    抽選はブラウザ内で行われ、結果を決めるためにリストがサーバーへ送られることはありません。裏で操作するスイッチは存在しません。

選ばれる理由

公平さを支える6つの仕組み

暗号論的乱数crypto.getRandomValues は暗号鍵の生成にも使われる乱数源。予測可能な Math.random ではありません。
剰余の偏りなし棄却サンプリングで小さい数が出やすくなる値を捨てるので、n 通りがぴったり n 分の1になります。
Fisher–Yates シャッフルリストの並べ替え、チーム分け、順番決めは Fisher–Yates 法。どの並び順も同じ確率です。
演出の前に決定押した瞬間に停止角度が決まります。速度の設定は見ている時間が変わるだけです。
サーバーは関与しない結果は手元の端末で計算。アカウントも、隠れた順番待ちも、遠隔操作もありません。
重みは自分で設定したときだけ確率を設定すると項目の大きさが変わり、見た目の面積がそのまま実際の確率になります。

単純な剰余が少しだけ不公平な理由と、棄却サンプリングによる解決

乱数生成器は決まった範囲の整数を返します。ブラウザが返すのは 32 ビット整数で、4,294,967,296 通り。n 個の中から1つ選ぶ一番簡単な方法は value % n、つまり n で割った余りを使うことです。ただし 2 の 32 乗が n で割り切れない限り、いくつかの余りだけが1回ぶん多く出てしまいます。

0 から 7 までしか出ない小さな生成器で、3つの中から選ぶ例を見ると分かりやすいでしょう。

方式項目 1項目 2項目 3
単純な剰余、値は 0 から 70、3、6:8分の31、4、7:8分の32、5:8分の2だけ
棄却サンプリング、6 と 7 は捨てて引き直す0、3:6分の21、4:6分の22、5:6分の2

当サイトの randomInt は、2 の 32 乗から余りを引いた limit を計算し、limit 以上の値が出たら捨てて引き直します。32 ビットならもともとの偏りはごくわずかで、1クラス分の名簿なら1億分の1未満、引き直しもほぼ起きませんが、結果は「ほぼ正確」ではなく「完全に正確」になります。

ルーレットは乱数をどうやって当選結果にしているか

ルーレットは、こっそり番号を選んでから回っているふりをしているわけではありません。実際の停止角度を乱数で決めています。5〜8周の間のランダムな回転数と、ランダムな最終角度。どちらも crypto.getRandomValues から得た値です。各項目は円の一部を占めているので、針の下で止まる確率は、その項目が 360 度に占める割合とぴったり一致します。誤差はおよそ 40 億分の 1 です。

項目に確率をパーセントで設定すると、その割合で円が描き直されます。合計が 100 にならないと回せません。50% の項目は円の半分を占め、長い目で見ると約半分の回で当たります。ルーレットを使わずリストから選ぶツールは weightedIndex を使い、重みの合計の上にランダムな点を取って、どの項目の範囲に入るかで決めます。

  • 回す前にルーレットがどの位置で止まっていても関係ありません。最終角度は出発点に関係なく一様に分布します。
  • 回転速度や時間はアニメーションを長くするだけ。停止角度は最初のフレームより前に決まっています。
  • 当選者を外すとルーレットが描き直され、残った項目で円を分け合います。

連続当選は普通のこと:本物のランダムの姿

抽選ルーレットへの一番多い不満は「また同じ人?」というもの。公平な乱数には記憶がないので、連続は起こりうるどころか、起きて当然です。次の回が前回と同じ結果になる確率は、単純に 1 を項目数で割った値です。

ルーレットの項目数2回連続で同じ結果20回回して1度でも連続が出る確率
250%ほぼ確実
425%約 99.6%
812.5%約 92%
128.3%約 81%
303.3%約 47.5%

全員に一度ずつ順番が回ってから重複させたいなら、それは「より公平な抽選」ではなく「非復元抽出」です。名前ルーレットの「外してもう一度回す」を使うか、リストシャッフルで名簿を一度に並べ替えましょう。

Math.random を使っている場所と、結果に影響しない理由

Math.random は演出には十分なので、いくつかのアニメーションで使っています。サイコロのわずかな傾き、マーブルレースの揺れ、数字が決まる前のパラパラ表示などです。どの場合も結果そのものは暗号論的乱数ですでに決まっており、演出は見た目の順位が変わらない程度に抑えています。

共通の乱数モジュールが Math.random に切り替わるのは、ブラウザが Web Crypto をまったく持っていない場合だけで、今ではかなり古いブラウザに限られます。現在の Chrome、Safari、Firefox、Edge、LINE のアプリ内ブラウザはいずれも crypto.getRandomValues に対応しています。

よくある質問

よくある質問

抽選ルーレットは本当にランダムですか?

当サイトのルーレットはランダムです。毎回ブラウザの暗号論的に安全な乱数 crypto.getRandomValues を使い、アニメーションの前に止まる位置を決めています。各項目の当選確率は面積に比例し、同じ大きさの項目は同じ確率です。

サイト運営者や回す人がイカサマできますか?

抽選はブラウザ内で行われるため、当サイトのサーバーが結果を決めたり変えたりすることはありません。回す人も操作できません。押すタイミングや長押しは、ランダムな停止角度に影響しません。コードはブラウザの開発者ツールでいつでも確認できます。

同じ名前が2回連続で当たったのはなぜ?

乱数には記憶がないからです。8 項目なら同じ項目が2回続く確率は 12.5%、20回回せば一度は連続が起きる確率が約 92% あります。重複させたくない場合は、当選した項目を毎回外してください。

長く回したり速く回したりすると確率は変わりますか?

変わりません。停止角度は「回す」を押した瞬間に決まります。時間、速度、減速のかかり方は見た目が変わるだけで、止まる場所は変わりません。

ルーレットの確率設定はどう動いていますか?

項目にパーセントを入れると、その割合ぶん円を占めるように描かれます。合計は 100 にする必要があります。30% の項目は長い目で見ると10回に3回ほど当たりますが、短期的にはそれより多くも少なくもなります。

シミュレーターのカイ二乗値と判定はどういう意味ですか?

各項目の実際の回数と期待回数の差を二乗し、期待回数で割って合計したものがカイ二乗値です。その項目数に対応する 5% の基準値を下回れば、公平な乱数と矛盾しない結果です。公平でも約20回に1回は不合格になるので、何度か試してから判断してください。

当選者を Math.random で決めていますか?

いいえ。Math.random はサイコロの傾きやマーブルの揺れなど、結果が出た後の演出にだけ使っています。結果は crypto.getRandomValues から得ており、Web Crypto に対応していない非常に古いブラウザでのみ Math.random に切り替わります。