Little Strange Software

スマホアプリの開発を行う LittleStrangeSoftware のブログです。

【JavaScript超入門番外編】乱数の活用方法3例【プログラミング初心者向け】

 どうも!LSSです!!

 

今回は、「乱数の活用方法」について。

記事タイトルに「プログラミング初心者向け」と書きましたが、乱数を扱ったプログラムを書いた事のある方には「言われんでも分かってるわい!」と言われそうな内容となっておりますw

 

「乱数を返す関数があるのは分かったけど、それを利用するのにどう手を加えたらいいの?」と考えている方向けの記事となります。

なお、JavaScriptの場合について書いていますが、考え方自体は他のプログラム言語にも応用できます!

 

 

f:id:little_strange:20210521235355p:plain

今回使用する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でグループ化する」、「くじ」の例では「意図した通りの当選確率を実現する」、「偏らせる」は可能性を持ちながらも敢えて出やすいもの・出にくいものを仕込む方法の例となります。

 

もちろん、アイデア次第で他にも様々な計算式にかける事で、面白い乱数の使い方ができると思います^^

 

 

 

ってなとこで、今回はこのへんで!

次回もまた、よろしくお願いします^^