【JavaScript超入門番外編】乱数の活用方法3例【プログラミング初心者向け】
どうも!LSSです!!
今回は、「乱数の活用方法」について。
記事タイトルに「プログラミング初心者向け」と書きましたが、乱数を扱ったプログラムを書いた事のある方には「言われんでも分かってるわい!」と言われそうな内容となっておりますw
「乱数を返す関数があるのは分かったけど、それを利用するのにどう手を加えたらいいの?」と考えている方向けの記事となります。
なお、JavaScriptの場合について書いていますが、考え方自体は他のプログラム言語にも応用できます!
今回使用する2つの関数について
2つの関数を使用します。
使い方の前にさらっと、その2つの関数の特性についておさらい。
Math.random()
これがないと始まらない、「乱数を返す関数」です。
この関数は「0以上1未満の小数」を結果として返しますが、その範囲内のどんな数値が返ってくるかは「運任せ」となります。
※0以上、という事で0は含みますが、1未満というのは1を含みません。
最大で0.999999…という事になります。
サンプルコード
<script>
document.write(Math.random());
</script>
サンプルコード実行例
Math.floor(引数)
「引数(ひきすう)」として与えた数値以下の、最大の整数を返します。
例えば Math.floor(2.3) なら 2 、Math.floor(5) なら 5 、 Math.floor(0.7) なら 0 という値になります。
なお、引数が負の数だった場合…例えば Math.floor(-7.5) なら -8 、 Math.floor(-3) なら -3 という値が返ってくる事になります。
サンプルコード
<script>
document.write(Math.floor(2.3));
</script>
サンプルコード実行例
以上を踏まえ、乱数を扱いやすく加工する方法を書いていきます!
1~6のいずれかの整数をランダムに返す
つまり「サイコロ」の作り方ですね。
Math.random()が返すのは1未満の小数ですが、そこから「1か2か3か4か5か6」というハッキリした数(整数)を返すようにするには?
サンプルコード
<script>
document.write(1+Math.floor(Math.random()*6));
</script>
サンプルコード実行例
説明
いくつかのカッコが組み合わさっていますが、その一番内側から見ていきます。
Math.random()*6
6種類の結果が欲しいので、Math.random()に6を掛けています。
すると、この部分の数値は「0~5.999999…」の範囲内の、いずれかの数値、という事になります。(この時点では小数のある数値なので膨大なパターンの結果になりえます)
そしてそれを、
Math.floor(Math.random()*6)
…と、Math.floor関数の引数として与える事で、「0か1か2か3か4か5」のどれか、という数値になります。
結果として欲しいのは「1~6」なので、
1+Math.floor(Math.random()*6)
と、単純に1を足すだけで、「1か2か3か4か5か6」のどれかをランダムで返す「サイコロ」になります^^
12%の確率で「当たり」
当たりかハズレ、の くじ を作る場合。
何%で当たるのかを指定する方法です。
サンプルコード
<script>
document.write(Math.floor(Math.random()+0.12));
</script>
サンプルコード実行例(0はハズレ、1は当たり)
説明
設定したい確率を、小数として Math.random() に足します。
今回の例は12%なので、0.12を足しています。
また内側のカッコの内容から見ていきます。
Math.random()+0.12
Math.random()は「0~0.999999…」の範囲でしたが、それに0.12を足した物は、「0.12~1.119999999…」の範囲から、ランダムで数値が返ってくる事になります。
その範囲内で「1以上」の部分は12%、「1未満」の部分は残り88%、と範囲の大きさが分かれる事になります。
そしてそれをまた、
Math.floor(Math.random()+0.12)
Math.floorの引数にする事で、「1以上」は1、「1未満」は0、と分かれる事になりますが、その場合の「1以上」になる確率は前述の通り「足した小数に準ずる」事になります。
ソシャゲのガチャで超レアを引くように…例えば「1万分の1の確率」なんて鬼のような設定にするなら、
Math.floor(Math.random()+0.0001)
とすると「1万回に1回の割合で1になり、それ以外は0」という確率を設定できます^^
0~99の整数を返すが小さい方が出やすいように偏らせる
これはちょっと変わった使い方になります。
0~99の100種類の整数、全て出てくる可能性はあるものの、小さい数字ほど出やすく、大きい数字は出にくい、という「わざと乱数を偏らせる」使い方。
サンプルコード
<script>
document.write(Math.floor(Math.random()*Math.random()*100));
</script>
サンプルコード実行例
説明
最初の「サイコロ」の時と同じように、乱数に100を掛けてMath.floorする事で100通りの結果を得ようとしています。
が、
Math.random()*Math.random()*100
と、Math.randomを2回、掛けています。
「0~0.9999999…」の範囲内からランダムに選ばれる数値に、同じくランダムに選ばれる数値を掛けるとどうなるか?
その結果の範囲は、やはり「0~0.9999999…」となり、最小値は0、最大でも1に満たない数という点は変わりません。
が、例えばその結果の数値が「0.3」と「0.4」だった場合。
Math.randomが1つなら、0.3*100なら30、0.4*100なら40、という大きさの数値になるところですが、2回掛けた事によって「0.3*0.4」は「0.12」とより小さい数になるために「0.3*0.4*100」は「12」とだいぶ小さい数になってしまいます。
二つのMath.randomがお互いに足を引っ張り合うイメージですねw
それでも「0.999*0.999」あたりで「0.998001」といった数値になるので、*100してMath.floorする事で最大の「99」がでる可能性はありますが、かなり確率が低くなります。
あとがき
特にゲームプログラムを作る時にはほぼ必須となる「乱数」
「0以上1未満」の値を返すところから、実用的に使用するための加工について3つの例を挙げてみました。
「サイコロ」の例では「分けたいパターン数を掛けてMath.floorでグループ化する」、「くじ」の例では「意図した通りの当選確率を実現する」、「偏らせる」は可能性を持ちながらも敢えて出やすいもの・出にくいものを仕込む方法の例となります。
もちろん、アイデア次第で他にも様々な計算式にかける事で、面白い乱数の使い方ができると思います^^
ってなとこで、今回はこのへんで!
次回もまた、よろしくお願いします^^