メインコンテンツへスキップ

抽選の仕組み

「完全ランダムだから信じて」ではありません。仕組みを公開しています。

当選者はホイールが動く前に決定されます

すべてのスピンにおいて、まず当選者を決定してからアニメーションをその位置に合わせます。この順序があるからこそ、ホイールを回す強さによって結果が変わることはなく、視覚効果を減らす設定をオンにしても異なるコードパスではなくアニメーションなしで同じ抽選が行われます。また、目にするスピンはすでに下された決定の再現であることを意味します。上記の2つの約束を両立させる唯一の方法です。

乱数の生成元

乱数生成元には Math.random ではなく、お使いのブラウザの暗号ジェネレーター crypto.getRandomValues を使用しています。Math.random は予測可能であることが許容されており、一部のエンジンでは実際に予測可能です。抽選においてこれは重大な問題です。

一部の数値を破棄する理由

余り(剰余)を取って32ビット乱数を「0から11までの数値」に変換する方法には、わずかな偏りがあります。2³² は 12 で割り切れないため、先頭のいくつかの選択肢の確率が1回分多くなります。12分割のホイールではごくわずかな偏りですが実在し、常に同じ区画が有利になり、回数を重ねても均等にはなりません。そのため余りを取る代わりに、端数となる範囲に出た抽選結果を破棄して引き直しています。ごくまれに追加の抽選が発生しますが、完全に均一な結果が得られます。

const limit = Math.floor(2 ** 32 / max) * max;

let draw = crypto.getRandomValues(new Uint32Array(1))[0];
while (draw >= limit) {
  draw = crypto.getRandomValues(new Uint32Array(1))[0];
}

return draw % max;

重みと区画サイズが一致する理由

重み付き抽選では、重みの合計を算出し、同じ棄却法でその合計未満の均一な数値を抽出し、その数値がどの項目に該当するかを判定します。ホイールは各区画を円全体における正確な割合で描画します。確率が異なるのに区画が等しく見えるホイールは私たちが否定する欺瞞的なものであるため、面積と確率は設計上、完全に一致しています。

リストがブラウザ外に出ることはありません

アカウント登録もサーバー側の保存もありません。リストはこのブラウザ内に保存され、共有リンクにはURL自体の中にホイールデータが含まれます。抽選に関する情報が私たちの確認できる場所に記録されることは一切ありません。

ご自身で確認

抽選ロジックはわずか数十行で、上記のすべての仕様はテストで保護されています。仕様が満たされなくなるとテストは失敗します。これには剰余バイアスを引き起こす数値を意図的にジェネレーターに与え、結果が均一であることを確認するテストも含まれます。

ホイールには最大 1000 件の項目を登録でき、上記の方法は1項目でも 1000 項目すべてでも同じです。