「ヒント」を作り込む:一歩だけ示す・理由を添える・回数を数える
遊びをつくる執筆にClaudeを使用しています。

パズルゲームで、プレイヤーが同じ盤面を30秒以上見つめたまま動かなくなる場面を考えてみます。ここでヒントボタンを押すと答えが全部表示されたら、手は進みますが、考える楽しさは消えます。反対に「もう少し考えてみましょう」とだけ表示されたら、プレイヤーは手がかりを得られず、ゲームを閉じるかもしれません。 ヒント機能の難しさは、この二つの失敗のあいだに線を引く点にあります。この記事では、その線を自分の作品で引けるようにします。ヒントを「答え」ではなく「段階」として作り、各段階に理由を添え、使った回数を数えてコストを決めます。最後に、やりすぎかどうかを友人に試してもらって判断する手順も示します。 題材は、隣り合うカードを入れ替えて小さい順に並べる最小のパズルです。コードは外部ライブラリもサーバーも使わない単独のHTMLで、他のゲームにも置き換えられるように書きます。
ヒントは「答え」ではなく段階で作る
最初に決めるのは、ヒントを一種類の出力にしないことです。助けの強さを弱い順に並べると、たいてい次の四つの段にできます。
- 1、示す内容:盤面のどこに注目するか(印だけ)、プレイヤーに残る仕事:なぜそこかを考え、手を選ぶ
- 2、示す内容:なぜそこが問題なのか(理由)、プレイヤーに残る仕事:解消する手を選ぶ
- 3、示す内容:どの手を打つか(一歩だけ)、プレイヤーに残る仕事:手を実行する
- 4、示す内容:残りの全手順(解答)、プレイヤーに残る仕事:ほぼなし
多くのゲームで適切なのは段1〜3までで、段4は「あきらめる」ボタンとして別に用意するのが無難です。段4をヒントに混ぜると、段1〜3の価値が下がります。
公式作品の機能名からも、この考え方を読み取れます。いずれも、作品を開いて実際の出方を確かめてください。
- 潮目のオセロ:ヒントは「理由付き」で、返る石のプレビューも別に備えています。ヒントと一手戻すはひとり対局のみで、オンライン対局には出ません。対人戦で助けを禁じる設計だと読み取れます。
- 月夜の配達:「残り最短距離」の表示と、「次の一歩を照らすヒント」が別々の機能として並んでいます。全体の見通しと次の一手が分かれています。
- プリズムの道:ヒントは「一歩だけ」です。解答全体を見せない設計です。
- かたちのあいだ:ヒントは「次の一手」で、最短とは限りません。「一手戻す」を使っても手数は減りません。助けが、記録に与える影響まで考えてあります。
細かい出方や文言は、作品ごとに開いて確かめてください。
手順1:次の一歩を返す関数を作る
ヒントの土台は、「いまの盤面から、よい次の一手を一つ返す関数」です。ここが曖昧だと、あとの段階もすべて曖昧になります。
- 盤面の状態を、プログラムで扱える形(配列など)にします。
- 「手を一つ打つ」処理を、盤面を受け取って新しい盤面を返す関数にします。
- 「いまの盤面から打てる手のうち、解決に近づくものを一つ返す」関数を作ります。
- 解決済みの盤面では、手の代わりに「なし」を返すようにします。
3の「近づく」の定義が、ヒントの質を決めます。このカードの例では、隣り合う二枚のうち左が右より大きい組を選び、入れ替えます。この手は逆順になっている組の数を必ず一つ減らすので、遠回りになりません。
ここで確かめておくべきことがあります。自分のゲームでは、ヒントの手が最短であると保証できるのでしょうか。保証できないなら、「最短とは限りません」と画面に書くか、最短が分かる範囲に絞って出します。かたちのあいだが「最短とは限らない」としているのは、この保証の線引きの一例と読み取れます。
手順2:押すたびに段を進める
次に、同じ盤面でヒントを続けて押すと、弱い助けから順に強くなるようにします。盤面が変わったら、段を1に戻します。
以下を hint.html として保存し、ブラウザで開いてください。カードをクリックすると、右隣と入れ替わります。
<!doctype html>
<meta charset="utf-8">
<div id="row"></div>
<button id="hint">ヒント</button>
<p id="msg"></p>
<p id="info"></p>
<script>
let cards = [3, 1, 4, 2];
let used = 0, level = 0, mark = -1;
function nextHint(list) {
for (let i = 0; i < list.length - 1; i++) {
if (list[i] > list[i + 1]) return i;
}
return -1;
}
function render() {
row.innerHTML = "";
cards.forEach((n, i) => {
const b = document.createElement("button");
b.textContent = n;
const on = mark >= 0 && (i === mark || i === mark + 1);
b.style.outline = on ? "3px solid orange" : "";
b.onclick = () => swap(i);
row.appendChild(b);
});
info.textContent = "ヒント使用: " + used + " 回";
}
function swap(i) {
if (i >= cards.length - 1) return;
[cards[i], cards[i + 1]] = [cards[i + 1], cards[i]];
level = 0; mark = -1; msg.textContent = "";
render();
}
hint.onclick = () => {
const i = nextHint(cards);
if (i < 0) { msg.textContent = "もうそろっています。"; return; }
level++; used++; mark = i;
const a = cards[i], b = cards[i + 1];
if (level === 2) msg.textContent = a + " の右に、より小さい " + b + " があります。";
if (level >= 3) msg.textContent = a + " をクリックすると、" + b + " と入れ替わります。";
render();
};
render();
</script>動かしながら、次の点を確認してください。
- ヒントを1回押すと、注目すべき二枚に枠が付きます(段1)。
- 続けて押すと、理由の文が出ます(段2)。
- さらに押すと、具体的な操作が出ます(段3)。
- どれかのカードをクリックすると、段が1に戻り、文が消えます。
- 並びきってからヒントを押すと、「もうそろっています。」と出ます。
段の数と文言は、自分のゲームに合わせて書き換えてください。変えてはいけないのは、「盤面が変わったら段を戻す」という点です。戻さないと、新しい盤面でいきなり強い助けが出てしまいます。
手順3:理由を添える
段2の理由は、ヒントの中でいちばん書き方に差が出る部分です。次の二つを、機械的に作れる文で書きます。
- 何が条件を満たしていないか:上の例では「3の右に、より小さい1がある」です。
- その手がなぜそれを解消するか:「入れ替えると、この組の逆順がなくなる」です。
理由を書くときに注意する点は三つあります。
- 「こちらのほうがよいです」のような評価だけの文は避けます。プレイヤーが次の盤面で自分で応用できないからです。
- 盤面の状態から文を組み立てられるようにします。手書きの固定文では、すべての盤面をカバーできません。
- 専門用語を使うなら、初出で短く説明します。ゲーム内の言葉と説明文がずれるのを防げます。
潮目のオセロが「理由付き」のヒントを備えていることは確認できますが、その理由の文面や種類は作品を開いて確かめてください。自作のヒントと並べて、理由の粒度を比べてみるのも参考になります。
手順4:回数を数えてコストを決める
ヒントを数えるのは、罰を与えるためではなく、プレイヤー自身に使いどころを意識してもらうためです。まず、数えたあとに何をするかを三つの型から選びます。
- 表示だけ、内容:「ヒント使用: 3回」を出すだけ、向くゲーム:気軽に遊べる、記録を競わない作品
- 回数制限、内容:1プレイで使える回数を決める、向くゲーム:緊張感が欲しい作品
- 点数への影響、内容:使うたびに点や評価が下がる、向くゲーム:点数や記録を残す作品
上のコードは「表示だけ」です。点数へ影響させるなら、used を使って最終点を計算します。減らす量には、公式作品の「こだまの森」が参考になります。この作品では、聴き直しが15点減、間違いが30点減で、間違いが3回で終了します。助けを借りる行為のほうが、失敗より軽い設計だと読み取れます。ヒントを使うのは悪いことではない、という立場を数値にしたものです。
自分のゲームでは、次の順で決めてみてください。
- まず「表示だけ」で作り、数えた数を見えるようにします。
- 次に、ヒントを使った人と使わなかった人で、結果に差をつけたいかを考えます。
- つけたいなら、減点は失敗の減点より小さくします。
- 回数制限にするなら、制限に達したときの表示も用意します。無言でボタンが効かなくなると、故障に見えます。
数値の根拠が自分に見えない場合は、とりあえず小さな値で始めて、次節の手順で確かめるのが確実です。
やりすぎの線を自分で確かめる
「ここまでが適切」という線は、作品の難しさやプレイヤーによって変わります。そこで、友人に遊んでもらって確かめる実験を設計します。結果はここには書けません。以下の手順で、自分の作品について答えを出してください。
問い:ヒントは、詰まった人を助けつつ、考える楽しさを奪っていないか。
準備するもの
- 動くゲーム(上のコードでも自作でも構いません)
- 遊んでくれる人(3人以上。その作品をまだ知らない人が望ましい)
- 記録用のメモ(紙でも表計算でも構いません)
手順
- 1人につき2回、同じ難しさで遊んでもらいます。
- ヒントを押すたびに、押した時刻を記録します。画面に出す必要はなく、コードの中でカウントしても構いません。
- 各プレイで、次の三つを記録します。
- ヒントを押した回数
- 押す直前に、何秒間手が止まっていたか
- 段2(理由)まで見たあと、自分で次の手を打ったか、段3まで押したか
- 終了後に、一言で聞きます。「ヒントは助けになりましたか。答えを教わった感じがしましたか」。
結果の読み方
- ほぼ全員が1回も押さず、感想でも「ボタンの存在に気づかなかった」と出る場合は、ヒントが見つけにくい状態です。配置や名前を見直します。
- 手が止まってすぐ、段3まで連打する人が多い場合は、段1・2が弱いか、考えるより押すほうが楽な設計になっています。回数の表示や減点を足してみます。
- 段2で止まって自分で打つ人が多ければ、理由の段が機能しています。
- 感想に「答えを教わった」が多い場合は、段3の文言を弱めるか、段3自体を別の「あきらめる」ボタンに移します。
起こりやすい誤り
- 作者本人が遊ぶと、ゲームの答えを知っているため、ヒントが過剰か不足かを判断できません。必ず別の人で確かめてください。
- 1回だけの結果で判断すると、たまたまの差に引きずられます。同じ人にも2回遊んでもらい、1回目と2回目の使い方の違いも見てください。
- 質問の仕方で答えが変わります。「ヒントは便利でしたか」は肯定を誘うので、使い方を聞く形にしてください。
次の行動
まず、上のコードを自作ゲームの「次の一手を返す関数」に置き換えて、段1〜3の三段階を作ってください。次に、友人2〜3人に遊んでもらい、ヒントを押す直前の停止時間と段の使い方をメモしてください。公式作品の「潮目のオセロ」「月夜の配達」「プリズムの道」「かたちのあいだ」を開き、ヒントがどの段まで示すかを見比べると、自作の線を引く参考になります。
作品が仕上がったら、アソバースの投稿画面で下書き保存しながら表示を確かめ、公開後も内容を更新できます。ヒントの出し方は、公開してから調整しても間に合います。

