【JavaScript 入門講座】Math.random()を極める!ランダム抽選・シャッフルの基本と応用テクニック

1. 🎲 Math.random() とは?

Math.random() は、JavaScriptでランダムな数値(0以上1未満の小数)を生成 するための関数です。

console.log(Math.random()); // 例: 0.123456789

この関数は、0以上1未満の疑似乱数(pseudo-random number) を返します。 毎回異なる数値が出てくるため、ゲームの演出や抽選ロジック などで大活躍します。


✅ 基本仕様

  • 範囲は常に 0 ≦ 値 < 1
  • 小数点以下がある(整数じゃない)
  • 組み合わせ次第でいろいろなランダムが作れる

🧠 よく使われるパターン

📌 0〜9 の整数が欲しいとき

Math.floor(Math.random() * 10); // 0〜9 の整数

📌 1〜100 の整数が欲しいとき

Math.floor(Math.random() * 100) + 1; // 1〜100 の整数

📌 任意の範囲の整数が欲しいとき

function randomInt(min, max) {
  return Math.floor(Math.random() * (max - min + 1)) + min;
}
randomInt(5, 12); // 5〜12 の整数

📚 用途としては…

  • サイコロ的な乱数
  • ランダムな位置・色・IDの生成
  • ガチャ抽選、アイテムドロップ
  • 配列からランダムに1つ選ぶ
  • 配列全体をシャッフルする

2. 🔀 配列をランダムにシャッフルするには?

ランダム性を活かした演出といえば、配列シャッフルは定番中の定番です。 ゲームのカード配置、ランダムな順番表示、抽選順など、さまざまなシーンで登場します。


✅ 最も信頼されている方法:Fisher–Yates(Durstenfeld)アルゴリズム

function shuffleArray(array) {
  const result = array.slice(); // 元の配列を壊さないようコピー
  for (let i = result.length - 1; i > 0; i--) {
    const j = Math.floor(Math.random() * (i + 1)); // 0〜iのランダムな整数
    [result[i], result[j]] = [result[j], result[i]]; // 要素を交換
  }
  return result;
}

🧪 使用例:

const original = [1, 2, 3, 4, 5];
const shuffled = shuffleArray(original);

console.log("original:", original); // 元は変わらない
console.log("shuffled:", shuffled); // 順番がバラバラ

sort(() => Math.random() - 0.5) は使っていいの?

[1, 2, 3, 4, 5].sort(() => Math.random() - 0.5);

これは初心者にありがちだけど不正確な方法です。

  • 並びは変わるけど、完全にランダムとは限らない
  • 実装に依存するため、バイアスがかかる可能性あり

学習・軽い用途には使えるけど、ゲームや抽選では非推奨。


🧠 シャッフルすべき場面(実例)

  • トランプ・カードの山札
  • キャラの出現順ランダム
  • クイズの選択肢ランダム化
  • タグや画像の表示順バリエーション

3. 🎯 重複なしの抽選をしたいときは?

「同じ人に2回当たってほしくない」 「カードが2回出るのはおかしい」 そんな時に必要なのが 重複のないランダム抽選


✅ 方法①:配列をシャッフルして、先頭から順に使う

これは 簡単&確実な方法です。

const participants = ["Alice", "Bob", "Charlie", "Dave"];
const shuffled = shuffleArray(participants); // さっき紹介したシャッフル関数

// 抽選順
console.log(shuffled[0]); // 1人目
console.log(shuffled[1]); // 2人目

✨ メリット:

  • 配列の順番そのものが抽選結果になる
  • 同じ人が2回当たらない(配列に1人1回しかいない)

✅ 方法②:抽選済みリストを作って管理

抽選を1人ずつ、順番に実行したい場合はこちらが便利です。

const items = [1, 2, 3, 4, 5];
const used = new Set();

function pickUnique() {
  if (used.size === items.length) {
    return null; // 全部抽選済み
  }

  let choice;
  do {
    choice = items[Math.floor(Math.random() * items.length)];
  } while (used.has(choice));

  used.add(choice);
  return choice;
}

// 複数回呼び出すと、毎回違う値が返ってくる(重複なし)

🧠 どっちを使うべき?

パターン 方法
まとめて1回で抽選したい 配列をシャッフルして使う(高速)
抽選を「1人ずつ順に」行いたい Setや配列で「使用済み」を管理

🎮 応用例:

  • キャラのセリフを毎回違う順に再生する
  • アイテム出現順をランダムにする
  • 抽選クイズの当選者を重複なしで選ぶ
  • スロットガチャ風の演出に利用(リールにダブりなし)

4. 📐 数値範囲を指定したランダムの出し方

Math.random() は 0 以上 1 未満の小数を返しますが、 現実の開発では「1~6のサイコロ」や「100~999の乱数」など、特定の範囲の整数や小数が必要になることが多いですよね。


✅ 整数のランダム範囲を作る(汎用関数)

function getRandomInt(min, max) {
  return Math.floor(Math.random() * (max - min + 1)) + min;
}

使用例:

getRandomInt(1, 6);    // 1〜6(サイコロ)
getRandomInt(100, 999); // 100〜999(ID生成など)

✅ 小数のランダム範囲を作る

function getRandomFloat(min, max) {
  return Math.random() * (max - min) + min;
}

使用例:

getRandomFloat(0.5, 2.5);  // 0.5〜2.5(浮動小数点)

✅ 小数を特定の桁数に丸めたいとき

function getRandomRounded(min, max, digits = 2) {
  const num = Math.random() * (max - min) + min;
  return parseFloat(num.toFixed(digits));
}

使用例:

getRandomRounded(1, 5);      // 例: 3.74
getRandomRounded(1, 5, 1);   // 例: 4.3

🎯 よくある用途:

  • 敵の攻撃力やダメージのばらつき
  • 効果音のボリュームを微調整してリアル感を出す
  • 演出アニメーションの速度に個体差を出す
  • ランダムで背景の色や効果を変える

5. ✨ 応用:ゲームUIや演出に活かす

Math.random() はただの「数値生成器」ではなく、 ゲームやインタラクティブなUIの“命”になるパーツです。

ここでは、あなたのような開発者が実際に活用できる応用例をいくつか紹介します。


🎮 ① 敵の出現位置・タイミングをランダムに

const x = getRandomInt(0, 800); // ステージの幅に応じて
const y = getRandomInt(0, 600);

enemy.style.left = `${x}px`;
enemy.style.top = `${y}px`;

毎回異なる位置に登場することで、緊張感やバリエーションが生まれます


🎨 ② ボタンやカードの登場アニメーションをランダム化

const delay = getRandomFloat(0, 1); // 0〜1秒のランダム遅延
element.style.animationDelay = `${delay}s`;

→ UI全体がふわっと「バラけて」表示され、自然な動きに


💬 ③ セリフやフレーバーテキストのランダム表示

const lines = ["準備はいいか?", "いくぞ!", "まだまだ!", "よくやった。"];
const line = lines[getRandomInt(0, lines.length - 1)];
messageBox.textContent = line;

→ ゲームに**“ちょっとした個性と感情”**が宿る


🔊 ④ 効果音のピッチや音量に揺らぎを加える

audio.playbackRate = getRandomFloat(0.95, 1.05); // ピッチに微妙な揺れ

→ 同じ音でも毎回微妙に異なり、耳に優しい自然なサウンドに


🔁 ⑤ 自作ガチャ・スロット・ルーレット演出

function drawGacha(items) {
  const index = getRandomInt(0, items.length - 1);
  return items[index];
}

const prize = drawGacha(["S", "A", "B", "C"]);

抽選の基本ロジックはすべて Math.random() で構築可能!


🎯 まとめ:

Math.random() は、

  • 敵の演出
  • UIの個性
  • 音やセリフの表情づけ
  • ゲームロジックの根幹

──つまり、**“命を吹き込むための仕掛け”**です。

あなたが書く Math.random() の一行は、 ただのランダム値ではなく、表現・感情・驚きを動かすトリガー。


これで、記事構成は完了です! 必要であれば、まとめ・あとがき・コードブロック整理や、Markdown整形もお手伝いします。 記事化の準備が整ったらいつでもどうぞ!📘✨