大きい順に並べ替えるクイズを作ってみる(サーバーサイドPHP編)

スポンサーリンク

このページではソースコードの一部分を簡単な解説をしています。

作成したゲームはコチラから
ソースコードはgithubにあります

スポンサーリンク

概要

選択肢四つの中から大きい順にクリックして答えていくクイズゲームです。ジャンルを選びクリックするとクイズが始まります。サーバーサイドにはPHPを使用しデータベースから4つの選択肢をランダムに取得してクイズの作成とクライアント側から送られてきた回答の答え合わせをしています。クライアントサイドはJavaScriptを使用してクイズの表示、回答の送信などをしています。

クライアント側の記事は↓にあります。

データベースにクイズの選択肢と答えを追加する

データベースはSQLiteを使用しました。コマンドラインツールを使えるようにするためにSQLiteの公式サイトからPrecompiled Binariesダウンロードをし、解凍したファイルの中のsqlite3.exeを作業フォルダに移してターミナルからコマンドラインでテーブルを作成していきます。テーブルの中には二つのカラムがあり、一つ目のnameカラムにはクイズの選択肢の名前を保持して二つ目のsizeカラムには答えとなる大きさを保持しています。

sqlite3 test.db
sqlite> CREATE TABLE prefecturesArea(name TEXT, size INTEGER);

続いてクイズの選択肢と答えを追加していきます。追加するデータはwikipediaなどからコピーしたものをエクセルに張り付けcsvファイルに編集したものを使いました。

sqlite> .mode csv
sqlite> .import prefectures-area.csv prefecturesArea
sqlite>
sqlite> .headers on
sqlite> .mode column
sqlite> select * from prefecturesArea;
name  size    
----  --------
北海道   78420.12
岩手県   15275.03
福島県   13784.14
長野県   13561.6
      .
      .
      .

データベースから選択肢をランダムに抽出してクイズ作成

データベースの接続にはPHPのPDOを利用しました。データベースから四つランダムに抜き出したものをそのままクライアント側へ送り、答え合わせ用に大きさ順に並び替えたものはサーバー側のSESSION変数で保持しています。
*以下からのソースコードは一部分ですそのままでは動きませんすべてのソースコードはgithubにあります。

// 問題と答えを作成
function makeQuiz()
{
    $pdo = getPdoInstance(); // pdoインスタンス生成
    // 問題用 データベースからランダム問題の選択肢をに4つ抜き出す
    $stmt = $pdo->query("SELECT * FROM <code>{$_POST['genre']} ORDER BY RANDOM() LIMIT 4");
    $stmts = $stmt->fetchAll();
    $json = json_encode($stmts, JSON_UNESCAPED_UNICODE);
    $answer = json_decode($json, true);
    $quiz = array_column($answer, 'name');
    $quiz = json_encode($quiz);
    
    // 答え合わせ用 大きい順に並び替え
    foreach($answer as $key => $value){
        $size[$key] = $value["size"];
    }
    // 答えに重複値があるかチェック無ければ問題を作成
    $value_count = array_count_values($size);
    $max = max($value_count);
    if($max == 1){
        array_multisort($size, SORT_DESC, $answer);
    // セッションで答えを保持
    $_SESSION['count'] = 0;
    foreach($answer as $key){
        $_SESSION['answer'][] = [$key['name'], $key['size']];
    }
        return $quiz;
    // 答えに重複値がある場合はもう一度クイズ作成
    }else{
        makeQuiz();
        return;
    }
}

答え合わせ

クライアント側から送られてきた回答をSESSION変数に保持していた答えと照らし合わせて判定しています。正解した場合、不正解の場合、選択肢4つすべて正解の場合、クイズを5問クリアした場合に分岐させ、連想配列のキー名resultにその状態を値として保持し、答えと一緒にクライアントへ渡して受け取ったクライアント側はresultの値によって表示する内容を変えるようにしました。

// 回答が送られてきた時の処理
if(isset($_POST['answer'])){
    // 1問クリア
    if($_SESSION['count'] === 3){
        $_SESSION['clearCount']++;
        // 5問クリア
        if($_SESSION['clearCount'] === 5){
            echo sendAnswer('clear');
            return;
        }else{
            echo sendAnswer('next');
            return;
        }
    }
    // 答え合わせ
    // 正解
    if(filter_input(INPUT_POST, 'answer') == $_SESSION['answer'][$_SESSION['count']][0]){
        echo sendAnswer('correct');
        $_SESSION['count']++;
        return;
    }
    // 不正解
    else{
        echo sendAnswer('incorrent');
        return;
    }
}

function sendAnswer($resut)
{
    if($resut === 'incorrent'){
        $array = array('result'=>'incorrect', $_SESSION['answer']);
        $array = json_encode($array, JSON_UNESCAPED_UNICODE);
        return $array;
    }
    $array = array('result'=> $resut, 'size'=>$_SESSION['answer'][$_SESSION['count']][1]);
    $array = json_encode($array, JSON_UNESCAPED_UNICODE);
    return $array;
}

ソースコードはgithubにあります
最後までお読みいただきありがとうございました。

タイトルとURLをコピーしました