0
0

【JavaScript】配列の要素をランダムに表示する

Last updated at Posted at 2024-02-14

はじめに

こちらの記事で紹介した野球クイズアプリ開発の続編です。

現状だと問題が順番に表示されているのですが、これをランダムに表示されるようにしたいと思います。

修正したい点

  • 問題を順番ではなく、ランダムに表示したい
quizController.js
import quizData  from "../data/quizdata.js";

let currentQuestionIndex = 0;
let score = 0;

function displayQuestion() {
    const question = document.getElementById('question');
    const scoreDisplay = document.getElementById('score');
    
    // 現在の質問と選択肢を表示
    question.textContent = quizData[currentQuestionIndex].question;
    quizData[currentQuestionIndex].choices.forEach((choice, index) => {
        const button = document.getElementById(`btn${index}`);
        button.textContent = choice;
        button.onclick = () => checkAnswer(choice);
    });
    
    // スコアを更新
    scoreDisplay.textContent = `スコア: ${score}`;
}

function checkAnswer(choice) {
    if (choice === quizData[currentQuestionIndex].answer) {
        score++;
        alert('正解!');
    } else {
        alert('不正解!');
    }

    currentQuestionIndex++;
    if (currentQuestionIndex < quizData.length) {
        displayQuestion();
    } else {
        alert(`クイズ終了!あなたのスコアは ${score} 点です。`);
        resetQuiz();
    }
}

// もしクイズが終了したら、最初の質問を表示する
function resetQuiz() {
    currentQuestionIndex = 0;
    score = 0;
    shuffle(quizData);
    displayQuestion();
}

// クイズの初期表示
displayQuestion();
quizdata.js
const quizData = [
    {
      question: "日本はWBCで何回優勝している?",
      choices: ["1回", "2回", "3回", "4回"],
      answer: "3回"
    },

    {
      question: "日本のプロ野球は何球団ある?",
      choices: ["10球団", "11球団", "12球団", "13球団"],
      answer: "12球団"
    },

    {
      question: "日本のプロ野球は何リーグある?",
      choices: ["1リーグ", "2リーグ", "3リーグ", "4リーグ"],
      answer: "2リーグ"
    },

    {
      question: "野球の試合で、チームが攻撃側から守備側に交代するのは、何アウト後?",
      choices: ["1アウト", "2アウト", "3アウト", "4アウト"],
      answer: "3アウト"
    },

   // 以下略
];

export default quizData;

解決方法

  • 問題の出題順をランダム化するためには、quizData配列をシャッフルする
  • 具体的には「Fisher-Yatesアルゴリズム」を使う
// 
function shuffle(array) {
    for(let i = (quizData.length - 1); i > 0; i--) {
        const j = Math.floor(Math.random() * (i - 1));
        [array[i], array[j]] = [array[j], array[i]];
    }
}

// クイズ開始時に選択肢をシャッフル
shuffle(quizData);
        

Fisher-Yatesアルゴリズムに関する説明は以下の記事などが参考になります。

一言で言うと、shuffle関数では配列からランダムに要素を抽出して入れ替えています。

そのためにはランダムな0〜1未満の数字を生成するMath.random()と、小数点以下の数字を切り捨てるMath.floor()を使います。

完成形

quizController.js
import quizData  from "../data/quizdata.js";

let currentQuestionIndex = 0;
let score = 0;

function shuffle(array) {
    for (let i = (array.length - 1); i > 0; i--) {
        const j = Math.floor(Math.random() * (i + 1));
        [array[i], array[j]] = [array[j], array[i]];
    }
}

// 中略・・・

// クイズ開始時に選択肢をシャッフル
shuffle(quizData);

function resetQuiz() {
    currentQuestionIndex = 0;
    score = 0;
    shuffle(quizData); // クイズをリセットする際にも選択肢をシャッフル
    displayQuestion();
}

// クイズの初期表示
displayQuestion();

これで問題がランダムな順番で表示されるようになりました!

参考

最後に

今後はそれぞれの問題に難易度を設定して配点の比重を変えたり、クイズの解説を表示できるようにしてみたいと思います!

コメントやアドバイスがあればお待ちしています!!

お読みいただきありがとうございました。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0