当サイトはアフィリエイト広告(PR)を利用しています

診断ツールの作り方|答えごとに点数を足してタイプを決める仕組み【HTML・JavaScript】

診断ツールの作り方|答えごとに点数を足してタイプを決める仕組み【HTML・JavaScript】

「あなたは〇〇タイプ!」とわかる診断は、SNSでシェアされやすく、遊んでいて楽しいコンテンツです。

実は診断ツールは、HTMLとJavaScriptだけで作れます。しくみはクイズゲームとほぼ同じで、「正解・不正解」のかわりに「タイプごとの点数」を数えるだけです。

この記事では、kakapo studio のプログラミングの学び方診断を作ったときのしくみを、コピペで動くコードと一緒に解説します。

完成イメージ

まずは、これから作るシンプルな診断(3問・2タイプ)を試してみてください。

休日の過ごし方診断を試す

本格的な例は、プログラミングの学び方診断(7問・4タイプ)で見られます。

完成コード(コピペでOK)

メモ帳に貼り付けて shindan.html という名前で保存し、ブラウザで開くと動きます。

shindan.html

<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>はじめての診断ツール</title>
  <style>
    body { font-family: sans-serif; text-align: center; padding: 24px; }
    #choices button { display: block; width: 100%; max-width: 320px; margin: 8px auto; padding: 12px; font-size: 16px; cursor: pointer; }
  </style>
</head>
<body>
  <h1>休日の過ごし方診断</h1>
  <p id="question"></p>
  <div id="choices"></div>
  <div id="result" hidden>
    <p>あなたは…</p>
    <h2 id="type-name"></h2>
    <p id="type-text"></p>
    <button id="retry">もう一度</button>
  </div>

  <script>
    // ① 質問のデータ:選んだ答えごとに、どのタイプに何点入るか
    const questions = [
      {
        text: "休みの日、まず何をしたい?",
        choices: [
          { label: "出かける!", points: { out: 2 } },
          { label: "家でゆっくり", points: { home: 2 } },
        ],
      },
      {
        text: "友だちから急に遊びに誘われたら?",
        choices: [
          { label: "すぐ行く", points: { out: 2 } },
          { label: "内容による", points: { out: 1, home: 1 } },
          { label: "今日はやめておく", points: { home: 2 } },
        ],
      },
      {
        text: "理想の夜ごはんは?",
        choices: [
          { label: "話題のお店", points: { out: 1 } },
          { label: "家で好きなものを作る", points: { home: 1 } },
        ],
      },
    ];

    // ② 結果のデータ
    const results = {
      out: { name: "おでかけタイプ", text: "新しい場所や人との出会いで元気になるタイプ。" },
      home: { name: "おうちタイプ", text: "自分のペースでゆっくり過ごすと元気になるタイプ。" },
    };

    // ③ 状態:今何問目か、各タイプの点数
    let current = 0;
    let scores = { out: 0, home: 0 };

    // ④ 質問を表示する
    function showQuestion() {
      const q = questions[current];
      document.getElementById("question").textContent = q.text;
      const box = document.getElementById("choices");
      box.innerHTML = "";
      q.choices.forEach((choice) => {
        const button = document.createElement("button");
        button.textContent = choice.label;
        button.addEventListener("click", () => choose(choice));
        box.appendChild(button);
      });
    }

    // ⑤ 答えを選んだら、点数を足して次へ
    function choose(choice) {
      for (const type in choice.points) {
        scores[type] += choice.points[type];
      }
      current++;
      if (current < questions.length) {
        showQuestion();
      } else {
        showResult();
      }
    }

    // ⑥ 一番点数が高いタイプを結果にする(同点なら先に書いたほう)
    function showResult() {
      let best = "out";
      for (const type in scores) {
        if (scores[type] > scores[best]) {
          best = type;
        }
      }
      document.getElementById("question").textContent = "";
      document.getElementById("choices").innerHTML = "";
      document.getElementById("type-name").textContent = results[best].name;
      document.getElementById("type-text").textContent = results[best].text;
      document.getElementById("result").hidden = false;
    }

    document.getElementById("retry").addEventListener("click", () => {
      current = 0;
      scores = { out: 0, home: 0 };
      document.getElementById("result").hidden = true;
      showQuestion();
    });

    showQuestion();
  </script>
</body>
</html>

しくみ:答えごとに点数を足していく

① 質問のデータ

ポイントは、選択肢ごとに points を持たせていることです。{ out: 2 } なら「おでかけタイプに2点」、{ out: 1, home: 1 } なら「両方に1点ずつ」という意味です。

どちらとも言えない答えに、両方のタイプへ点を入れておくと、結果が極端になりすぎません。

② 結果のデータ

タイプごとに、名前と説明文を用意します。質問と結果をデータとして分けておくと、あとから中身を変えるのがかんたんです。

⑤ 点数を足す

答えが選ばれたら、その選択肢の points を、タイプごとの合計に足していきます。

⑥ 一番点数が高いタイプを結果にする

全部答え終わったら、合計点が一番高いタイプを結果にします。

本格的にするための工夫

ここからは、プログラミングの学び方診断で実際に入れている工夫を紹介します。

工夫1:同点のときのルールを決めておく

タイプが増えると、同点になることがよくあります。そこで、同点のときはどのタイプを優先するかを、データとして決めておきます。

const questions = [
  {
    text: "プログラミングを学ぶ、一番の目的は?",
    choices: [
      { label: "作りたいもの(ゲーム・アプリなど)がある", points: { ai: 2, book: 1 } },
      { label: "仕事にしたい・転職したい", points: { school: 3 } },
      { label: "副業で稼げるようになりたい", points: { school: 1, trial: 2 } },
      { label: "なんとなく興味がある", points: { trial: 2, ai: 1 } },
    ],
  },
  // …(全7問)…
];

// 同点のときは、この順番で先にあるタイプを結果にする
const typeOrder = ["trial", "ai", "book", "school"];
// ===== 点数を合計して、タイプを決める =====
function calcScores() {
  const scores = { ai: 0, book: 0, school: 0, trial: 0 };
  answers.forEach((choiceIndex, questionIndex) => {
    const points = questions[questionIndex].choices[choiceIndex].points;
    for (const type in points) {
      scores[type] += points[type];
    }
  });
  return scores;
}

function calcType() {
  const scores = calcScores();
  // いちばん点数が高いタイプ(同点なら typeOrder で先にあるほう)
  let best = typeOrder[0];
  typeOrder.forEach((type) => {
    if (scores[type] > scores[best]) {
      best = type;
    }
  });
  return best;
}

答えを1つずつ記録しておく(answers)作りにしたので、「ひとつ前に戻る」ボタンも作れます。戻ったときは、記録を消して点数を計算し直すだけです。

工夫2:結果が偏っていないか、全パターンを調べる

診断を作ってみて気づいたのが、配点しだいで、特定の結果ばかり出てしまうことです。

そこで、すべての答え方を機械的に試して、どのタイプが何回出るかを数えました。プログラミングの学び方診断は 4×3×3×4×3×4×3 = 5,184通りなので、一瞬で計算できます。

// 全部の答え方を試して、どのタイプが何回出るか数える
const counts = { ai: 0, book: 0, school: 0, trial: 0 };

function tryAll(i) {
  if (i === questions.length) {
    counts[calcType()]++; // 7問すべて答えたら、結果を数える
    return;
  }
  for (let c = 0; c < questions[i].choices.length; c++) {
    answers[i] = c;
    tryAll(i + 1);
  }
}

tryAll(0);
console.log(counts);

最初の配点では「スクール集中タイプ」が35%も出ていて、どんな答え方をしてもスクールを勧められるような診断になっていました。配点を調整して、4つのタイプがそれぞれ21〜27%になるようにしています。

あわせて、「転職したい・3か月で・予算あり」ならスクール、「作りたいものがある・無料で」ならAI独学、のように、典型的な人の答え方で、納得できる結果が出るかも確かめました。

工夫3:結果をシェアできるURLにする

結果ごとに ?type=ai のようなURLを作り、XやLINEでシェアできるようにしています。

// シェア
const shareUrl = SHINDAN_URL + "?type=" + type;
const shareText = "プログラミングの学び方診断の結果は「" + r.name + "」でした! #kakapo_studio";
$("share-x").href =
  "https://x.com/intent/post?text=" + encodeURIComponent(shareText) +
  "&url=" + encodeURIComponent(shareUrl);
$("share-line").href =
  "https://social-plugins.line.me/lineit/share?url=" + encodeURIComponent(shareUrl);

シェアされたURLを開いた人には、その結果と「自分も診断してみる」ボタンを表示します。

// シェアされたURL(?type=ai など)から来た人には、その結果を見せる
const sharedType = new URLSearchParams(location.search).get("type");
if (results[sharedType]) {
  showResult(sharedType, true);
}

クイズとのちがい

クイズ診断
選択肢が持つ情報正解かどうかどのタイプに何点入るか
数えるもの正解した数タイプごとの点数
結果〇問正解一番点数が高いタイプ

クイズゲームが作れたら、診断ツールはすぐに作れます。クイズの作り方はこちらの記事で解説しています。

まとめ

  • 診断ツールは、選択肢ごとに「どのタイプに何点入るか」を持たせて、合計点で結果を決める
  • 同点のときのルールを決めておく
  • 全パターンを試して、結果が偏っていないか確かめる
  • 結果ごとのURLを作ると、SNSでシェアしてもらいやすい

プログラミングの学び方診断をやってみる