「必ず勝てる手」があるゲームを作って、見つけさせる
遊びをつくる執筆にClaudeを使用しています。

先手が必ず勝てる石取りゲームがあるとします。その必勝法を一言も教えずに遊ばせたら、プレイヤーは何局目で気づくのでしょうか。気づく前に何が起きるのかも気になります。最初の数局は勝ち負けが運に見えるはずです。そのうち「残りが8のときはなぜか負ける」といった違和感が生まれ、やがて自分の言葉で法則を言えるようになる、という流れが想像できます。 必勝法のあるゲームは、一見すると遊びとして終わっています。答えが決まっているからです。ただし、それは答えを知っている人から見た話です。知らないプレイヤーにとっては、答えを探す過程そのものが遊びになります。作る側の仕事は、答えを隠すことではなく、気づくきっかけをどこに置くかを決めることです。 この記事は実験の設計書です。結果は書いていません。短いHTMLを1つ作り、数人に遊んでもらい、ログから「いつ、どの形で気づいたか」を読み取る手順を示します。読者が自分で行えば、自分のゲームに合った答えが出る形にしています。
この記事の目次
題材は石取りゲーム:必勝法が一行で書けて、盤面からは見えない
使うのは次のルールのゲームです。
- 石が21個あります。
- 二人が交互に、1〜3個のどれかを取ります。
- 最後の1個を取った人の勝ちです。
必勝法は一行で書けます。取り終えたとき、残りが4の倍数になるように取ります。先手は最初に1個取って20個にします。その後、相手がk個取ったら、自分は4−k個取ります。残りは16、12、8、4、0と減り、最後の石は必ず自分が取ります。
実際に確かめてみます。20個の局面で相手が1個取れば残りは19個です。自分が3個取ると16個になります。相手が3個取れば残り13個で、自分は1個取って12個にします。相手の取り方によらず、自分の番の終わりに4の倍数が残ります。
この題材が向いている理由は三つあります。
- 必勝法が正しいことを、作り手が数行で確かめられます。
- 画面に石の数が出るだけで、必勝法は見た目に表れません。
- 発見が段階的に起こります。残り1〜3個なら取り切って勝てます。残り4個は、どう取っても相手に取り切られます。そこから残り8個も同じだと気づき、4の倍数という法則へ進みます。逆算の発見です。
3の段階が、発見の遊びの芯になります。プレイヤーは終盤の勝ち負けから、少しずつ手前へ法則を広げていきます。実験では、この広がりがログにどう出るかを見ます。
準備するもの:記録まで取れる最小のゲーム
必要なのは、次の最小構成のHTMLと、遊んでもらう数人です。外部ライブラリは使わず、通信もしません。1ファイルで動きます。人が先手で、CPUは後手です。CPUは勝てる局面なら必勝の取り方をします。MISSは、その手を外してランダムに取る確率です。
<!doctype html>
<meta charset="utf-8">
<p id="s"></p><div id="b"></div><pre id="out"></pre>
<script>
const START = 21; // 初期の石の数
const MISS = 0; // CPUが必勝手を外す確率(0〜1)
let n, game = 0;
let rows = ["対局,手番,取った数,残り,4の倍数"];
function show(msg) {
s.textContent = "残り " + n + " 個 " + (msg || "");
b.innerHTML = "";
const max = n > 0 ? Math.min(3, n) : 0;
for (let k = 1; k <= max; k++) {
const x = document.createElement("button");
x.textContent = k + "個取る";
x.onclick = () => human(k);
b.append(x);
}
if (n === 0) {
const x = document.createElement("button");
x.textContent = "次の対局";
x.onclick = start;
b.append(x);
}
out.textContent = rows.join("\n");
}
function move(k, who) {
n -= k;
rows.push([game, who, k, n, n % 4 === 0 ? 1 : 0].join(","));
}
function human(k) {
move(k, "人");
if (n === 0) return show("あなたの勝ち");
cpu();
}
function cpu() {
let k = n % 4;
if (k === 0 || Math.random() < MISS)
k = 1 + Math.floor(Math.random() * Math.min(3, n));
move(k, "CPU");
show(n === 0 ? "CPUの勝ち" : "");
}
function start() { game++; n = START; show(); }
start();
</script>ログの最後の列は、その手のあとの残りが4の倍数なら1です。人の手で1が並ぶほど、必勝法に沿っていることになります。
この記事のコードは、手元のブラウザで開くだけで動きます。アソバースに投稿する場合は、このファイルをindex.htmlとしてZIPの直下に入れるか、HTMLとして直接アップロードします。投稿は入力、表示の確認、公開の順に進みます。実験の間は下書き保存で足ります。
手順:条件を三つに分けて、数人に遊ばせる
問いは「ルールだけを知るプレイヤーは、何局目で、どんな形で必勝法に近づくか」です。手がかりの出し方を変えると何が変わるかも、あわせて確かめます。
条件の設計
- A、画面に出すもの:残りの石の数だけ、確かめたいこと:手がかりなしで発見が起きるか
- B、画面に出すもの:残りの数と、直前の対局の手順、確かめたいこと:振り返りが発見を早めるか
- C、画面に出すもの:残りの数と、勝ち負けが決まった局面の印、確かめたいこと:終盤から逆算する発見が起きやすくなるか
条件Bは、rowsの内容を対局終了後に画面へ出すだけで作れます。条件Cは、残りが1〜3個の局面に「取り切れる」、4個の局面に「取り切れない」と表示する改造です。ただし、5個以上の局面には何も印を付けないでください。印を付けると、答えを直接見せることになります。
進め方
- 遊ぶ人を3〜6人集めます。人数が少ないので、結果を一般化せず、自分のゲームの手がかりを選ぶ材料として読みます。
- 1人に割り当てる条件は1つだけにします。同じ人に複数の条件を遊ばせると、学習が持ち越されて比較できません。
- ルールは口頭で説明します。必勝法やヒントは言いません。
- MISSは最初0に固定します。1人あたり8〜10局を目安に遊ばせます。
- 各局の終了ごとに、「いま何か気づいたことはありますか」と一度だけ尋ね、一言をメモします。答えを促す質問はしません。
- 全局が終わったら、「このゲームに勝つコツは何だと思いますか」と聞いて記録します。
記録の取り方:何を、どの単位で残すか
記録は1局ごとの行にします。ログから自動で取れる項目と、手で書く項目を分けます。
- 初手の取った数、取り方:ログの1手目から読む
- 4の倍数を渡せた手の数、取り方:その局の人の手のうち、最終列が1の数
- 人の手の数、取り方:その局の人の手の行数
- 勝敗、取り方:最後の表示から読む
- 局後の一言、取り方:手でメモする
見るべき指標は、局ごとの「4の倍数を渡せた手の数÷人の手の数」です。この値が局を追ってどう動くかを、プレイヤーごとにグラフか表にします。
もう一つ大事なのは、勝ち負けと分けて見ることです。CPUが必勝手を指すので、初手を誤ればほぼ負けます。それでも、勝敗と手の質は別の記録です。負けた局にも、終盤だけ正しく指せている手があるかもしれません。
結果の読み方:どんな形ならどう判断するか
結果が出たら、次のような形に当てはめて読みます。ここに挙げる基準は、読み取りの目安として仮に置いたものです。
終盤から正確になっていく形。 残りが少ない手だけ先に4の倍数を渡せるようになり、徐々に序盤へ広がるなら、逆算の発見が起きていると読めます。条件Cの印が効いたのか、条件Aでも起きたのかを比べます。
初手が急に1へ固定される形。 初手が3択なので、偶然1を選ぶこともあります。2局連続で初手が1になり、その後の手も続けて4の倍数を渡しているなら、法則に気づいた可能性が高いと見ます。1局だけなら偶然の可能性を残します。
初手は1だが、中盤が崩れる形。 「最初に1個取る」という手順だけを覚えた状態かもしれません。局後の一言と、最後の「勝つコツ」の答えを見比べます。コツを言葉にできていれば、中盤の崩れは操作ミスの可能性があります。言葉にできなければ、手順の暗記と読みます。
変化が見えない形。 対局数が足りないか、手がかりが足りない可能性があります。条件Aなら、条件BかCを足します。プレイヤーが「運だ」と感じる状況が続いていないかも、一言のメモで確認します。
最後にMISSを動かす問いを足せます。MISSを0.3にして、同じ数人に別の日に遊ばせます。CPUが手を外すと、法則を知らなくても勝てる局が出ます。偶然の勝ちが、気づく機会を減らすのか増やすのかは、ログで比べて判断します。ここでも、先に答えを決めて読まないでください。
誤りやすい点
- 作り手が答えを言ってしまう。 「4の倍数だよ」と言うのはもちろん、「残りが少ないときが大事」といった助言も条件を崩します。質問は決めた文言だけにします。
- 同じ人に別の条件を遊ばせる。 前の条件で気づいていると、次の条件の効果が読めなくなります。
- ランダムなCPUで検証する。 必勝法を使わなくても勝てるので、発見が起きにくくなります。実験の最初はMISSを0にします。
- 先手と後手の関係を取り違える。 初期個数が4の倍数なら後手が必勝になります。21個なら先手が必勝ですが、20個にすると人間の先手は必敗です。個数を変えるときは、必勝がどちらにあるかを先に確かめます。
- ルールを変えて確認を省く。 取れる数を1〜4個にすれば、5の倍数を渡す形になります。一般に、取れる最大数をmとすると、m+1の倍数を渡す形です。最後の1個を取った人が負けのルールにすると、渡すべき残数は4の倍数に1を足した数に変わります。変えたルールは、小さな個数から手で確かめてから使います。
- ログの転記で数え間違える。 手作業の集計は、人数が少なくても誤りが入ります。最終列が1の行を数える手順を決めて、同じ方法で全員分を集計します。
次の行動
まず上のコードを保存して開き、自分で1局遊んで、4の倍数列の最終列が1になるかを確かめてください。次に、遊んでもらう人を3人集め、条件AからCを1人ずつ割り当てて記録を取ります。結果の読み方の四つの形のうち、どれに近いかを見れば、自分のゲームに足すべき手がかりが決まります。

