マガジン

AIに難易度を「ちょうどよく」と頼むと何を基準にするか

遊びをつくる

執筆にClaudeを使用しています。

速さ、選択肢、ミスの許容を三つの異なる仕掛けで表したゲーム模型のイラスト。
記事のテーマをもとに制作したAI生成イラスト。

自作の的当てゲームを、AIに渡す場面を考えてみます。「このゲーム、難易度をちょうどよくして」と一行だけ添えます。返ってきたコードでは、的の落ちる速さが変わっているかもしれません。的が出る間隔が変わっているかもしれませんし、ミスの許容数に手が入っているかもしれません。いずれにせよ、その変更が「誰にとって」ちょうどいいのかは、依頼文のどこにも書かれていません。 この記事は、その空白をAIがどう埋めるかを観察する実験の設計書です。結果は書きません。読者の手元で、同じゲームと同じ依頼を使って確かめる手順と、記録の取り方、読み方を示します。観察が終わったら、AIに推測させるのをやめ、基準を自分で言葉と数字にして渡す形へ進みます。

この記事の目次
  1. 何を確かめるか
  2. 準備:動かす数値を一か所に集めた試作
  3. 手順:同じ試作に三種類の依頼を出す
  4. 記録と結果の読み方
  5. 基準を自分で与える形へ
  6. 次の行動

何を確かめるか

「ちょうどよく」という依頼には、少なくとも三つの未確定があります。この実験では、それぞれを問いに分けます。

  1. どの数値を動かすか。 速さ、出現間隔、的の大きさ、許されるミスの数のうち、AIが選ぶ項目に偏りがあるかを見ます。
  2. 基準を言葉にするか。 「初心者向けに」「カジュアルな層を想定して」など、想定する遊び手を自分から明言するのか、黙って数値だけを変えるのかを見ます。
  3. 同じ依頼で揺れるか。 同じ文面を何度か出したとき、変更の方向(易しくする/難しくする)や項目が毎回同じか、バラつくかを見ます。

もう一つ、補助的に見るものがあります。それは、AIが聞き返してくるかどうかです。「誰が遊ぶ想定ですか」と尋ねるなら、それも観察結果の一つです。

準備:動かす数値を一か所に集めた試作

実験用のゲームは、小さければ小さいほど変更点を追いやすくなります。難易度に関わる数値を、CONFIG という一つのかたまりにまとめた的当てを使います。次のコードをHTMLファイルとして保存すれば、ブラウザだけで動きます。

html
<!doctype html>
<meta charset="utf-8">
<canvas id="c" width="400" height="300" style="border:1px solid #888"></canvas>
<p id="s"></p>
<script>
const CONFIG = {
  spawnMs: 900,  // 的が出る間隔(ミリ秒)
  speed: 1.5,    // 落下速度(1フレームあたりのpx)
  radius: 20,    // 的の半径
  lives: 3       // 取り逃がしてよい数
};
const ctx = c.getContext("2d");
let t = [], hit = 0, life = CONFIG.lives, over = false;
setInterval(() => { if (!over) t.push({ x: 30 + Math.random() * 340, y: 0 }); }, CONFIG.spawnMs);
c.onclick = e => {
  const r = c.getBoundingClientRect(), x = e.clientX - r.left, y = e.clientY - r.top;
  const i = t.findIndex(o => Math.hypot(o.x - x, o.y - y) <= CONFIG.radius);
  if (i >= 0) { t.splice(i, 1); hit++; }
};
function loop() {
  ctx.clearRect(0, 0, 400, 300);
  for (const o of t) {
    o.y += CONFIG.speed;
    ctx.beginPath(); ctx.arc(o.x, o.y, CONFIG.radius, 0, 7); ctx.stroke();
  }
  t = t.filter(o => o.y <= 300 || (life--, false));
  if (life <= 0) over = true;
  s.textContent = "命中 " + hit + " / 残り " + life + (over ? " 終了" : "");
  if (!over) requestAnimationFrame(loop);
}
loop();
</script>

まず、このまま自分で5回遊んで、どんな感触かをメモしておきます。AIの変更を評価するときの「変更前の基準点」になります。

あわせて、依頼文を三種類用意します。

  • 依頼A(曖昧): 「このゲームの難易度をちょうどよくしてください。」
  • 依頼B(理由を求める): 「このゲームの難易度をちょうどよくしてください。何を基準にそう判断したかも説明してください。」
  • 依頼C(基準つき): 「初めて遊ぶ人が最初の30秒で的の半分以上を取れて、ミス3回で終わるまで1分前後続く難易度にしてください。」

依頼Cの数字は例です。実際に使うときは、自分のゲームに合う目標へ置き換えてください。Cは後半の節で使う、比較用の対照です。

手順:同じ試作に三種類の依頼を出す

進め方は次のとおりです。

  1. 依頼ごとに、毎回新しい会話を開きます。前の会話が残っていると、前の回答が文脈になって揺れの観察が崩れます。
  2. 各会話の最初に、コード全体を貼り、続けて依頼文をそのまま送ります。依頼文に言葉を足さないでください。
  3. 各依頼を5回ずつ、合計15回実施します。回数が少なすぎると揺れが偶然かどうか判断できず、多すぎると記録が続きません。5回は、傾向を見るための最低限の目安です。
  4. 返ってきた回答は、コードを含めて丸ごと保存します。要約して保存すると、あとから「副次的な変更」を拾えなくなります。
  5. 聞き返された場合は、「お任せします」とだけ返し、その後の変更を記録します。聞き返されたこと自体も記録欄に残します。

AIに使うモデルや設定を途中で変えないでください。複数のAIを比べたいなら、同じ手順をAIごとに別シートで行います。

記録と結果の読み方

記録シートの項目

1回の回答ごとに一行、次の項目を記録します。

  • 依頼の種類・回番号、記録のしかた:A-1、B-3 のように記します
  • 変更した数値、記録のしかた:spawnMs speed radius lives のうち、変わったものすべて
  • 変更前後の値、記録のしかた:例:speed 1.5 → 1.2
  • 方向、記録のしかた:易しく/難しく/項目により混在
  • 述べられた基準、記録のしかた:回答中の想定プレイヤーや目標を示す言葉を、そのまま書き写します
  • 聞き返し、記録のしかた:あり/なし
  • 副次的な変更、記録のしかた:CONFIG 以外のコードへの変更(得点、演出、新機能の追加など)

さらに、変更後のコードを自分で5回遊び、5回それぞれの命中数と終了までの秒数を書きます。手元の端末での体感に加えて、数字を残してください。

結果の読み方

集計では、まず列ごとに縦に見ます。判断の目安は次のとおりです。

  • 動かした項目が毎回ほぼ同じなら、そのAIの「ちょうどよく」には既定の調整の型があると読めます。その型が自分のゲームの狙いに合うかは、別に判断します。
  • 項目や方向が回ごとにバラつくなら、依頼Aの出力は再現できません。同じ文面でも違う難易度が出るので、そのまま採用するのは避けたほうが安全です。
  • AとBで変更内容に違いが出るなら、説明を求めること自体が調整の中身に影響しています。説明が先か変更が先かで、判断の質が変わる可能性があります。
  • 述べられた基準の言葉が毎回同じ層(たとえば初心者)を指すなら、AIが暗黙の想定プレイヤーを持っていると読めます。それが自分の想定読者と一致するかを確かめます。
  • 基準を述べず、数値だけ変えていた回が多いなら、変更の根拠を後から追えません。記録に「基準なし」と明記し、Bの結果と比較します。
  • 自分で遊んだ数字が、AIの述べた基準と合わないなら、AIは数値を変えただけで、遊びの結果までは確かめていません。この差こそ、基準を人間が数字で持つ必要がある理由になります。

誤りやすい点

  • 画面のリフレッシュレートが違う端末では、requestAnimationFrame の回数が変わり、speed の体感も変わります。変更前後の比較は、必ず同じ端末で行ってください。
  • 5回の試遊は、自分の慣れで後半ほど上手くなります。変更前と変更後を交互に遊ぶと、慣れの影響を均せます。
  • 回答の「それっぽい説明」は、基準の証拠になりません。説明が数値の変更と食い違っていないかを、コードの差分で確かめてください。
  • 副次的な変更を見落とさないでください。得点や出現位置まで書き換えられていると、難易度の比較そのものが成り立たなくなります。
  • 結果を一般化しすぎないでください。この観察から言えるのは、この試作と、使ったAIと、その日の依頼文についてだけです。

基準を自分で与える形へ

観察が終わったら、依頼Cの形に進みます。コツは、基準を遊び手・場面・測れる数字の三つに分けて書くことです。

  1. 遊び手: 「ゲームに慣れていない人」「このジャンルを遊び慣れた人」のように、一つに絞ります。
  2. 場面: 「最初の30秒」「1回の挑戦」のように、どの区間の話かを示します。
  3. 数字: 命中率、ミス3回までの継続秒数、ゲームオーバーまでの平均など、自分で遊んで測れるものにします。

この三つを書いた依頼は、返ってきたコードの採否を、自分の試遊で判定できます。基準に届かなければ、「命中率が目標より低かった。速さだけを下げて」のように、測った数字を添えて次の調整を頼めます。これで調整が、推測のやり取りから、測定を挟んだ往復に変わります。

難易度を言葉と数字で切り分ける考え方は、アソバースの公式作品にも見られます。たとえば「時計じかけの台所」は、時間制限なしの「見習い」と、1皿28秒・配膳6秒・ミス3回までの「本番」に分かれています。「かたちのあいだ」にも、3×3の入門と4×4の2段階があります。どちらも、設計から読み取れるのは、難しさを一つのつまみで済ませず、遊び手の段階ごとに条件を明示していることです。それぞれの段階の遊び心地は、作品を開いて確かめてください。

自分のゲームでも、「初めての人向け」と「慣れた人向け」の二つに分けて基準を書くと、AIへの依頼が二本に分かれ、それぞれの採否を別々に判断できます。

次の行動

まず、上のコードを保存して自分で5回遊び、変更前の数字を残します。次に、依頼Aを新しい会話で5回出し、記録シートに変更した数値と述べられた基準を書き込んでください。そこで見えた偏りや揺れを手がかりに、自分のゲーム向けの依頼Cを作り、試遊の数字で採否を決めてみてください。