囲碁のセキを、プログラムで判定する

公開日:2026年10月24日

終局した盤を開くと、黒の3子に×が付いていました。その石は、死んでいません。

囲碁アプリ「おるふぇ碁」で、終局後の盤に、死んでいると思われる石へ自動で×を付ける機能を作っていました。中盤にポツンと残った石なら簡単です。ところが「セキ」の形になると、アプリは平然と片方を死に石と決めて、点数を狂わせました。囲碁を打つ人なら一目で分かる誤りを、プログラムはなぜ見抜けないのか。その試行錯誤の記録です。

セキとは

囲碁の用語を、必要なぶんだけ説明します。石は、縦横に隣り合う空点(呼吸点)がなくなると取られます。そして、眼(自分の石で囲まれた空点)を2つ作れば、石は取られません。

「セキ」は、黒と白が、お互いに相手を取れないまま、盤上に残る形です。図1を見てください。

A5B4C3D2E1
図1 黒12子、白11子。空いているのは印の2点だけ。
A5B4C3D2E1
図2 黒がC3に打つと、黒の呼吸点はC2の1つだけになる。

印の2点は、黒にも白にも隣り合っています。黒がここに打つと、黒の呼吸点は残り1つになって、白に取られます(図2)。白が打っても、同じことが起きます。つまり、どちらも打てません。そうなると、この2点は、どちらの地にもなりません。数えるときは、0目です。

終局のあとの数え方

おるふぇ碁では、双方が続けてパスをすると整地に入ります。日本ルールでは、死んでいる石は打って取らずに、そのまま取り上げます。おるふぇ碁は、AIとの対局しか想定していないので、「死んだ石の確認を、プレイヤーに任せる方式」を選びました。得点は、地 + アゲハマ + 死に石で、コミは白に加えます。

ここで、画面を開いた時点で、死んでいると思われる石にあらかじめ×を付けておく機能を足しました。そのために、アプリは石の生き死にと、セキを見分ける必要があります。

眼を、どう決めるか

片目しかない塊の空点を、普通に地として数えると、点数がずれます。そこで、次の考え方にしました。

  1. 2眼を作れず、しかも相手の石と呼吸点を共有している塊の、眼の空点は0目(セキの形)。
  2. どちらの色にも接する空の領域は、元から0目。
  3. それ以外の空点は、地として数える。

空点が「眼」かどうかは、次の条件で決めました。盤の外は、自分の石として数えます。

空点の位置眼になる条件
辺と隅でない空点上下左右の4方向がすべて自分、斜めの4方向のうち3方向以上が自分
辺と隅8方向すべてが自分

1つ目の「2眼を作れない」は、この条件で判定します。ただし、相手が眼を潰しに来る手までは読みません。守る側が先に打たないと2眼にならない形でも、「2眼を作れる」と判定します。その場合、本当はセキなのに、3つ目のとおり、地として数えてしまいます。この間違いは、セキを地として数える方向にしか起きないので、プレイヤーが空点をタップして、地と0目を切り替えられるようにしました。

途中で、Claudeから、「辺と隅の扱いで誤る形が、あるはずだ」という指摘がありました。私が「そんな例はないと思う」と例を求めたところ、辺と隅の偏りで誤る形は、死に石が残っている場合に限られると分かり、Claudeはその指摘を取り下げました。

最初の設計は、3つのルール

出発点は、「生きるには、最低6個の石が要る」という観察です。辺に2眼を作る最小の形が6個なので、盤の真ん中にポツンとある5個以下の石は、空点がいくらあっても、相手の生き石に囲まれていれば、死んでいると見てよい、と考えました。設計は、次の3つのルールにしました。

実装では、Claudeが、この3つのルールに、さらに2つのルールを足していました。1つは「周回する」(×の石を取り除いて、判定し直す。最大6周)、もう1つは「壁の中の死んだ小さな石を、先に取り除く」です。Claudeの説明では、相手の壁の中に死んだ石が入ると、壁が眼を持てず、眼0と判定されて、お互いに死んだ扱いで×が外れてしまうためだそうです。私には、「①で先に×を付けて、あとで②で復活させる順なら、この2つのルールは要らないのでは」という疑問が残りました。

実際の盤面で、穴が見つかる

設計を実装したあと、実際の9路盤のセキの盤面を、私が見せるたびに、穴が見つかりました。3つの盤面を、順に見ます。

1つ目: 黒の3子に×が付く

A9B8C7D6E5F4G3H2J1
図3 右上の隅の黒3子(輪を付けた石)。空いているのはJ1とJ3で、J1は黒の眼になっている。

Claudeが足した「壁の中の死んだ小さな石を、先に取り除く」ルールは、この形ではうまくいかないのではないか、と私は考えました。そこで、実際に盤面を作ってみると、やはり、右上の隅の黒3子(H1、H2、J2)に×が付いてしまいました。この形は一眼のセキです。原因は、そのルールの条件が足りなかったことです。黒の3子は、石が5個以下で、白の大きな塊に接しているので、J1に眼の空間を持っていても、先に×を付けられてしまったのです。Claudeが、「その塊に自分の眼の空間がない」ときだけ働くように条件を足して、直しました。

2つ目: セキの中の白石は、取るべきか

この盤面は、囲碁のルールの面で、とても興味深いものでした。×の判定の話は少し後回しにして、先にルールの話をします。

A9B8C7D6E5F4G3H2J1
図4 黒の中に残った白石(輪を付けた石)。呼吸点はB2の1つだけ。

左上の黒の中に、白石が1子(A2)残っています。呼吸点はB2の1つだけで、黒がB2に打てば取れます。さて、この白石を取らずに終局するのと、終局の前に取るのとでは、結果が変わるのでしょうか。

セキの中のこの白石を、終局の前に取るかどうかで、勝敗が逆になります。

  • 取らずに終局すると、コミ6.5で、白の半目勝ち。
  • 黒が終局の前にB2で打って取ってから終局すると、黒の半目勝ち。

この白石は、終局後には取り上げられません。セキの石は、盤上に残ったまま、数えないからです。一方、終局の前に打って取った石は、アゲハマとして数えます。同じ盤面なのに、終局前に1手打つだけで、負けが勝ちに変わります。

根拠は、日本囲碁規約の第十条第1項です。終局の合意のあとに取り上げるのは「地の中の相手方の死に石」だけと決まっています。B2は、黒の活き石と白の死に石に囲まれた空点なので、規約では「駄目」で、地ではありません。だから、この白石は、取り上げられません。

さて、この白石に×を付けるかどうかが問題になりました。付けても点数は変わりませんが、「死んでいて、黒の得になる」ように見えてしまいます。実際には、取らないかぎり、黒の得にはなりません。そこで、アゲハマにならない石には、×を付けないことにしました。

3つ目: 隅のセキに、誤って×が付く

A9B8C7D6E5F4G3H2J1
図5 右上の隅。輪を付けた黒の2子(H2、J1)と、白7子が、H1とJ2の2点を共有している。

右上の隅で、黒のH2とJ1の2子と、白の7子の形です。H1とJ2の2点を、お互いに共有しています。「壁の中の死んだ小さな石を、先に取り除く」ルールで、黒の2子に先に×が付きました。その2子を取り除いて数えると、H1とJ2が白の地に見えてしまい、×が外れませんでした。そこでClaudeが、「お互いの呼吸点がすべて共通のときは、先に×を付けない」という条件を足して、この場面をやり過ごしました(後に、このルールも要らなくなります)。この形では、どちらもH1とJ2の2点しか呼吸点がなく、どちらかがそこを埋めると、自分がアタリになります。相手を取れないので、セキとして扱います。

規約の「死活確認例」で確かめる

実際の盤面を探して回るのは、きりがありません。そこで、日本囲碁規約にある「死活確認例」を、テストに使えないかと考えました。規約の文には、「この形で中断したときの判定」が書いてあり、正解が付いています。

図は画像なので、Claudeが画素を読み取って盤面に起こし、判定文の石の数と、読み取った塊の大きさを見比べて、確かめました。

劫を終局前に解消しておくパターンと、判定文の石の数から、どの塊か特定しきれない例は、Claudeがテストから外しました。入れたのは、例1、2、6、10、25、11の上の図、7-1(隅の曲がり四目)です。入れた例の期待値も、Claudeが判定文から決めました。AIはよく仕事をしてくれます。

隅の曲がり四目は、形で決める

規約の例7-1では、黒の隅の3子が活き石、囲まれた白の7子が死に石です。ところが、テストを走らせると、実装は逆に、黒の3子に×が付き、白には付きませんでした。

眼の判定をまた直すより、規約の図の形をそのまま使うほうが確実だと考えて、私が「隅の曲がり四目のパターンは1つしかないよね」と提案しました。この形のパターンは、4つの隅、斜めの折り返し、黒白の入れ替えを合わせて、16通りです。盤と照合して、形が合うときだけ、隅の3子を囲んでいる白石に×を付け、隅の3子は活きとして扱います。これで、この例は、正しく白の7子に×が付くようになりました。

判定を、1回にする

結局、「周回する」と「壁の中の死んだ石を先に取り除く」ルールは、要らなくなりました。隅のセキのためにClaudeが足した「呼吸点がすべて共通のときは、先に×を付けない」条件も、同じように要らなくなりました。きっかけは、私が「そもそも、何のために周回するのか」と聞いたことです。Claudeの答えは、こうでした。②のルールで×が付かなくなった石が眼の中に残ると、その空間は眼として数えられません。そのため、×の石を先に取り除いて、判定し直す必要があったのです。そこで私が、「自分の塊の眼数より少ない、相手の死に石を、空点として数えて眼を判定する」方式を提案しました。Claudeも「この判定なら、周回をなくせます」と理解を示し、判定は1回になり、壁の中の死んだ1子の問題も、隅のセキも、同じテストが全部通りました。

そのあとで

ここまで作っても、問題が残っていました。6個以上の大きな死に石が、「生き」と判定されてしまうと、×が付きません。相手が眼を潰しに来る手まで読まない、形のルールの限界です。何かいい方法はないかとClaudeに聞くと、AIの「所有権(地の見込み)」から、死に石を出せると教わりました。KataGoをつなげば、済む話でした。最初からそう言ってほしかった……。

Claudeには、今までの苦労は無駄ではないと慰められました。実際、自前の判定は、使わなくなったわけではありません。今のアプリでは、解析がオンのときは、KataGoの判定を使います。形のルールは、解析エンジンを止めているときや、判定が出なかったとき、判定を待たずに進むときの代わりに使います。KataGoの判定は、石ごとの地の見込みが、一定の割合(60%)以上かどうかで決まります。日本ルールで取り上げられない石(セキの中の石など)は、そのままだと×が付いてしまうことがあるので、「アゲハマにならない石には、×を付けない」処理を、KataGoの結果にも通しています。得点の計算と、規約の例で確かめたテストは、KataGoに切り替えても、そのまま使えます。

AIに聞けば一瞬で出る死に石の候補を使う方法を、AIはすぐには教えてくれませんでした。そのおかげで、囲碁のルールに、少し詳しくなりました。

おるふぇ碁を遊ぶ

← Orfevre Lab トップへ戻る