ゴマちゃんフロンティア

アザラシが大好きなエンジニアの開発日記です

【開発日記】「アザラシ検定」Webアプリを制作・公開しました!

time 2019/04/29

というわけで、GW前にTwitterに投稿しましたが、「アザラシ検定」なるWebアプリを公開しました!

「あなたのアザラシ力を測定」という意味不明なキャッチコピーです。
元々は「Laravel」と「vue.js」の練習を兼ねて、私個人のアザラシ力向上のために作っていたアプリでしたが、公開せずに自己満足で終わるのはもったいないと思い、ブログと同じVPS上にアップロードして公開してみました。
フォロワーのアザラー様のおかげで程よく拡散され、概ね好評をいただいております。ありがとうございます!

せっかくなので仕様の紹介と、作った感想について書き残しておきます。
アザラシ検定自体は以下のURLからアクセスできます。
http://azarashiquiz.gomafrontier.com/

細かい仕様と仕組み

問題データの用意

レベルごとにJSONファイルに配列で書いています。
1問題ごとのフォーマットは以下のような感じ。

"question_text": "ゴマ模様が特徴のアザラシの名前は?",
"level": 1,
"answer": "ゴマフアザラシ",
"answer_index": 3,
"choices": [
    {
        "choice_index": 1,
        "choice_text": "ワモンアザラシ"
    },
    {
        "choice_index": 2,
        "choice_text": "タテゴトアザラシ"
    },
    {
        "choice_index": 3,
        "choice_text": "ゴマフアザラシ"
    },
    {
        "choice_index": 4,
        "choice_text": "ゴマアザラシ"
    }
]

問題文と選択肢、解答の番号を用意しています。
フォーマットとしては過不足ありませんでしたが、すべて手作業で追記していたこと、1問あたり (それっぽい) 選択肢を4つ用意しなければならないことがきつかったです。
そのうち管理画面を用意して、登録・編集が可能なフォームを作ろうと考えています。

問題の取得と抽出

トップ画面で問題のレベルを選んだ後にサーバと通信し、レベルに応じた問題の一覧を取得します。
レベル選択後に画面が暗くなりロード中を示す画像が表示されますが、そのタイミングですね。

問題数は10固定なので、DBからレベルに応じたレコードを取り出し、シャッフルした後で10レコードを取り出しています。なので決まったパターンはなく、内容や順番は完全にランダムです。
コードでは以下のようになっています。

$resultQuiz = array();

// レベルに応じた問題の取得
$quizzes = Quiz::where('level', $level)->distinct()->get()->toArray();

// 出題順序をランダムにする
shuffle($quizzes);

// 出題する問題数分だけ取得
$quizzes = array_slice($quizzes, 0, self::QUESTION_COUNT);

取得後は問題データをブラウザのLocalStorageに保存し、問題画面を表示します。
進行に合わせて「現在回答している問題番号」「選んだ回答の番号」もLocalStorageに保存しています。

結果画面と「○級」の基準

最後の問題を回答するとサーバとの通信が行われ、送信した回答に対するランクやコメント、答えの一覧を取得します。
級の基準は単純で、「正解数/問題数」の割合で算出しています。
コード的には以下のような感じ。

protected function calcAzarashiRank($correct_answer_count, $total_answer_count)
{
    $rank = 0;

    // 正解数が0の場合は5級扱いにする
    if ($correct_answer_count === 0) {
        return 5;
    }

    // 正解率を計算
    $correct_answer_rate = $correct_answer_count / $total_answer_count;

    // 正解率に応じたランクの判定
    switch ($correct_answer_rate) {
        case $correct_answer_rate === 1:
            $rank = 1;
            break;

        case  0.8 <= $correct_answer_rate:
            $rank = 2;
            break;

        case 0.5 <= $correct_answer_rate:
            $rank = 3;
            break;

        case 0.2 <= $correct_answer_rate:
            $rank = 4;
            break;

        default:
            $rank = 5;
            break;
    }

    // 上手く算出できなかった場合は例外
    if ($rank === 0) {
        throw new \Exception("ランクの計算が不正です。(rank:{$rank})");
    }

    return $rank;
}

すぐ下に表示されるコメントはDBに用意されており、レベルと級に応じて15パターンのいずれかを表示します。

回答と正答の一覧はBootstrap4のTableで作成しています。
スマホからだと見にくいのが難点ですが、「どの問題の何を選んで、答えは何だったか」を10問表示する関係で、他に良いレイアウトが思い付かなかったので押し通しました。

自己評価と感想

まず第一に誉めるとすれば、各画面遷移時のテンポの良さですね。
この手の「サクッとやってみて欲しいもの」はSPAと相性いいです。これが1つ回答するごとに画面描画とかだったら嫌になりそうです。
「1問1画面」のシンプルな構成が実現できたのもSPAのおかげですね。
あとは大きなバグもない (?) かと思われます。通販サイトやブログと違って大きな仕組みがないので、なくて当然でないと困るところではありますが…。

逆に今後改善していきたい点は「問題の追加」と「レイアウト・デザイン」ですね。
特に問題は各レベル30問ほどしか用意されていません。故に現状では一発ギャグの領域を出ないので、試験の対策本のように「継続してアザラシを学習できる」アプリにすることが目標です。
デザインは「Bootstrap4」のデフォルトそのままなので、分かる人が見るとちょっと残念に感じます。私自身がデザインさっぱり分からないので、自分でもできそうなところから改善する予定です。

またユニットテストをほとんど書いていなかったり、デプロイの仕組みが整っていなかったりと、今時のWebアプリとして「それはどうなの…?」な点が多いです。
継続的な運用を見越したwebアプリを作れるようになりたいですね。

あとがき

ということで、アザラシ検定アプリを制作・公開した件に関するお話でした。
作って公開して良かったか後悔したかで言えば、間違いなく「良かった」です。
Laravelやvue.jsの勉強になったことは勿論、フォロワー様からの「作ってくれてありがとう」の声がすごく嬉しかったです。

今後もITでアザラシな人として面白いアプリを作っていこうと思いますので、お楽しみに~!

down

コメントする