2014年12月8日月曜日

JavaScriptの配列とオブジェクト、HTMLのフォームでクイズを作ろう2

前回はJavaScriptの配列とオブジェクト、HTMLのフォームを使ってクイズを作りました。しかし、前回のコードでは回答した時に記録をとっていないので、何度か回答していると同じ問題が出題されるということがあります。今回は一度回答した問題は出題しないという処理を追加してみます。始めに出題番号を入れる変数と回答を記録する変数を用意します。変数の型は配列にしておきます。

var quizzes = [/** 出題内容は省略 **/];
var quiz;

//出題番号を入れておく
var questionNumber;

//回答を記録しておく変数
var answered = [];

window.onload = function(){
    init();
};

function init(){
    var r = Math.floor(Math.random() * quizzes.length);
    quiz = quizzes[r];
    
    //問題用のフォームに表示する
    var questionForm = document.querySelector("#question");
    questionForm.value = quiz.q;
}

function doAnswer(){
    //回答時の処理は省略
}

function right(){
    //正解した時の処理は省略
}

function wrong(){
    //不正解の時の処理は省略
}


出題番号の記録と回答の記録用の配列を用意したら、始めにinit関数を修正します。

function init(){
    var r = Math.floor(Math.random() * quizzes.length);
    quiz = quizzes[r];

    //出題番号を入れておく
    questionNumber = r;
    
    //問題用のフォームに表示する
    var questionForm = document.querySelector("#question");
    questionForm.value = quiz.q;
}

次に正解時に回答用の配列に答えた問題番号を入れておきます。

function right(){
    alert("正解です");
    
    //答えた問題の出題番号を記録しておく
    answered.push(questionNumber);
    init();
}

出題番号を回答用の配列に入れる時は、配列の変数.push(値)を利用します。これで回答した問題の番号の記録はできました。後は出題の直前ですでに回答した問題か調べて出題します。init関数を修正します。

function init(){
    //init関数の中だけでr変数を使用する
    var r;
    
    //既に出題しているかを調べる
    //alreadyがfalseの場合は再度出題番号を取得する
    var already = true;
    do{
        r = Math.floor(Math.random() * quizzes.length);
        for ( var i = 0; i < answered.length; i++ ) {
            //取得した出題番号がすでに回答済みの場合はfalseを入れる
            if ( answered[i] == r ) {
                already = false;
            }
        }
    }while(already == false);

    quiz = quizzes[r];    
    questionNumber = r;
    
    //問題用のフォームに表示する
    var questionForm = document.querySelector("#question");
    questionForm.value = quiz.q;
}

do-while文とif文を利用して、出題番号を取得した後にすでに回答済みか調べて、回答していない問題の出題番号を取得します。これで同じ問題が出題されるということはなくなります。しかしこの状態では、すべての問題を回答後にinit関数でまだ回答していない問題の出題番号を取得し続けるという処理が残ってしまうため、right関数の方に全問回答の処理を追加しておきます。

function right(){
    alert("正解です");
    
    //答えた問題の出題番号を記録しておく
    answered.push(questionNumber);
    
    //全問回答した場合
    if (answered.length == quizzes.length) {
        //クイズを終了する処理を追加
    
    //問題が残っている場合は出題する
    } else {
        init();
    }
}

right関数内の次の出題を行う処理のところにif文を追加して、全問正解の場合はクイズを終了するという処理を追加しておきます。これで出題番号を取得し続ける不具合は解決します。

0 件のコメント:

コメントを投稿