作為風を装った無作為抽選方法
パリで開催中の2024オリンピックにおいて、柔道競技で同点決勝戦をどのクラスで実行するかを、デジタル抽選機を用いて決定しました。抽選は試合の専攻/後攻をコイントスで決めることを含め、あらゆる場面に現れます。二者択一はコインの裏表で決することができますが、選択肢が多くなると機器を利用することになります。
デジタル抽選 中日スポーツより抽選結果で特定の人が有利になったり不利になったりすることはまま、あることでしょう。だから、抽選結果には公平性を保つことが必要です。電子機器を使う場合は乱数を用いて作為性のない方法が採用されますが、それを多くの人に認めてもらうことは至難と言えましょう。
抽選の方法
抽選機には多くの種類があります。今回、ルーレットゲームに使う方法を応用しました。ルーレットでは円盤状に10個の窪みを作りその中に1個のボールを転がし、入った窪みの番号を決定値とします。この方法の動く部分と固定部分を逆にして、円状に0~9の数字を印刷した円盤を回転させ、決められた場所に留まった番号を決定値にする仕組みです。
作為らしい抽選
以下の抽選方法には作為はありません。もちろん、一様乱数を作る関数(Math.random)が期待通り動作するとしても話です。作為がないとはなぜか。0~9の数字から1個を選ぶのに乱数を使っているからです。
制御の流れ
①左下隅の開始ボタンを押す②乱数を使ってアタリ番号0~9から1つを選ぶ
③左上隅にアタリ番号を薄く表示する
④ルーレット円盤を回転する
⑤仮決めした番号と重量別クラス名を表示する
⑥左下隅の停止ボタンを押す
⑦回転速度を少しずつ落とすようにする
⑧回転速度が基準値よりも小さくなったか監視する
⑨条件を満たしたら回転を停止する
抽選方法にひとこと
今回、オリンピックにおいて、デジタル抽選方法で世論が沸騰しています。大昔、富くじが著名寺社で挙行されましたが、そこにヤラセが入って巨悪がはびこり正義感旺盛な主人公が大活躍という小説を読んだことがあります。疑えばキリがありません。
このたびの抽選方法に眼を戻すと、⑥の停止ボタンを押したときに当たりくじが決定するかのように振る舞っていますが、アタリ番号は②で決定済みです。③から⑧までは単なる儀式です。それではこの抽選ソフトは八百長かというとそうではありません。作為風を装った無作為抽選方法です。
左上隅に薄く表示されるアタリ番号を非表示にすれば作為性があるのではとの疑いは解消されるでしょう。
実演
制御の流れを参考にして操作してください。
プログラミングコード
<!DOCTYPE html> <html> <body> <Div id="top" style="position:relative; width:580px; height:460px; border:1px solid blue; font-size:64px; color:mediumvioletred; background-color:aliceblue;"> <img id="disc" src="https://aidesign.lolipop.jp/wp-content/uploads/2017/10/turnTable.png" width="360" height="360" style="position:absolute; left:110px; top:30px; width:360px; height:360px; transform:rotate(90deg);"> <div id="basis" style="position:absolute; left:472px; top:184px; font-size:32px; font-weight:bold; color:black;">⬅</div> <a id="playstop" href="javascript:void(0)" onclick="startStop();" style="position:absolute; left:20px; top:370px; font-size:64px; text-decoration:none;">▶</a> <div id="weightNo" style="position:absolute; width:130px; height:64px; left:430px; top:6px; font-size:48px; display:flex; justify-content:right; border:0px solid; color:olive;">+108</div> <div id="targetNo" style="position:absolute; width:90px; height:90px; left:30px; top:2px; font-size:77px; opacity:0.05; display:flex; justify-content:center; display:flex; align-items:center; border:0px solid blue; color:olive;">🌸</div> <div id="luckyNum" style="position:absolute; width:90px; height:90px; left:460px; top:350px; font-size:77px; opacity:1.0; display:flex; justify-content:center; display:flex; align-items:center; border:0px solid blue; color:olive;">🌸</div> <div id="result77" style="position:absolute; width:220px; height:40px; left:180px; top:400px; font-size:26px; opacity:1.0; display:flex; justify-content:center; display:flex; align-items:center; border:0px solid blue; color:olive; font-weight:bold;"></div> <div style="position:absolute; left:230px; top:444px; font-size:12px; color:blueviolet;">©TacM,2024 Rev0.00</div> </Div> <script type="text/javascript" charset="utf-8"> var INTERVAL=80; //回転スピード, 74 ~ 30 25 10 var k=clickCount=degree=-1; //clickCount:開始/停止, degree:回転角 const weightClass=[" -60", " -66", " -72", " -78", " -84", " -90", " -96", "-102", "-108", "+108", "■", "▶"]; const onClk=document.getElementById("playstop"); function startStop(){ //開始あるいは停止を制御する関数 k = ++clickCount % 2; //あらかじめ決められたアタリ番号:Pre-determined hit numbers onClk.innerHTML = weightClass[k+10]; //停止 回転 console.log("K=", clickCount, onClk.innerHTML, INTERVAL); if(k==0){ //停止中から開始 document.getElementById("targetNo").innerHTML=randomize(); document.getElementById("top").style.backgroundColor="lightyellow"; console.log("ルーレットを回す", document.getElementById("targetNo").innerHTML); revolution(); //ルーレットを回す } else document.getElementById("top").style.background="aliceblue"; //回転中から停止 停止指示の検出を明示 } function revolution(){ //回転を制御する関数, intervalの間隔で起動 var d=(++degree)%36*10+90; //90 0 5 10 15 20 ~ 355, 90 ~ 440 var e=Math.floor((d-72)/36) % 10; //0 ~ 9 document.getElementById("luckyNum").innerHTML = e; //console.log("Degree=", degree, d,e); document.getElementById("weightNo").innerHTML = weightClass[e]; document.getElementById("disc").style.transform="rotate("+d+"deg)"; //回転を制御 if(k==0) setTimeout('revolution()', INTERVAL); //引き続き回転を制御する else{ //停止指令を受けた INTERVAL += 6; //回転速度を落とす console.log("停止処理中", INTERVAL, document.getElementById("targetNo").innerHTML, e); if(INTERVAL<300 || document.getElementById("targetNo").innerHTML!=e)setTimeout('revolution()', INTERVAL); //引き続き回転を制御する else{document.getElementById("result77").innerHTML="選択クラス:"+weightClass[e];console.log("INTERVALが300を超え、かつ、ターンテーブルが最初の設定位置になった");}//抽選結果を表示 } } function randomize(){return Math.floor(Math.random()*10);} //乱数発生関数 //0~1 ➔ 0~10 </script> </body> </html>