ロゴ

コインを投げたり、サイコロを振る動作をさせるには「ランダム関数random()」 を使います。 

下のJavaScriptのプログラム例は「コインを5回投げたあとに、次の結果が裏か表かを予想してください」というものです。

裏になるか表になるかの確率は1/2なのですが、その出現の様子は想像がつかないことを感じてもらうためにこれを作りました。 

さて、『次は裏でしょうか表でしょうか?』 これは製作途中のプログラムですが、裏か表を予想してみてください。意外と当たりませんよ。

****************ボタンを押して始めます

 5枚の次が「表か裏か」を予想してください。

 表?裏?


あなたの予想はどちら  おもて   うら   

あなたの予想はあたりましたか?

もう一度挑戦する場合は、「F5」を押してページの再読込をしてください。 

ランダムといってもなにか傾向が感じられる?

「表か裏」の確率は1/2です。 

でも、上のゲームを何回かやってみても、裏と表が半々で出現していませんから、ゲームの面白さが出てきます。

for (let i = 1 ; i <=5 ; i++) {  //④それを5回繰り返す
document.getElementById('myCoin').addEventListener('click', myToss);  //①クリックすると
let myAns = document.getElementById('myHajime');
function myToss() {   //②1(表)か2(うら)かを決め、
let myKekka = Math.floor(Math.random() * 2 + 1);
myAns.insertAdjacentHTML('beforebegin', '<img src="img/k0' + myKekka + '.jpg">');
}  //③画像を左に表示して
}
//⑤予想をボタンで決めて6枚目のコインを投げる
document.getElementById('myCoin2').addEventListener('click', myComp);
//⑥ここでは結果を表示するだけで、特に何もしない
function myComp() {
let myCkekka = Math.floor(Math.random() * 2 + 1);
if (myCkekka == 1) {
document.getElementById('myKek2').innerHTML = '結果は「表」です <img src="img/k01.jpg">';
} else {
document.getElementById('myKek2').innerHTML = '結果は「うら」です <img src="img/k02.jpg">';
}
document.getElementById('myOpn').remove();
document.getElementById('myCoin2').remove();
}

このプログラムは作りかけのものですので、結果を表示するだけで終わっていますが、結果を評価して点数をつけたりするとゲームらしくなるでしょう。

5回コインを投げると1/2の確率で裏表が出現していないし、その出方もかなり不規則なので、6枚目を予想するだけでも難しいのです。

つまり、それが「賭け」の面白さですが、「コンピュータ乱数」を使っているので、裏か表の確率は1/2です。 しかしこのように、出現はデタラメですし、さらに、このゲームのように6回目を当てるのはさらに予想しにくくなるというところが面白いところです。つまりそれが「ランダム」ということなのでしょう。

ちなみに私が上のゲームを10回やってみたところ、6問正解でした。皆さんはどうですか。

サイコロの目の出方もやってみると1/6になっていない

サイコロを振って1の目が出る確率は1/6(約17%ずつ)です。 

しかし、下のプログラム(→こちらに関連記事があります)は、サイコロを100回振ってそれぞれの目の出た回数を集計させ、それを5回やった結果を手集計したものが下のグラフですが、やはり、サイコロの目は等分に出現していません。

<p><button onclick="myAns();">Push</button></p>
<script>
function myAns() {
let one=0,two=0,three=0,four=0,five=0,six=0;
for (let i=1; i<=100; i++) {    //①100回繰り返す
let sai2 =Math.floor(Math.random()*6+1);

switch (sai2) {    //②出た目ごとに集計する
case 1:
one = one+1;
break;
case 2:
two= two+1;
break;
case 3:
three= three+1;
break;
case 4:
four= four+1;
break;
case 5:
five =five+1;
break;
case 6:
six= six+1;
break;
}
}

  //③別窓に表示する
alert('1は'+one+'個 2は'+two+'個 3は'+three+'個 4は'+four+'個 5は'+five+'個 6は'+six+ '個です。') ;
}
</script>

サイコロを振った目の出方の例

目の出方は平均の17回(100回の1/6)ずつでなく、かなりばらついています。延々とやり続けると1/6になるはずですが、少ない試行回数では結構偏っています。これが「ランダム」ということでしょう。 

これによって「賭けをする」価値がでてくるということですが、この出現の様子を見ると、何かしらの「波やリズム」があるようで、それを読んで賭けるのが「勝負師」ということになるのでしょうか。 

これはサイコロを100回振った場合ですが、たくさんの回数でサイコロを振った場合も簡単に試すことができます。 100回繰り返す「for文」の100を1000などに変えるだけです。

100万回振らせてみたら均等になってくる

下は、100,1000,10000,100000,1000000回を3回振らせて平均の%を表示しています。

コンピュータの計算能力はすごいもので、100万回の計算を繰り返しさせても、一瞬で完結するので、ぜひ自分でプログラムを自分のコンピュータで動かしてみてください。

100万回サイコロを振って見ると

この数字をみると、100回ではかなり出現する数がばらついていますが、10000回程度以上を振ると、出現のばらつきは0.5%以内と均等化しているようです。 

実際にサイコロを10000回振るのは大変なことですが、このように、長くゲームをやり続けると、目の出現のしかたは平均化してきます。 しかしそれでも、出現のタイミングや傾向は予想できないので、やはりゲームに勝つには「運と勘」などの要素も必要になるということでしょうか。

 

乱数の小数以下は切り捨て処理をするのが正解

私の経験した失敗例です。 ちょっとした計算のさせ方を間違えると変な答えが出ましたという例です。

random()関数は、0~1の乱数を作ってくれます。 コインの裏表をシミュレートするには1と2(または0と1でもOK)があればいいですし、サイコロの目では1~6の数字があればいいので、たとえばサイコロであれば、「0から1のコンピュータが作る乱数を6倍して1を加えた後に小数以下を切り捨てる」という方法をおぼえておけば、いろいろなところで使えます。

Math.floor(Math.random()*6+1);  がランダムな1~6を出すやり方です。 

この「floor」が少数以下の切り捨てをする関数です。 それを間違って「切り上げや四捨五入」をしてしまうと不具合が起きてしまいますから注意しましょう。

例えば、上のプログラム部分の切り捨て関数「floor」を四捨五入の「round」に変えてみると、答えの合計が100になリません。(ここでは示しませんが、上のコードでやってみてください)

理由は、毎回の計算結果で、1から6ではなく、1から7の答えになって、切り上げられて「7」になった個数が集計から抜けてしまうためですが、たしかに、関数のレファレンスを読むと理屈や注意事項が書いてあります。 

しかし、読むだけではわかりにくいので、経験してみて初めて納得できます。

このように、趣味で楽しむJavaScriptであれば、ともかくやってみてうまくいまで試行錯誤することはしかたがないでしょうね。

PR

JavaScriptは馴染むしか方法がないのか

JavaScriptの本を読み始めて、3ヶ月後くらいは自分でコードが書けなかったのですが、それでも、時間をかければ、このHPの記事程度のことは徐々にできるようになります。しかし、趣味でやり始めた程度ですので、JavaScriptのわかりにくさや馴染にくさはなくなりません。

上の「5枚のコインを投げる」ときにどうすればいいのかということは試行錯誤をしてたどり着いたのですが、他のページでも紹介しているように、ヒントを得るには、この本が一番役に立っています。 これからJavaScriptを始めようとしている方にはおすすめです。

JavaScriptワークブック: ステップ30 (情報演習 36)

新品価格
¥990から
(2024/7/1 14:41時点)

この本をヒントに、「.insertAdjacentHTML('beforebegin', '<img src="img/k0' + myKekka + '.jpg">');」 を使って、もとの画像の前に順に画像を表示するという方法に行き着きました。

それにたどり着くまでには、たとえば、5つの裏表の結果をプールしておいて一斉に表示したり、1枚ずつ投げては予想するという方法などもやりました。

このように「考えたものをプログラムしていく」というのは時間がかかるうえに、Javascriptの独特の書式に馴染むのも大変です。

英字圏で開発されたものなので、日本人にはわかりにくいものになっているように思うのですが、WEBではこのJavaScriptを使ってものすごい仕組みが作られているのですから、私のような初心者にもわかりやすいものにしてくれと言っても、受け入れられることはなさそうなので、独学では、気ままに気楽にやっていくしか方法はないのでしょう。

********

→こちらに 「.write」「.writeIn」を使わないように代替えして書き直した記事を書いています。 入門者には便利な命令語なのですが、今では使うと問題を起こすために「非推奨」となっています(→それはこちらで紹介)が、何がいけないのかを調べてみました。参考に。


記事の目次へ

PR

(来歴)R6.7作成  R6.8月確認   
PR
AmazonのJavascript本 送料無料

楽天ブックスは品揃え200万点以上!


記事の目次はこちらから

電子工作の記事の目次へ