囲碁のセキを、プログラムで判定する
公開日:2026年10月24日
終局した盤を開くと、黒の3子に×が付いていました。その石は、死んでいません。
囲碁アプリ「おるふぇ碁」で、終局後の盤に、死んでいると思われる石へ自動で×を付ける機能を作っていました。中盤にポツンと残った石なら簡単です。ところが「セキ」の形になると、アプリは平然と片方を死に石と決めて、点数を狂わせました。囲碁を打つ人なら一目で分かる誤りを、プログラムはなぜ見抜けないのか。その試行錯誤の記録です。
セキとは
囲碁の用語を、必要なぶんだけ説明します。石は、縦横に隣り合う空点(呼吸点)がなくなると取られます。そして、眼(自分の石で囲まれた空点)を2つ作れば、石は取られません。
「セキ」は、黒と白が、お互いに相手を取れないまま、盤上に残る形です。図1を見てください。
印の2点は、黒にも白にも隣り合っています。黒がここに打つと、黒の呼吸点は残り1つになって、白に取られます(図2)。白が打っても、同じことが起きます。つまり、どちらも打てません。そうなると、この2点は、どちらの地にもなりません。数えるときは、0目です。
終局のあとの数え方
おるふぇ碁では、双方が続けてパスをすると整地に入ります。日本ルールでは、死んでいる石は打って取らずに、そのまま取り上げます。おるふぇ碁は、AIとの対局しか想定していないので、「死んだ石の確認を、プレイヤーに任せる方式」を選びました。得点は、地 + アゲハマ + 死に石で、コミは白に加えます。
ここで、画面を開いた時点で、死んでいると思われる石にあらかじめ×を付けておく機能を足しました。そのために、アプリは石の生き死にと、セキを見分ける必要があります。
眼を、どう決めるか
片目しかない塊の空点を、普通に地として数えると、点数がずれます。そこで、次の考え方にしました。
- 2眼を作れず、しかも相手の石と呼吸点を共有している塊の、眼の空点は0目(セキの形)。
- どちらの色にも接する空の領域は、元から0目。
- それ以外の空点は、地として数える。
空点が「眼」かどうかは、次の条件で決めました。盤の外は、自分の石として数えます。
| 空点の位置 | 眼になる条件 |
|---|---|
| 辺と隅でない空点 | 上下左右の4方向がすべて自分、斜めの4方向のうち3方向以上が自分 |
| 辺と隅 | 8方向すべてが自分 |
1つ目の「2眼を作れない」は、この条件で判定します。ただし、相手が眼を潰しに来る手までは読みません。守る側が先に打たないと2眼にならない形でも、「2眼を作れる」と判定します。その場合、本当はセキなのに、3つ目のとおり、地として数えてしまいます。この間違いは、セキを地として数える方向にしか起きないので、プレイヤーが空点をタップして、地と0目を切り替えられるようにしました。
途中で、Claudeから、「辺と隅の扱いで誤る形が、あるはずだ」という指摘がありました。私が「そんな例はないと思う」と例を求めたところ、辺と隅の偏りで誤る形は、死に石が残っている場合に限られると分かり、Claudeはその指摘を取り下げました。
最初の設計は、3つのルール
出発点は、「生きるには、最低6個の石が要る」という観察です。辺に2眼を作る最小の形が6個なので、盤の真ん中にポツンとある5個以下の石は、空点がいくらあっても、相手の生き石に囲まれていれば、死んでいると見てよい、と考えました。設計は、次の3つのルールにしました。
- ① 先に、塊ごとに生き死にを判定して、死に判定の塊に×を付ける。
- ② 死に判定の塊が、相手の死に判定の塊に接しているとき、×を外す(お互いに死んでいる塊が接しているのは、セキの形だから)。
- ③ 生き判定でも、石が5個以下の塊には×を付ける。
実装では、Claudeが、この3つのルールに、さらに2つのルールを足していました。1つは「周回する」(×の石を取り除いて、判定し直す。最大6周)、もう1つは「壁の中の死んだ小さな石を、先に取り除く」です。Claudeの説明では、相手の壁の中に死んだ石が入ると、壁が眼を持てず、眼0と判定されて、お互いに死んだ扱いで×が外れてしまうためだそうです。私には、「①で先に×を付けて、あとで②で復活させる順なら、この2つのルールは要らないのでは」という疑問が残りました。
実際の盤面で、穴が見つかる
設計を実装したあと、実際の9路盤のセキの盤面を、私が見せるたびに、穴が見つかりました。3つの盤面を、順に見ます。
1つ目: 黒の3子に×が付く
Claudeが足した「壁の中の死んだ小さな石を、先に取り除く」ルールは、この形ではうまくいかないのではないか、と私は考えました。そこで、実際に盤面を作ってみると、やはり、右上の隅の黒3子(H1、H2、J2)に×が付いてしまいました。この形は一眼のセキです。原因は、そのルールの条件が足りなかったことです。黒の3子は、石が5個以下で、白の大きな塊に接しているので、J1に眼の空間を持っていても、先に×を付けられてしまったのです。Claudeが、「その塊に自分の眼の空間がない」ときだけ働くように条件を足して、直しました。
2つ目: セキの中の白石は、取るべきか
この盤面は、囲碁のルールの面で、とても興味深いものでした。×の判定の話は少し後回しにして、先にルールの話をします。
左上の黒の中に、白石が1子(A2)残っています。呼吸点はB2の1つだけで、黒がB2に打てば取れます。さて、この白石を取らずに終局するのと、終局の前に取るのとでは、結果が変わるのでしょうか。
セキの中のこの白石を、終局の前に取るかどうかで、勝敗が逆になります。
- 取らずに終局すると、コミ6.5で、白の半目勝ち。
- 黒が終局の前にB2で打って取ってから終局すると、黒の半目勝ち。
この白石は、終局後には取り上げられません。セキの石は、盤上に残ったまま、数えないからです。一方、終局の前に打って取った石は、アゲハマとして数えます。同じ盤面なのに、終局前に1手打つだけで、負けが勝ちに変わります。
根拠は、日本囲碁規約の第十条第1項です。終局の合意のあとに取り上げるのは「地の中の相手方の死に石」だけと決まっています。B2は、黒の活き石と白の死に石に囲まれた空点なので、規約では「駄目」で、地ではありません。だから、この白石は、取り上げられません。
さて、この白石に×を付けるかどうかが問題になりました。付けても点数は変わりませんが、「死んでいて、黒の得になる」ように見えてしまいます。実際には、取らないかぎり、黒の得にはなりません。そこで、アゲハマにならない石には、×を付けないことにしました。
3つ目: 隅のセキに、誤って×が付く
右上の隅で、黒の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はすぐには教えてくれませんでした。そのおかげで、囲碁のルールに、少し詳しくなりました。