マガジン

マインスイーパの最初の一手はなぜ安全なのか

遊びを見つける

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

道をつなぐ線、丸い駒、幾何学のタイルからなるパズルの模型。
記事のテーマをもとに制作したAI生成イメージ。実際のゲーム画面ではありません。

マインスイーパを開いて最初のマスを押すと、地雷が出ずに数字や空白がぱっと広がります。ところが、地雷はゲーム開始時にすでに埋まっていると思って遊ぶ人も多いはずです。埋まっているのなら、最初に押したマスが地雷でもおかしくありません。それなのに初手で爆発しない実装が多いのは、作り手が初手の扱いを決めているからです。 この記事で確かめるのは「初手を安全にする方法は何通りあり、それぞれ盤面の運をどこまで減らし、どこに癖を残すか」という問いです。結論を先に言うと、方法によって地雷の分布は変わります。初手が安全でも、その後の推理だけで解ける盤面かどうかは別の話です。以下では、数える単位と手順を示します。数値の結果は書かないので、手元で計算して確かめてください。

この記事の目次
  1. 初手が安全なことの価値を数える
  2. 初手を安全にする3つの作り方
  3. 自分のゲームの初手を調べる記録の取り方
  4. 結果の読み方と間違えやすい点
  5. コードで3方式の癖を見る
  6. 運を減らすことと、推理で解けることは別
  7. 次の行動

初手が安全なことの価値を数える

まず、初手を安全にしない場合の危険度を計算します。標準的な盤面サイズでは、地雷の数を全マス数で割った値が、初手で地雷を踏む確率です。

  • 初級、盤面:9×9(81マス)、地雷数:10、初手が地雷の確率(地雷数÷マス数):10÷81
  • 中級、盤面:16×16(256マス)、地雷数:40、初手が地雷の確率(地雷数÷マス数):40÷256
  • 上級、盤面:30×16(480マス)、地雷数:99、初手が地雷の確率(地雷数÷マス数):99÷480

電卓で割ってみてください。いちばん易しい盤面でも、10回に1回は初手で終わる計算になります。初手での失敗は、推理の腕前とは無関係な理不尽な負けです。そこで多くの実装は、最初のクリックだけ運の要素を取り除いています。

ただし、どの実装も同じ方法を使うとは限りません。自分が遊ぶゲームがどれに当たるかは、次の節の手順で調べます。

初手を安全にする3つの作り方

初手を安全にする方法は、大きく3種類に整理できます。

  • 方式A(押してから置く):最初のクリックを受けた後で、押したマスを除いた場所に地雷を置きます。
  • 方式B(動かす):先に地雷を置いておき、最初のクリックが地雷だったときだけ、その地雷を別の空きマスへ移します。移し先を「左上から探して最初の空きマス」のように決める実装がありえます。
  • 方式C(やり直す):先に地雷を置き、最初のクリックが地雷なら、盤面ごと作り直します。安全な盤面になるまで繰り返します。

方式AとCは、数学的には同じ結果になります。Cは「押したマスが地雷でない配置」だけが残るまで引き直すので、押したマスを除いたすべての配置が同じ確率で現れます。これはAと同じ分布です。

方式Bは違います。移し先に決まりがあれば、その場所に地雷が集まりやすくなります。初手の位置がどこであっても、地雷が偏って現れる場所があることになります。偏りは小さくても、同じ盤面を何百回も遊べば、偏りのある場所は理屈の上では見つかります。

さらに、実装によっては初手の周囲8マスも地雷から外し、最初のクリックで空白が広がるようにしています。この仕様の有無は、遊ぶ側から見ると手触りの差になります。

自分のゲームの初手を調べる記録の取り方

遊んでいるマインスイーパ(または自作の盤面)がどの方式に近いかは、観察で絞り込めます。単位は「1回の対局の最初のクリック」です。

  1. 毎回、盤面の角を最初のクリックにして、対局を50回以上繰り返します。角にすると、周囲が3マスしかないので、周囲の扱いの違いが表れやすくなります。
  2. 1回ごとに、初手の結果を次の3つのどれかで記録します。「空白が広がった(周囲に地雷0)」「数字が出た」「地雷だった」。
  3. 角のほかに中央でも同じ回数を繰り返し、角と中央の「空白が広がった割合」を並べます。
  4. 余力があれば、爆発を避けて初手を終えた後、盤面左上の角に地雷があった回数も数えます。

記録は「回数÷試行数」の割合にして、角と中央で比べます。1回ごとのばらつきは大きいので、数十回程度では結論を急がず、傾向として読みます。

結果の読み方と間違えやすい点

記録の読み方は次のとおりです。

  • 「地雷だった」が一度も出なければ、初手保護がある可能性が高いと言えます。ただし、50回で0回でも、保護なしの盤面で危険度が10〜20%程度なら出ないほうが不自然です。確率の見積もりは、前の節の表と照らして行ってください。
  • 角で「空白が広がった」割合が中央より極端に高い、または毎回空白になるなら、周囲8マスも地雷から外している可能性があります。
  • 初手の安全は保証されているのに、盤面左上の角の地雷が多めに感じられるなら、方式Bの癖を疑う手がかりになります。ただし、これは試行回数が少ないとただの偶然と見分けがつきません。

起こりやすい誤りもあります。

  • 回数が少ない:10回程度では、偏りがあってもなくても見分けがつきません。
  • 押す場所が毎回違う:初手の位置をばらばらにすると、角と中央の比較ができなくなります。
  • 自分の記憶に頼る:「爆発した気がする」で数えず、1回ごとに記録してください。
  • 旗を立てた盤面を混ぜる:初手の観察では、旗を使わず最初の1クリックの結果だけを記録します。

コードで3方式の癖を見る

実装を確かめる代わりに、自分で3方式を書いて比べる方法もあります。次の単独HTMLを保存して開くと、初級盤面で3方式を各20,000回ずつ試し、「初手の周囲が空白になった割合」と「左上のマスが地雷だった割合」を表示します。

html
<pre id="o"></pre>
<script>
const W=9,H=9,M=10,N=W*H,T=20000,c=40; // cは初手のマス番号。40は中央
const all=[...Array(N).keys()];
function pick(cells,m){const a=cells.slice();
  for(let i=a.length-1;i>0;i--){const j=Math.floor(Math.random()*(i+1));[a[i],a[j]]=[a[j],a[i]];}
  return new Set(a.slice(0,m));}
function near(p){const x=p%W,y=(p/W)|0,r=[];
  for(let dy=-1;dy<=1;dy++)for(let dx=-1;dx<=1;dx++){
    const nx=x+dx,ny=y+dy;
    if((dx||dy)&&nx>=0&&nx<W&&ny>=0&&ny<H)r.push(ny*W+nx);}
  return r;}
const A=()=>pick(all.filter(i=>i!==c),M);
const B=()=>{const m=pick(all,M);
  if(m.has(c)){m.delete(c);for(let i=0;i<N;i++)if(i!==c&&!m.has(i)){m.add(i);break;}}
  return m;};
const C=()=>{let m;do{m=pick(all,M);}while(m.has(c));return m;};
let out="";
for(const [name,f] of [["A 押してから置く",A],["B 動かす",B],["C やり直す",C]]){
  let zero=0,tl=0;
  for(let t=0;t<T;t++){const m=f();
    if(near(c).every(i=>!m.has(i)))zero++;
    if(m.has(0))tl++;}
  out+=name+"  周囲が空白: "+(zero/T)+"  左上が地雷: "+(tl/T)+"\n";}
document.getElementById("o").textContent=out;
</script>

読み方は次のとおりです。

  • 「周囲が空白」の割合は、理屈の上ではAとCで近い値になり、試行のたびに小さくぶれます。この「ぶれ」の幅を知るために、同じコードを数回実行してください。
  • 「左上が地雷」の割合は、Bだけ他の2つより高くなると予想できます。実際にそうなるかは、実行して確かめます。
  • cを0(左上の角)に変えると、Bで地雷が移る先と初手が重なるため、見え方が変わります。cを変えて、自分で理由を考えてみてください。

運を減らすことと、推理で解けることは別

初手が安全になっても、盤面の運は消えません。初手のあとに、どこを押しても確率が五分五分の局面が現れることがあります。これは「推測を強いられる盤面」と呼ばれます。初手保護は「最初の理不尽な負け」を消す仕組みであり、「その後を必ず論理で解ける盤面」を保証する仕組みではありません。

この違いも、手元で数えられます。初手のあとで推測が必要になった対局が何回あったかを、「推測なしで終えた回数÷対局数」として記録します。保護の有無とは別の、盤面生成の設計の差が見えてきます。推測が不要な盤面だけを出す実装は、生成後に解けるか検証する処理が必要で、作る側の手間も増えます。

次の行動

まず、遊んでいるマインスイーパで、角を初手にして50回の記録を取ってみてください。次に、上のコードのcと地雷数を変えて、3方式の割合がどう動くかを見てください。自分で盤面生成を書いてみたくなったら、HTMLファイル1つでもアソバースに投稿できます。