マガジン

配達ゲームで燃料を無限にしたら、面白さは残るか

遊びを見つける

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

月夜の街を結ぶ配達経路と、手前に置かれた自転車と三つの小包。
記事のテーマをもとに制作したAI生成イラスト。

「月夜の配達」のような経路パズルで、一歩進むたびに燃料が1減る場面を考えてみます。小包は3つ、バッグは2枠です。遠回りは許されないので、どの順に拾ってどの順に届けるかを何度も頭の中で組み替えます。この迷う時間が、ゲームの緊張感の正体に見えます。 では、燃料が減らなくなったらどうなるでしょうか。迷う理由が消えて、ただ歩くだけの作業になるかもしれません。反対に、バッグが2枠しかないために拾う順番の難しさが残り、緊張感がほとんど変わらないかもしれません。どちらになるかは、予想では決められません。 この記事は、その答えを読者が自分で出すための実験の設計書です。結果は書きません。燃料の有無を切り替えられる小さな試作を用意し、条件を一つずつ変えて、緊張感を支えていたのが燃料なのか、バッグの枠なのか、それとも別のものなのかを切り分けます。

この記事の目次
  1. 何を外すのかを先に決める
  2. 準備:最小の試作を用意する
  3. 手順:条件を一つずつ変える
  4. 記録の取り方
  5. 結果の読み方と、誤りやすい点
  6. 次の行動

何を外すのかを先に決める

「燃料を無限にする」と一言で言っても、燃料は同時にいくつかの役割を担っています。

  • 手数の上限:遠回りすると失敗するので、一手に重みが生まれます。
  • 比較の基準:「燃料がこれだけ余った」という形で、うまくやれたかが数字になります。
  • やり直しの動機:失敗したときに、もっと短い道を探したくなります。

燃料を外すと、この3つが同時に消えます。そこで、問いを二つに分けます。

  1. 燃料を無限にすると、迷う時間や考える手間は減るか。
  2. 減るなら、「手数の目標」を自分で置き直すと戻るか。

1つ目は、燃料が選択の重みを作っていたかを調べる問いです。2つ目は、重みを作っていたのが燃料そのものか、燃料が生む「測れる目標」かを調べる問いです。同じ「燃料なし」でも、目標を人が置き直せば別のゲームになるからです。

もう一つ、先に決めておくことがあります。バッグの枠(同時に持てる小包の数)は今回は動かしません。一度に変えるのは一つだけにします。バッグ枠を変える追加実験は、最後に触れます。

準備:最小の試作を用意する

「月夜の配達」を遊んで感触を確かめたうえで、構造だけを真似た小さな試作を使います。作品そのものを再現するものではなく、実験用の道具です。

用意するものは次のとおりです。

  • 下のコードを haitatsu.html という名前で保存したもの(ブラウザで開くだけで動きます)
  • 紙とペン、またはメモアプリ
  • スマホのタイマー(手が止まった時間を測りたい場合)
  • 可能なら、遊んでくれる人を1人以上

試作は5×5のマスです。矢印キーで1マス動くたびに燃料が1減ります。「拾」のマスに乗ると小包を拾い、同じ番号の「届」のマスに乗ると届けます。バッグは2枠です。i キーで燃料の有限と無限を切り替え、r キーでやり直せます。

html
<canvas id="c" width="250" height="250"></canvas>
<p id="s"></p>
<script>
let INF=false;const FUEL=20,N=5;
const P=[{f:[0,1],t:[4,0]},{f:[2,4],t:[0,3]},{f:[4,2],t:[2,0]}];
let me,fuel,bag,done,steps,msg;
function reset(){me=[0,0];fuel=FUEL;bag=[];done=[];steps=0;msg="";draw();}
function draw(){
  const g=document.getElementById("c").getContext("2d");
  g.clearRect(0,0,250,250);g.font="14px sans-serif";
  for(let i=0;i<N;i++)for(let j=0;j<N;j++)g.strokeRect(i*50,j*50,50,50);
  P.forEach((p,i)=>{
    if(done.includes(i))return;
    if(!bag.includes(i))g.fillText("拾"+(i+1),p.f[0]*50+12,p.f[1]*50+30);
    g.fillText("届"+(i+1),p.t[0]*50+12,p.t[1]*50+30);
  });
  g.beginPath();g.arc(me[0]*50+25,me[1]*50+40,6,0,7);g.fill();
  document.getElementById("s").textContent=
    `手数${steps} 燃料${INF?"∞":fuel} 配達${done.length}/3 バッグ${bag.length}/2 ${msg}`;
}
document.addEventListener("keydown",e=>{
  if(e.key==="r")return reset();
  if(e.key==="i"){INF=!INF;return reset();}
  const d={ArrowLeft:[-1,0],ArrowRight:[1,0],ArrowUp:[0,-1],ArrowDown:[0,1]}[e.key];
  if(!d||msg)return;
  const x=me[0]+d[0],y=me[1]+d[1];
  if(x<0||y<0||x>=N||y>=N)return;
  e.preventDefault();
  me=[x,y];steps++;if(!INF)fuel--;
  P.forEach((p,i)=>{
    if(!bag.includes(i)&&!done.includes(i)&&bag.length<2&&p.f+""==me+"")bag.push(i);
    if(bag.includes(i)&&p.t+""==me+""){bag=bag.filter(k=>k!=i);done.push(i);}
  });
  if(done.length==3)msg="完了";else if(!INF&&fuel<=0)msg="燃料切れ";
  draw();
});
reset();
</script>

燃料の初期値 FUEL は20にしてあります。最少手数はあえて書いていません。実験の最初に、自分で数えて確かめてください。

マップを複数用意する

同じ配置を何度も遊ぶと、答えを覚えてしまい、燃料の有無とは関係なく迷いが減ります。これが最大の落とし穴です。そこで、配列 P の座標を書き換えた配置を、最低3種類用意します。座標は [x, y] で、0〜4の範囲です。拾う場所と届ける場所が重ならないように決めてください。

手順:条件を一つずつ変える

比べる条件は次の4つです。

  • A 基準、燃料:有限(FUEL=20)、手数の目標:なし、見たいこと:元の緊張感の感触
  • B 燃料なし、燃料:無限(iキー)、手数の目標:なし、見たいこと:迷いが残るか
  • C 目標つき、燃料:無限、手数の目標:自分で決めた手数、見たいこと:目標が緊張感を戻すか
  • D 厳しめ、燃料:有限(最少手数ちょうど)、手数の目標:なし、見たいこと:厳しすぎない範囲があるか

手順は次の順序です。

  1. 最初のマップで、Bの状態(iキーで無限)で何度か試して、最少手数を自分で数えます。この数はCとDで使います。
  2. 次のマップごとに、条件をA→B→C→Dの順で固定せず、入れ替えて割り当てます。たとえば、マップ1にA、マップ2にB、マップ3にCを割り当て、別の日や別の人は割り当てをずらします。
  3. Cでは、遊ぶ前に紙に目標手数を書きます。最少手数に2〜3を足した値が、達成できそうな目標になります。
  4. Dでは、FUEL を手順1で数えた最少手数に書き換えます。

一人で行う場合、同じ日に全条件を続けると疲れが影響します。マップごとに間隔を空けるか、数日に分けてください。複数人で行う場合は、どの条件かを事前に伝えず、遊んだあとに聞くほうが偏りません。

記録の取り方

1プレイを1行として、次の項目を紙かメモアプリに書きます。

  • 条件(A〜D)とマップの番号
  • 手数(画面の表示をそのまま)
  • 手が止まった回数:次の一歩を決めるまでに3秒以上かかった回数です。自分で数えにくい場合は、画面を録画して見返すか、横で数えてもらいます。
  • r でやり直した回数
  • 終了直後の「もう一回遊びたい度」:0(もういい)、1(どちらでも)、2(すぐやりたい)の3段階です。
  • 一言メモ:「どうでもいい」と感じた瞬間があれば、そのときの状況を書きます。

回数は、各条件につき最低2プレイ(別のマップで)は取ってください。1回だけだと、たまたまの出来に左右されます。それでも少ない回数なので、後で述べるように、断定でなく傾向として読みます。

「止まった回数」は主観が入りやすい項目です。数え方の基準(3秒)を最初に固定し、途中で変えないでください。

結果の読み方と、誤りやすい点

記録がそろったら、条件ごとに「止まった回数」「やり直し回数」「もう一回遊びたい度」の平均を並べます。読み方の目安は次のとおりです。

  • AとBで止まった回数があまり変わらない場合:迷いの源は燃料以外にあります。バッグ2枠や拾う順番の組み合わせが、パズルとして働いている可能性があります。
  • Bで止まった回数が大きく減る場合:燃料が一手の重みを作っていたと読めます。
  • Bで「もう一回遊びたい度」が低く、Cで上がる場合:緊張感の源は、燃料そのものより「測れる目標」にあった可能性があります。
  • Dでやり直しが増え、遊びたい度が下がる場合:燃料の余裕がなさすぎて、挑戦が罰に変わっています。AとDの間に、ちょうどよい余裕の範囲がありそうです。

どの読み方でも、複数のパターンが同時に当てはまることがあります。数人分の記録を足しても統計的に確かな結論にはなりません。「この試作ではこう見えた」という範囲にとどめてください。

誤りやすい点も挙げておきます。

  • 答えの暗記:同じマップを繰り返すと、迷う理由そのものが消えます。マップは必ず変えます。
  • 一度に二つ変える:燃料とバッグ枠を同時に変えると、どちらの効果か分かりません。
  • 条件の順序の影響:Aを最初、Bを最後に固定すると、慣れによる差が条件の差に見えます。
  • 試作の限界:試作は5×5の単純な盤面です。結果を「月夜の配達」にそのまま当てはめることはできません。

本体の作品に戻って確かめる

試作で見えたことを、実際の「月夜の配達」で確かめる視点を挙げておきます。確認済みの設計から読み取れるのは、燃料が1区間につき1減って有限であること、バッグが2枠であること、残り最短距離の表示、次の一歩を照らすヒント、一歩戻る機能があることです。これらは、燃料の重みを保ちつつ失敗の取り返しをつける仕組みと読めます。燃料の総量や各夜の細かな配置は、作品を開いて確かめてください。最少区間数の記録はプレイ中だけ残るので、自分用にメモを取っておくと、条件Cの「手数の目標」の練習にもなります。

バッグ枠の追加実験は、コードの bag.length<2 を bag.length<3 に書き換えるだけでできます。燃料の条件は固定し、枠だけを変えてください。

次の行動

まず haitatsu.html を保存し、Bの状態で最少手数を数えるところから始めてみてください。そのうえで、マップを3つ用意し、A〜Cの記録を1行ずつ取ります。最後に「月夜の配達」を遊び直し、残り最短距離の表示やヒントが自分の迷い方をどう変えるか、一言メモに残してみてください。