マガジン

オセロで「返した石が自分の色にならない」ルールを試す:石が消えると終局はどうなるかの実験設計

遊びを見つける

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

迷路の一角から出口までを段階的に照らす三つの灯りと、小さな旅人の駒
記事のテーマをもとに制作したAI生成イラスト。

標準のオセロでは、挟まれた石は相手の色に変わります。変わるだけなので、石は盤の上に残ります。では「挟まれた石が自分の色にならず、盤から取り除かれる」としたら、終局はどんな形になるでしょうか。盤が石で埋まる終わり方は残るのか、それとも別の終わり方が主役になるのか。この記事は、その問いを自分で確かめるための実験の設計書です。結果は書いていません。数字は、読者が自分の手元で出します。 題名の「自分の色にならない」には、実は複数の作り方があります。相手の色のまま動かない、灰色の中立石になる、盤から消える、などです。この実験では「消える」の一種類に絞ります。変えるルールを一つにしておくと、終局の形が変わったときに原因を特定できます。 実験は二本立てです。短いJavaScriptで、ランダムに打つ者同士の対局を何千回も走らせる方法と、実物の盤で人が打つ方法です。前者は偏りのない数が出ます。後者は、人が打つとどんな形になるかを見せてくれます。両方を並べて読むところが、この実験の肝です。

この記事の目次
  1. 変えるルールを一つだけ決める
  2. 実験の前に予想を書き留める
  3. 手順:二つの方法で対局を集める
  4. 記録の取り方
  5. 結果の読み方と誤りやすい点
  6. 次の行動

変えるルールを一つだけ決める

比べる対象は次の2つです。

  • 標準ルール(flip):挟んだ相手の石は、自分の色に変わります。
  • 消滅ルール(vanish):挟んだ相手の石は、盤から取り除かれて空きマスになります。

消滅ルールは、次のように厳密に定義します。曖昧なまま始めると、記録が比べられなくなるからです。

  1. 初期配置は標準と同じです。中央の4マスに、対角線上で同じ色が並ぶように置きます。先手は黒です。
  2. 石を置けるのは、標準と同じ条件を満たすマスだけです。つまり、空きマスのうち、いずれかの方向に「相手の石が1個以上続き、その先に自分の石がある」マスです。
  3. 置いたら、挟んだ相手の石をすべて取り除きます。複数の方向で同時に挟めた場合も、すべて取り除きます。
  4. 挟む側の端にある自分の石は、そのまま残ります。
  5. 置ける場所がなければパスです。両者が続けてパスしたら終局です。
  6. 勝敗は、終局時の石の数が多い方です。同数なら引き分けとします。

標準ルールの終局の形はすでに知られています。盤が埋まるか、両者とも置けなくなるかです。標準ルールでは石を置くたびに空きマスが1つ減るので、パスがなければ最大60手で盤が埋まります。初期配置が4石、盤が64マスだからです。この「60手」が、比較の物差しになります。

実験の前に予想を書き留める

実験を始める前に、予想を紙に書いておきます。結果を見てから「そう思っていた」と感じる後付けを避けるためです。次の4つに、それぞれ一言で答えを書いてください。

  1. 消滅ルールでは、盤が石で埋まる局面が現れるでしょうか。
  2. 終局の主な理由は、「片方の色が全滅する」「両者とも置けなくなる」「終わらない」のどれでしょうか。
  3. 先手(黒)と後手(白)の勝ちやすさは、標準ルールと比べてどう変わるでしょうか。
  4. 1局の手数は、標準ルールの最大60手より長いでしょうか、短いでしょうか。

予想を立てるヒントとして、石の総数の動きを式にしてみてください。ある手で相手の石を k 個取り除いたとします。置いた石が1個増え、k 個減るので、盤上の石の総数は「1 − k」だけ変わります。標準ルールでは、挟んだ石が消えずに色が変わるだけなので、総数は必ず1個ずつ増えます。この違いが、盤の埋まり方に何をもたらすか。結論は書きません。手元で式を追って確かめてください。

手順:二つの方法で対局を集める

準備するもの

  • ブラウザとテキストエディタ(コード実験用)
  • 実物のオセロ盤と石、取り除いた石を入れる小皿(手作業用)
  • 記録用の紙か表計算ソフト
  • 任意:標準ルールの対局感覚を確かめるための「潮目のオセロ」(後述)

手順A:コードで大量に対局する

次のコードを index.html として保存し、ブラウザで開くと、標準ルールと消滅ルールをそれぞれ1000局ずつ自動で打ち、結果を1行ずつ表示します。双方が合法手の中からランダムに選ぶだけの打ち手で、戦略はありません。外部ライブラリは使わず、1つのファイルで動きます。

html
<pre id="o"></pre>
<script>
const D=[[-1,-1],[-1,0],[-1,1],[0,-1],[0,1],[1,-1],[1,0],[1,1]];
const ok=(y,x)=>y>=0&&y<8&&x>=0&&x<8;
function flips(b,r,c,p){
  if(b[r][c])return[];
  const all=[];
  for(const[dr,dc]of D){
    const line=[];let y=r+dr,x=c+dc;
    while(ok(y,x)&&b[y][x]===-p){line.push([y,x]);y+=dr;x+=dc;}
    if(line.length&&ok(y,x)&&b[y][x]===p)all.push(...line);
  }
  return all;
}
function game(mode){
  const b=Array.from({length:8},()=>Array(8).fill(0));
  b[3][3]=b[4][4]=-1;b[3][4]=b[4][3]=1;
  let p=1,passes=0,turns=0;
  while(passes<2&&turns<500){
    const moves=[];
    for(let r=0;r<8;r++)for(let c=0;c<8;c++){
      const f=flips(b,r,c,p);if(f.length)moves.push([r,c,f]);
    }
    if(!moves.length){passes++;p=-p;continue;}
    passes=0;turns++;
    const[r,c,f]=moves[Math.floor(Math.random()*moves.length)];
    b[r][c]=p;
    for(const[y,x]of f)b[y][x]=mode==="flip"?p:0;
    p=-p;
  }
  const n=v=>b.flat().filter(q=>q===v).length;
  return{turns,bl:n(1),wh:n(-1),capped:passes<2};
}
function run(mode,N){
  let t=0,s=0,cap=0,bw=0,ww=0,gone=0;
  for(let i=0;i<N;i++){
    const g=game(mode);t+=g.turns;s+=g.bl+g.wh;
    if(g.capped)cap++;if(g.bl>g.wh)bw++;if(g.wh>g.bl)ww++;
    if(!g.bl||!g.wh)gone++;
  }
  const f=x=>(x/N).toFixed(1);
  return mode+" 手数"+f(t)+" 石"+f(s)+" 上限"+cap+" 黒勝"+bw+" 白勝"+ww+" 全滅"+gone;
}
const N=1000;
document.getElementById("o").textContent=run("flip",N)+"\n"+run("vanish",N);
</script>

表示される項目の意味は次のとおりです。

  • 手数:パスを除いた、石を置いた回数の平均です。
  • 石:終局時に盤にある石の合計の平均です。
  • 上限:500手に達して打ち切られた局の数です。終局ではなく、打ち切りです。
  • 黒勝・白勝:終局時の石の数で決めた勝敗の局数です。残りは引き分けです。
  • 全滅:終局時にどちらかの色の石が0個だった局の数です。

ページを開き直すたびに乱数が変わるので、少なくとも3回読み込み、そのたびに1行ずつ書き写してください。

手順B:実物の盤で10局打つ

コードの数字は、人の打ち方を反映していません。そこで、実物の盤で消滅ルールの対局を行います。二人で10局が目安です。先手と後手は5局ずつ入れ替えます。

  • 取り除いた石は盤から出し、小皿に置きます。数え間違いを防ぐためです。
  • 1局の手数に上限を決めておきます。たとえば両者合わせて100手です。終わらない対局を止めるための保険で、上限に達した局は「打ち切り」と記録します。
  • 一人で行うなら、白黒の両側を交互に考えて打ちます。ただし、片側に肩入れして打ちやすくなる点が、後で述べる誤りの原因になります。

標準ルールの感覚を確かめたいときは、「潮目のオセロ」のひとり対局が使えます。返る石のプレビューや理由付きヒントがあり、どの石が挟まれるかを目で追う練習になります。ただし、この作品にルールを変える機能はありません。消滅ルールは、あくまで盤とコードで行います。

記録の取り方

記録は、次の表を1局につき1行で埋めます。コード側は平均値を3回分、手作業は10局分です。

  • ルール、記録する内容:標準か消滅か
  • 方法、記録する内容:コードか手作業か
  • 手数、記録する内容:パスを除く、石を置いた回数
  • パス回数、記録する内容:局全体で何回パスがあったか
  • 終局の理由、記録する内容:全滅/両者置けず/盤が埋まった/打ち切り
  • 黒石・白石、記録する内容:終局時の石の数
  • 勝敗、記録する内容:黒勝・白勝・引き分け

手作業の10局には、もう一つ自由記述の欄を設けます。「石が最後にいくつ残ったか」「最後の数手はどんな動きだったか」を一行で書いてください。数字では見えない終局の形が、そこに残ります。

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

最初にコードの検算をする

標準ルール(flip)の行を見ます。手数が60を超えていたら、コードの打ち間違いです。標準ルールでは石を置くたびに空きマスが1つ減るので、パスを除いた手数は60を超えられません。コードを貼り直し、特に mode==="flip"?p:0 の行が元のとおりか確かめてください。この検算に通ってから、消滅ルールの行を読みます。

予想と照らし合わせる

予想の4問に、数字で答えを出します。読み方の目安は次のとおりです。

  • 石の平均が標準の行と大きく違う:終局時の盤の形が、そもそも別物になっています。予想1の答えは、石の数そのものから読めます。
  • 「全滅」が多い:終局の主役は、盤の埋まりではなく、石が尽きることです。予想2の「全滅」に近い答えです。
  • 「全滅」が少なく、手数も短い:両者が置けなくなって止まる局が中心です。パス回数の欄を併せて見て、どちらの色が先に置けなくなるかを調べてください。
  • 「上限」が0でない:打ち切られた局があります。終わらない局面が現れうるという意味です。打ち切りは終局ではないので、勝敗の集計には混ぜず、別に数えます。
  • 黒勝と白勝の差が標準より開いた:先手の影響が変わった可能性があります。3回の間に差が入れ替わるなら、偏りとまでは言えません。

起こりやすい誤り

  • 1回の読み込みで結論を出す:ランダム対局は毎回揺れます。3回の数字がそろってはじめて、傾向として読みます。揺れが大きければ、N を増やして再実行します。
  • ランダム対局を人の実力として読む:コードの打ち手は戦略を持ちません。人の打ち方との差は、手作業の10局と並べて初めて見えます。両者が食い違ったら、どちらかが間違いなのではなく、別の問いに答えているのだと読みます。
  • 端の石まで取り除く:消えるのは「挟まれた石」だけで、挟んだ側の端の石は残ります。手作業で最も間違いやすい点です。
  • 複数方向の同時挟みを片方向しか処理しない:置いたマスから見て、複数の方向で挟めた場合は、すべて取り除きます。
  • 打ち切りを終局に混ぜる:記録欄の「終局の理由」を分けておきます。
  • 手作業で片側に肩入れする:一人で打つと、無意識に黒を有利にしやすくなります。気づいたら、先手を入れ替えて記録します。

次の行動

まず予想の4問を紙に書き、そのあとでコードを3回走らせて、標準ルールの検算を済ませてください。次に、手作業で消滅ルールを10局打ち、予想と見比べます。コードを index.html のまま改造し、消えるのを「挟まれた石のうち一個だけ」に変えるなど、ルールをもう一つだけ動かすと、次の実験になります。形になったら、アソバースにHTMLとして投稿する手もあります。ZIPやHTMLの直接アップロードに対応していて、直下の index.html が入口になります。公開にはメールアドレスの確認が必要です。