クモのようにコツコツと

フロントエンドエンジニア イイダリョウの技術ブログ。略称「クモコツ」

【JS】Math.random()でつくるサイコロとおみくじ

JSのMathオブジェクトには数値系の組み込み関数が用意されています。その中の乱数(ランダムな数字)を返す関数Math.random()を使ってサイコロとおみくじを作ってみました。

【目次】

※参考:HTML、CSS、JSの基本はこちら
【HTML、CSS、JSの書式】これを読めばコードが読める!書ける!まとめ!(基本5+応用1記事) - クモのようにコツコツと

Mathは数値系のオブジェクト

JSにあらかじめて用意されているMathオブジェクトには数値系の組み込み関数が用意されています。(「Math」とは「数学」という意味です)

例えばMath.PIは円数率(パイ)を返します。

alert(Math.PI);

//結果
//3.141592653589793

サイコロにMath.random()で乱数を表示

Mathオブジェクトの組み込み関数Math.random()は乱数(ランダムな数字)を返します。これを使ってサイコロを作ってみます。

初期値は「1」です。ここを押してみてください。

See the Pen Saikoro-0 by イイダリョウ (@i_ryo) on CodePen.

ありゃりゃ?見ての通り、長々と少数がある数値が表示されてますね。。*1.

コードを見ていきましょう。

※参考:HTML、CSS、JSの基本はこちら
【HTML、CSS、JSの書式】これを読めばコードが読める!書ける!まとめ!(基本5+応用1記事) - クモのようにコツコツと

まずはHTMLから。

<h1>サイコロ</h1>
<div id="saikoro">1</div>

#saikoroに初期値の1を入れています。

次はCSS。

h1 {
  text-align: center;
}

#saikoro {
  margin: 0 auto;
  width: 200px;
  height: 200px;
  border: 1px solid #333;
  text-align: center;
  padding:  40px 0;
  box-sizing: border-box;
  font-size: 100px;
  border-radius: 10px;
  background: #eee;
}

#saikoro:hover {
  cursor: pointer;
  opacity: 0.7;
}

主な内容は#saikoroへのスタイルです。グレー背景の角丸ボックスの中央に文字が表示されています。

最後はJSです。

//要素取得
const saikoro = document.getElementById("saikoro");

//サイの目
function sainome(){
const nmb = Math.random();
saikoro.innerHTML = nmb; 
}

//イベント
saikoro.addEventListener("click", sainome, false);
  • 変数saikoro#saikoroの要素を取得
  • 関数sainome()の中、変数nmbMath.random()の乱数を代入
    変数saikoroの中身を変数nmbに変更(innerHTML)する
  • 変数saikoroをクリックした時に関数sainome()を実行する

Math.random()は0以上1未満(0.99999...)の間の乱数を返します。

※参考:Math.random() - JavaScript | MDN

このままではいつまでたっても1より大きい数は表示されません。さて、どうするか…。

Math.random()に6を掛ける

Math.random()の数値に掛け算をしてみましょう。例えば1の10倍は10です。乱数を1〜10までにしたい場合は10を掛ければいいということになります。

ではサイコロの1〜6にしたい場合はどうなるでしょうか。6を掛ければ実現できそうです。

やってみた。

See the Pen Saikoro-1 by イイダリョウ (@i_ryo) on CodePen.

うーむ、数字は1よりも大きくなったけど、まだ長々とした少数が続きますね。。*2

コードはこうなりました。

//要素取得
const saikoro = document.getElementById("saikoro");

//サイの目
function sainome(){
const nmb = Math.random() * 6;
saikoro.innerHTML = nmb; 
}

//イベント
saikoro.addEventListener("click", sainome, false);

変数nmbのところ、Math.random() * 66を掛けています。

さて、この少数を切り捨てたい。どうするか?

Math.floor()で小数を切り捨てる

少数の切り捨てはMath.floor()という組み込み関数が用意されています。これを使ってみる。

See the Pen Saikoro-2 by イイダリョウ (@i_ryo) on CodePen.

やた!少数が消えた!!*3

コードはこうなっています。

//要素取得
const saikoro = document.getElementById("saikoro");

//サイの目
function sainome(){
const nmb = Math.floor(Math.random()*6);
saikoro.innerHTML = nmb; 
}

//クリックイベント
saikoro.addEventListener("click", sainome, false);

変数nmbのところ、Math.floor(Math.random()*6)。乱数の式全体をMath.floor()の引数の中に入れました。これで少数が切り捨てられました!

さて、サイコロを何回か押すうちに、6が出ないことに気がつきます。そして逆に0がでちゃってますね。。

先ほどMath.random()は0以上1未満と書きました。0に幾つかけても0のままだし、1未満(0.99999...)にいくら6を掛けても6にはならないわけです。うーむ、どうすべい…。

乱数の式に1を足す

0〜5しかでないサイコロを1〜6にしたい。つまり最小値と最大値、どちらも1足りない。ということは乱数の式の最後に1を足すとよさそうです!

やってみた。

See the Pen Saikoro-3 by イイダリョウ (@i_ryo) on CodePen.

おお!今度は1〜6の数が出てきます!!

コードはこうです。

//要素取得
const saikoro = document.getElementById("saikoro");

//サイの目
function sainome(){
const nmb = Math.floor(Math.random()*6 + 1);
saikoro.innerHTML = nmb; 
}

//クリックイベント
saikoro.addEventListener("click", sainome, false);

変数nmbMath.floor()の中、Math.random()*6 + 1で6を掛けたあとに1を足しています。

これでサイコロが完成しました!転がっている感がなくてなんだか味気ないですけどね…。(今後改造できればと思います)

配列を使ってサイコロをおみくじにする。

ここから応用編です。

サイコロは乱数の値をそのまま表示しましたが、これを配列のn番目、と書くとおみくじになるのではないか。

作ってみた。

See the Pen Omikuji by イイダリョウ (@i_ryo) on CodePen.

押してみてください!

あなたの今日の運勢はなんでしたか?このおみくじは無料なので「大吉」が出るまで何度でもどうぞw

コードを見ていきましょう。まずHTML。

<h1>おみくじ</h1>
<div id="omikuji">引く</div>

id名をomikujiに変えています。ボックス内の初期値は「引く」です。

次はCSS。

h1 {
  text-align: center;
}

#omikuji {
  margin: 0 auto;
  width: 200px;
  height: 200px;
  border: 1px solid #333;
  text-align: center;
  padding:  40px 0;
  box-sizing: border-box;
  font-size: 80px;
  border-radius: 10px;
  background: #eee;
}

#omikuji:hover {
  cursor: pointer;
  opacity: 0.7;
  transition: 0.3s;
}

こちらもセレクタを#omikujiに変更。スタイルの内容はほぼ同じ。ボックス内の文字数が増えたため、文字サイズなどを調整。

最後、JSです。

//要素取得
const omikuji = document.getElementById("omikuji");

//運気
const unki = [ 
  "大吉",
  "吉",
  "中吉",
  "小吉",
  "末吉",
  "凶",
  "大凶"
]

//結果
function kekka(){
const nmb = Math.floor(Math.random() * unki.length );
omikuji.innerHTML = unki[nmb]; 
}

//イベント
omikuji.addEventListener("click", kekka, false);
  • 変数omikuji#omikujiを取得
  • 変数unkiに配列で運気の種類をいれる
  • 関数kekka()の中、少数切り捨て Math.floor()の引数に乱数Math.random()を入れるところまでは同じ。
    乱数にunkiの配列数(length)を掛けるところが異なる。
    omikujiの中身を配列unkinmb番目に変更。
  • omikujiをクリックすると関数kekka()を実行

乱数に配列数(length)を掛けることで、例えば配列数が7個の場合0〜6になります。

そして配列のカウントは0番目から始まるため、今回は1を足す必要はないわけです!

ちょっとの改造で値を数値から文字列に変更できましたね!他にもオブジェクトや画像などいろんなものに置き換えられそうです♪

まとめ

Math.randomで超シンプルなサイコロとジャンケンを作りました。ホントにこれはもう車輪の再々々々…発明かよ!って感じですが、自分で作って体験をしたかったのでw

ユーザーの操作に対し「こうしたらこうなった」という予定調和ではないランダムな動きを返したい場合の起点になる関数かと思います。

ジャンケンなどのゲームや、クスッと笑えるジョークコンテンツ、ランダムな動きのアニメなど、いろいろな場面に使えるかと思います。それではまた!!


※参考:ネイティブJSやってみたシリーズ
qiita.com

*1:スマホだと幅が増えすぎて見切れるようです。別タブで開いてみてください

*2:スマホで画面が見切れる場合はまた別タブで開いてみてください

*3:ようやくスマホでも画面が見切れなくなった!