【初心者向け】JavaScriptで乱数を生成する方法 - Math.randomの基礎

JavaScriptのMath.randomを使った乱数生成の基本を初心者向けに解説。整数乱数、範囲指定、実践的な活用例まで詳しく説明します。

Learning Next 運営
29 分で読めます

【初心者向け】JavaScriptで乱数を生成する方法 - Math.randomの基礎

みなさん、プログラミングでランダムな値を生成したいと思ったことはありませんか?

「サイコロの目をランダムに決めたい」 「ゲームでランダムなイベントを起こしたい」

こんなことを実現したいと思ったことはありませんか?

このような要求は、インタラクティブなWebアプリケーションを作る上で非常によくあります。 でも大丈夫です!

この記事では、JavaScriptのMath.randomを使った乱数生成について初心者向けに詳しく解説します。 基本的な使い方から実践的な活用例まで、ランダムな値を自在に扱う技術をマスターしましょう!

Math.randomって何のこと?

Math.randomの基本概念

Math.randomは、0以上1未満のランダムな小数を生成するJavaScriptの組み込み関数です。

簡単に言うと、「毎回異なる、予測できない数値を作る」機能なんです。 この基本的な機能を応用することで、様々な範囲や種類のランダム値を生成できます。

基本的な使い方

Math.randomの最もシンプルな使用例をご紹介します。

// 基本的な乱数生成
let randomValue = Math.random();
console.log(randomValue); // 例: 0.7834592837465789
// 複数回実行すると毎回異なる値
console.log(Math.random()); // 例: 0.2341567890123456
console.log(Math.random()); // 例: 0.8976543210987654
console.log(Math.random()); // 例: 0.1234567890123456

Math.random()を実行すると、毎回違う小数が生成されます。

重要なのは、生成される値は0以上1未満だということです。 つまり、0は含まれますが、1は含まれません。

値の範囲を理解しよう

Math.randomが生成する値の特徴を詳しく見てみましょう。

// Math.randomの特徴
console.log('Math.randomの値は:');
console.log('最小値: 0(含む)');
console.log('最大値: 1(含まない)');
// 実際の例
for (let i = 0; i < 5; i++) {
let value = Math.random();
console.log(`${i + 1}回目: ${value}`);
}
// 0.0 <= Math.random() < 1.0

このコードを実行すると、必ず0から1の間の小数が表示されます。

決して1.0になることはないのがポイントです。

整数の乱数を生成しよう

0または1を生成する方法

最もシンプルな整数乱数の例から始めましょう。

// 0または1をランダムに生成
function randomBinary() {
return Math.floor(Math.random() * 2);
}
// 使用例
console.log(randomBinary()); // 0 または 1
console.log(randomBinary()); // 0 または 1
console.log(randomBinary()); // 0 または 1
// コイントスのシミュレーション
function coinToss() {
return randomBinary() === 0 ? '表' : '裏';
}
console.log('コイントス結果:', coinToss());

Math.floor()を使って小数点以下を切り捨てることで、整数にします。

Math.random() * 2は0以上2未満の値を生成するので、切り捨てると0または1になります。 コイントスのように、2つの選択肢から1つを選ぶ場面でよく使われます。

1から6のサイコロを作る

サイコロの目を生成する例をご紹介します。

// 1から6の整数をランダムに生成
function rollDice() {
return Math.floor(Math.random() * 6) + 1;
}
// 使用例
console.log('サイコロの目:', rollDice()); // 1, 2, 3, 4, 5, 6 のいずれか
// 複数回振る
function rollDiceMultiple(times) {
let results = [];
for (let i = 0; i < times; i++) {
results.push(rollDice());
}
return results;
}
console.log('5回振った結果:', rollDiceMultiple(5));
// 例: [3, 1, 6, 2, 4]

Math.random() * 6で0以上6未満の値を生成します。

Math.floor()で切り捨てると0から5になるので、+ 1で1から6にします。 これで本物のサイコロと同じ結果が得られます。

指定範囲の整数乱数

任意の範囲で整数乱数を生成する汎用的な方法をご紹介します。

// min以上max以下の整数をランダムに生成
function randomInt(min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
}
// 使用例
console.log(randomInt(1, 10)); // 1から10の間
console.log(randomInt(50, 100)); // 50から100の間
console.log(randomInt(-5, 5)); // -5から5の間
// 年齢をランダムに生成
function randomAge() {
return randomInt(18, 65);
}
console.log('ランダムな年齢:', randomAge());

(max - min + 1)で範囲の幅を計算します。

例えば1から10の場合、(10 - 1 + 1) = 10となり、0から9の値に1を足して1から10になります。 この公式を覚えておくと、どんな範囲でも整数乱数を作れます。

小数の乱数を生成しよう

指定範囲の小数

小数点を含むランダムな値を生成する方法をご紹介します。

// min以上max未満の小数をランダムに生成
function randomFloat(min, max) {
return Math.random() * (max - min) + min;
}
// 使用例
console.log(randomFloat(0, 10)); // 0.0から10.0未満
console.log(randomFloat(-1, 1)); // -1.0から1.0未満
console.log(randomFloat(10.5, 20.5)); // 10.5から20.5未満
// 小数点以下の桁数を指定
function randomFloatFixed(min, max, decimals) {
let value = Math.random() * (max - min) + min;
return parseFloat(value.toFixed(decimals));
}
console.log(randomFloatFixed(0, 1, 2)); // 例: 0.73
console.log(randomFloatFixed(10, 20, 1)); // 例: 15.8

小数の場合はMath.floor()を使わずに、そのまま計算します。

toFixed()で小数点以下の桁数を指定し、parseFloat()で数値に戻します。 価格や測定値など、細かい値が必要な場面で役立ちます。

パーセンテージの生成

0%から100%のランダムな値を生成する例をご紹介します。

// 0から100のパーセンテージを生成
function randomPercentage() {
return Math.floor(Math.random() * 101); // 0から100(101は含まない)
}
// 小数点付きパーセンテージ
function randomPercentageFloat(decimals = 1) {
let value = Math.random() * 100;
return parseFloat(value.toFixed(decimals));
}
// 使用例
console.log(randomPercentage() + '%'); // 例: 73%
console.log(randomPercentageFloat(2) + '%'); // 例: 45.67%
// 成功率のシミュレーション
function isSuccess(successRate) {
return Math.random() * 100 < successRate;
}
console.log('70%の確率で成功:', isSuccess(70)); // true または false

パーセンテージは0から100の範囲なので、101倍して切り捨てます。

isSuccess()関数は、指定した確率でtrueを返すので、ゲームの当たり判定などに使えます。

配列からランダムに選択しよう

単一要素の選択

配列からランダムに1つの要素を選ぶ方法をご紹介します。

// 配列からランダムに1つの要素を選択
function randomChoice(array) {
if (array.length === 0) {
return undefined;
}
let randomIndex = Math.floor(Math.random() * array.length);
return array[randomIndex];
}
// 使用例
let fruits = ['りんご', 'バナナ', 'オレンジ', 'ぶどう', 'いちご'];
console.log('選ばれた果物:', randomChoice(fruits));
let colors = ['赤', '青', '緑', '黄', '紫'];
console.log('選ばれた色:', randomChoice(colors));
// 空配列の場合
console.log('空配列から選択:', randomChoice([])); // undefined

配列の長さを使って、有効なインデックスをランダムに生成します。

空配列のチェックも忘れずに行うことで、エラーを防げます。 メニューの選択や、ランダムなメッセージ表示などによく使われます。

複数要素の選択

配列から重複なしで複数の要素を選ぶ方法をご紹介します。

// 配列からランダムにn個の要素を選択(重複なし)
function randomChoices(array, count) {
if (count >= array.length) {
return [...array]; // 全要素を返す
}
let shuffled = [...array]; // 元の配列をコピー
let result = [];
for (let i = 0; i < count; i++) {
let randomIndex = Math.floor(Math.random() * shuffled.length);
result.push(shuffled.splice(randomIndex, 1)[0]);
}
return result;
}
// 使用例
let students = ['田中', '佐藤', '山田', '鈴木', '高橋', '渡辺'];
console.log('選ばれた3人:', randomChoices(students, 3));
// 例: ['山田', '鈴木', '田中']
// 重複ありの選択
function randomChoicesWithDuplicates(array, count) {
let result = [];
for (let i = 0; i < count; i++) {
result.push(randomChoice(array));
}
return result;
}
console.log('重複ありで3回選択:', randomChoicesWithDuplicates(fruits, 3));

重複なしの場合は、選んだ要素を配列から取り除きます。

重複ありの場合は、毎回全体から選択します。 抽選やチーム分けなど、様々な場面で活用できます。

配列をシャッフルしよう

Fisher-Yatesアルゴリズム

配列をランダムに並び替える標準的な方法をご紹介します。

// 配列をランダムにシャッフル(Fisher-Yatesアルゴリズム)
function shuffleArray(array) {
let shuffled = [...array]; // 元の配列をコピー
for (let i = shuffled.length - 1; i > 0; i--) {
let randomIndex = Math.floor(Math.random() * (i + 1));
// 要素を交換
[shuffled[i], shuffled[randomIndex]] = [shuffled[randomIndex], shuffled[i]];
}
return shuffled;
}
// 使用例
let numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
console.log('元の配列:', numbers);
console.log('シャッフル後:', shuffleArray(numbers));

配列の最後から順番に、ランダムな位置の要素と交換していきます。

これは数学的に証明された、完全にランダムなシャッフル方法です。 カードゲームやクイズの問題順序をランダムにする時に使われます。

実践的なシャッフル例

カードデッキのシャッフルを実装してみましょう。

// カードデッキのシャッフル
let deck = [];
let suits = ['♠', '♥', '♦', '♣'];
let ranks = ['A', '2', '3', '4', '5', '6', '7', '8', '9', '10', 'J', 'Q', 'K'];
suits.forEach(suit => {
ranks.forEach(rank => {
deck.push(suit + rank);
});
});
console.log('シャッフルされたデッキ:', shuffleArray(deck).slice(0, 5));
// 最初の5枚を表示

この方法で、本物のトランプと同じようにカードをシャッフルできます。

実践的な使用例

じゃんけんゲーム

じゃんけんのコンピューター側の手を決める例をご紹介します。

class JankenGame {
constructor() {
this.choices = ['グー', 'チョキ', 'パー'];
}
getComputerChoice() {
return randomChoice(this.choices);
}
play(playerChoice) {
let computerChoice = this.getComputerChoice();
let result = this.judge(playerChoice, computerChoice);
return {
player: playerChoice,
computer: computerChoice,
result: result
};
}
judge(player, computer) {
if (player === computer) {
return '引き分け';
}
let winConditions = {
'グー': 'チョキ',
'チョキ': 'パー',
'パー': 'グー'
};
return winConditions[player] === computer ? 'プレイヤーの勝ち' : 'コンピューターの勝ち';
}
}
// 使用例
let game = new JankenGame();
console.log(game.play('グー'));
// 例: { player: 'グー', computer: 'パー', result: 'コンピューターの勝ち' }

クラスを使ってじゃんけんゲームの機能をまとめています。

コンピューターの手はランダムに決まるので、公平なゲームになります。

クイズアプリ

問題をランダムに出題するクイズアプリの例をご紹介します。

class QuizApp {
constructor() {
this.questions = [
{ question: 'JavaScriptの作者は?', answers: ['ブレンダン・アイク', 'ビル・ゲイツ', 'スティーブ・ジョブズ'], correct: 0 },
{ question: 'HTMLの正式名称は?', answers: ['HyperText Markup Language', 'Home Tool Markup Language', 'Hyperlink Text Management Language'], correct: 0 },
{ question: 'CSSは何の略?', answers: ['Computer Style Sheets', 'Cascading Style Sheets', 'Creative Style Sheets'], correct: 1 },
{ question: 'JSONは何の略?', answers: ['JavaScript Object Notation', 'Java Standard Object Notation', 'JavaScript Organized Notation'], correct: 0 }
];
this.usedQuestions = [];
}
getRandomQuestion() {
if (this.usedQuestions.length === this.questions.length) {
this.usedQuestions = []; // リセット
}
let availableQuestions = this.questions.filter((_, index) =>
!this.usedQuestions.includes(index)
);
let randomQuestion = randomChoice(availableQuestions);
let questionIndex = this.questions.indexOf(randomQuestion);
this.usedQuestions.push(questionIndex);
return {
...randomQuestion,
shuffledAnswers: this.shuffleAnswers(randomQuestion)
};
}
shuffleAnswers(question) {
let answers = [...question.answers];
let correctAnswer = answers[question.correct];
let shuffled = shuffleArray(answers);
let newCorrectIndex = shuffled.indexOf(correctAnswer);
return {
answers: shuffled,
correct: newCorrectIndex
};
}
}
// 使用例
let quiz = new QuizApp();
let question = quiz.getRandomQuestion();
console.log('問題:', question.question);
console.log('選択肢:', question.shuffledAnswers.answers);
console.log('正解番号:', question.shuffledAnswers.correct);

問題と選択肢の両方をランダムにすることで、より公平なクイズができます。

使用済みの問題を管理することで、同じ問題が連続しないようにしています。

パスワード生成器

ランダムなパスワードを生成する例をご紹介します。

class PasswordGenerator {
constructor() {
this.lowercase = 'abcdefghijklmnopqrstuvwxyz';
this.uppercase = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
this.numbers = '0123456789';
this.symbols = '!@#$%^&*()_+-=[]{}|;:,.<>?';
}
generatePassword(length = 12, options = {}) {
let {
includeLowercase = true,
includeUppercase = true,
includeNumbers = true,
includeSymbols = false
} = options;
let charset = '';
if (includeLowercase) charset += this.lowercase;
if (includeUppercase) charset += this.uppercase;
if (includeNumbers) charset += this.numbers;
if (includeSymbols) charset += this.symbols;
if (charset === '') {
throw new Error('少なくとも1つの文字種類を含める必要があります');
}
let password = '';
for (let i = 0; i < length; i++) {
let randomIndex = Math.floor(Math.random() * charset.length);
password += charset[randomIndex];
}
return password;
}
generateSecurePassword(length = 16) {
// 各文字種類から最低1文字ずつ含める
let password = '';
password += randomChoice(this.lowercase);
password += randomChoice(this.uppercase);
password += randomChoice(this.numbers);
password += randomChoice(this.symbols);
// 残りの文字をランダムに
let allChars = this.lowercase + this.uppercase + this.numbers + this.symbols;
for (let i = 4; i < length; i++) {
password += randomChoice(allChars);
}
// 文字をシャッフル
return shuffleArray(password.split('')).join('');
}
}
// 使用例
let passwordGen = new PasswordGenerator();
console.log('基本パスワード:', passwordGen.generatePassword());
console.log('記号なしパスワード:', passwordGen.generatePassword(8, { includeSymbols: false }));
console.log('セキュアパスワード:', passwordGen.generateSecurePassword());

様々な文字種類を組み合わせて、強固なパスワードを生成できます。

セキュアパスワードでは、各文字種類を最低1文字ずつ含めることで、より安全になります。

よくある間違いとその対処法

範囲指定の間違い

よくある範囲指定のミスとその修正方法をご紹介します。

// 間違い:1から10の整数を生成しようとして...
function wrongRandomInt() {
return Math.random() * 10; // 0.0から9.999...の小数になる
}
// 正しい:1から10の整数を生成
function correctRandomInt() {
return Math.floor(Math.random() * 10) + 1; // 1から10の整数
}
// より一般的な正しい実装
function randomIntRange(min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
}
// 検証
console.log('間違った実装:', wrongRandomInt()); // 小数が出力される
console.log('正しい実装:', correctRandomInt()); // 1-10の整数が出力される

Math.floor()を使わないと小数のままになってしまいます。

整数が欲しい場合は、必ずMath.floor()で切り捨てましょう。

偏りのある乱数

特定の値に偏りが生じる問題とその対策をご紹介します。

// 偏りのある実装(良くない例)
function biasedRandom() {
// Math.round を使うと端の値の確率が半分になる
return Math.round(Math.random() * 10);
}
// 偏りのない実装
function unbiasedRandom() {
return Math.floor(Math.random() * 11); // 0から10
}
// 検証用の関数
function testRandomDistribution(func, iterations = 10000) {
let counts = {};
for (let i = 0; i < iterations; i++) {
let value = func();
counts[value] = (counts[value] || 0) + 1;
}
return counts;
}
// 分布を確認
console.log('偏りあり:', testRandomDistribution(biasedRandom));
console.log('偏りなし:', testRandomDistribution(unbiasedRandom));

Math.round()を使うと、端の値(0と10)の確率が他の値の半分になってしまいます。

公平な乱数を作るには、Math.floor()を使いましょう。

まとめ

JavaScriptのMath.randomは、様々な種類のランダムな値を生成する基盤となる重要な機能です。

今回学習した内容をまとめました。

  • Math.randomは0以上1未満の小数を生成
  • Math.floorと組み合わせて整数乱数を作成
  • 配列からのランダム選択やシャッフルの実装
  • ゲーム、クイズ、パスワード生成などの実践的活用
  • 範囲指定の正しい方法と偏りの回避

実際に使える技術

  • 整数乱数:Math.floor(Math.random() * (max - min + 1)) + min
  • 配列からの選択:配列の長さを使ったインデックス指定
  • 配列のシャッフル:Fisher-Yatesアルゴリズム
  • 実用的なアプリケーション:ゲーム、クイズ、パスワード生成

乱数を適切に活用することで、ユーザーにとって予測できない、興味深いインタラクションを提供できます!

特に、正しい範囲指定と偏りのない分布を意識することが重要です。 これらの技術をマスターして、より魅力的で動的なWebアプリケーションを作成してみませんか?

ぜひ今日から、ランダムな要素を取り入れたプログラムを作ってみてください!

関連記事