コンピュータ囲碁プログラム CGF碁盤プロトコル

  • 5
    いいね
  • 0
    コメント

書き終えた。ディープ・ラーニングで囲碁プログラムやりたいが 囲碁プログラム分かんね、という人は CgfGoBan から入るのがいいのではないか。
細かなことをいうと CGF碁盤のは、プロトコルじゃなくてAPIか。関数3つ覚えるだけ。

あ、そういえば UEC杯コンピュータ囲碁大会 では 別に通信なんかできなくたって 自分が作ったソフトの画面を見ながら D3 に打ちました、とか 対局者同士で人間が手入力して対局しても構わないんだった。 この記事が全て無駄になったが、いいだろう。コンピュータ将棋から入ってくると、コンピュータ囲碁もいろいろ新鮮だ。

今回の記事

なんかもう UEC杯が 今年で終わってしまうが、
コンピュータ囲碁プログラム で指し手をサーバーに送る部分を解説する。

通信用のソフトは CGF碁盤 を使うとする。

CgfGoBan : http://www.yss-aya.com/cgfgoban_j.html

別に わたしが書かなくても cgfthink.txt に書かれているんだが、みんな読まないだろう。

大まかに言うと、cgfgui_thinking関数に 引数8個を渡せば(受け取れば)いい。
あとは細かなものだ。
これでコンピュータ囲碁ソフトは 通信対戦ができる。

ちなみに 参加者はだいたい CGF碁盤とか使ってなくて プロトコル読んで 自力実装してくるようだ(>_<)

引数1 int init_board[]

囲碁盤なんだが、例えば19路盤とは こんな感じになっている。

  ABCDEFGHJKLMNOPQRST
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19

左上から右へ、右端から1段下の左端へ。ちょうど 日本人向きのテキストエディターと同じ座標 の方向だ。
ところで 囲碁盤、将棋盤、チェス盤 の座標の振り方を見比べると みな違って面白い。

19路盤の周りに  があると考えてくれ。

だから配列は 21 x 21 の部分を使うんだが、
実際には 縦21、横256 のテーブルだ。

init_board[ y * 256 + x ]

なんで こんなんなってるかというと、16進表記で 0xYYXX としたいわけだ。
例えば D3 に打ち込みたいときは 0x0304 となる。XYひっくり返ってしまうが……。

で、

  • 0 空いてる交点
  • 1 黒石
  • 2 白石
  • 3 枠

を入れる。将棋やチェスをやっていると、 えっ、これだけ!? と感動を覚えるところだ。実のところ プログラムは簡単だわ何をしたら勝てるのかそもそも囲碁が分からないわ適当に思考ルーチンを組んでも適当に動いてくれるわハンディキャップの付け方は数段階あるわ盤のサイズは変えれるわ、プログラミングの教材として面白いのではないか、中国ルールならば。日本ルールが実装できるなら、既に強豪ソフトだと思う。

引数2 int kifu[][3]

棋譜。とりあえず CgfGoBan では 2048手まで、としている。まあ、500手を超えるようなら 3コウ、4コウ、5コウ でもして永遠に石を取り合っているのだろう

だから配列のサイズは

kifu[2048][3]

なんだが、1手目を[0]として 2048手目が[2047]となる。
うしろの[3]は何か。

kifu[][0] これは、石を置いた座標を入れる。さっきの 0x0304 などが入る。パスは 0。
kifu[][1] これは、石の色が入る。黒が1、白が2 だった。
kifu[][2] これは、あってもなくてもいいんだが、考えていた秒が入る。1秒考えたら1。もう2017年では強豪ソフトは 0 秒で打ってしまうんだろうが、だいたい文化的なものに触れるとき、こういう淘汰されていく部分を見るのは 味わい深い。

簡単だろ。

引数3 int tesuu

手数。

0 から始まるので、tesuu が 0 の黒番は、0 手目が打たれた盤面(初期局面)を見ながら、これから 1 手目 を打つところだ。

だから白が 40手目を打ったら tesuu は 40 で、40手目が打たれた盤面を見ながら黒がこれから 41 手目を打つことになる。

理屈には適っているが 感覚的には すごく ややこしい。むしろ 棋譜配列のインデックス とでも思ってた方が楽か。

引数4 int black_turn

これから黒が石を置く(着手する)というときに 1 が入っている。そうでなければ 0。要するに黒番なら 真、白番なら 偽。

プログラムを組んでるときに 石の色と間違えて 白の手番こないな、とか思ったりするが 紛らわしいと思ったら 好きなように改造しよう。

引数5 int board_size

盤面のサイズ。19路盤(じゅーきゅーろばん)なら 19、9路盤なら 9。

もう分かってても 1手ごとに毎回 送られてくる。

引数6 double komi

囲碁は先手有利で、黒番と 白番では 黒が有利なので、白にハンディーキャップをあげようというもの。また、0.5 を付ける という工夫によって 互先(たがいせん。初期局面でハンディーキャップの黒石を置いてないやつ)では持碁(じご。引き分け)を 無くしている。置き碁(おきご。初期局面でハンディーキャップの黒石を置いてあるやつ)では持碁になる可能性がある。

コミはプレイヤーの実力差ではなく、先手後手の有利不利を埋めるためのハンディーキャップで、プロ棋士が年度の黒白の勝率を見て調整している。
特にルールは無いので、盤のサイズが変わっても 19路盤でも9路盤でも コミはそのまんまで構わない。

黒は有利を拡大して逃げ切ろうとするし、白は技芸を使って追い抜こう、というのが囲碁のゲーム性。

中国ルールでは コミ7.5、日本ルールでは コミ6.5。
囲碁盤の目の数は奇数で、黒手番の方が1手多く回ってくる理屈なので、単純に考えれば、理屈上黒は石1つ多く置ける。
中国ルールでは石、日本ルールでは囲んだスペースに着目して勝ち負けを決めるので、中国ルールでは黒に1石分有利に出てしまうのでコミが1多い。
つまり 中国ルールも 日本ルールもこれで コミでは大差ない。

ちょっと疲れたので 休憩してから続きを書く。

引数7 int endgameType

うむ……、インスタント・コーヒーがうまい……。お湯がコーヒーに変わるのだから コーヒーに変えない手はないぜ☆

ところで この引数は 終局処理フラグで 0~3 あるんだが、何なのかというと 囲碁は最後に この石は死んでる、この石は生きている、と判定するんだが 画面上の石に 〇× を付けたいよね という話しだ。空き地も、黒のか白のかダメなのか印を付けたい。

この cgfgui_thinking関数の引数にセットした内容は CgfGoBan という碁盤画面に送り返されるんだが、「おいコンピューター、石の生き死に返せよ」とかいうときに画面から思考エンジンに 1 とか返ってくるわけだ。

  • 0 (プレイ中)思考しろよ
  • 1 (終局処理)石の生き死に返せよ。空き地は黒、白、ダメのどれか返せよ
  • 2 (テスト用)局面評価を返せよ、?とか▲とか記号はいくつかあるんで使えよ
  • 3 (テスト用)マス目に数字を付けろよ、53手目の石とかよく使うだろ

というのが入って関数が呼び出される。

引数8 int endgameBoard[]

これがだから endgameType 引数に対応して 黒の〇とか 数字とかを入れる囲碁盤だ。

内容としては、

  • 0 石が活、あるいは分かんないとき
  • 1 石が死
  • 2 セキで活(未使用なので 0 を使うこと)
  • 3 空き地は白地
  • 4 空き地は黒地
  • 5 空き地はダメ

セキとは

セキというのは 石を置いたら取り返されるのが分かっているので置きたくないから白黒どっちもずっと空き地にしているところだ。

だから囲碁の石は実際のところ 活き石、死に石 の他に セキ石 というのがある。セキ石は 活き石 としてカウントしよう、ということだ。

中国ルールでは セキ(石を置きたくない空き地)が残ったら 黒のものか白のものか囲まれている4方向(または枠)を見て 黒だけに囲まれていれば黒のもの、白だけに囲まれていれば白のもの、どちらのものとも言えないものは 白黒半分ずつ点数を分ける。

このとき、どちらのものでもない2つの空き地が残っていたら、白1、黒1と仲良く折半。
どちらのものでもない3つの空き地が残っていたら 白1.5、黒1.5 と分けるわけだが、ここで 0.5 という端数が出てくる。これが原因で コミの0.5が無かった時代には 引き分け(持碁)があった。

日本ルールでは セキに絡んでいる石や空き地は数えない。冷たいものだ。

セキによって 中国ルールと日本ルールとで勝敗がひっくり返ることはある。

だから おおまかに言うと、囲碁のルールをしっかり取り入れていれば それはもう強豪ソフト、でも 強豪ソフトじゃなくても まあ だいたい石は置けるよね、勝敗の計算を間違ってたりするけど、ということだ。

勝敗の計算を間違っていて、コンピュータ・プログラミングと言えるのか?

という疑問が当然出てくると思うんだが、勝敗の計算ができるんならそれは囲碁が強いということだ というのが、どういうことか説明しよう。

盤上に最後の石まで置けば、石の数でも空き地の数でも、数えることはできるだろう。ひとーつ、ふたーつ、みっつ。オセロみたいにまだここからひっくり返せる という局面であれば、ひっくり返して、ひっくり返らなくなるまで石を置けば。

しかし そこまで打たなくても お互いが納得したところで対局終了するのが囲碁のゲーム性の1つだ。じゃあ、どこで納得するのか。強豪なら早く納得するだろうし、初心者なら打つところがなくなるまで打ってから最後に石なり空き地なりを数えるだろう。 な? ほら分かった。

だから 人間の実力以上のソフトなら 人間が対局終了した局面の勝敗の計算をできるだろうし、
人間の実力以下のソフトなら 人間が対局終了した局面をみても「まだまだこれからだろ!もっと指せ」と思う。別に人間に限らず 先に勝敗判定できる方は強い、その勝敗判定が合ってればの話しだが。勝敗が合ってるのか合ってないのかどう判定するのか、また堂々めぐりだが……。

理屈上、最後は 弱い方に付き合って、強い方は相手が納得するまで しばらく打ち続けることになると思うんだが、そんな経験したことないんで分からないぜ。勝敗が計算できるんなら強豪ソフト。 納得するまで説明は続く。

で、中国ルールは納得行かなかったら石が置けなくなるまで最後まで指してよい ので、コンピューター同士の対戦にはちょうどいい。しかし中国ルールでも納得したところで勝敗を計算しろと言われたら 問題点は同じだが。

囲碁おもろ☆

で 第8引数 なんだが、図形を置くというのもある。

  • 0: 何も描かない
  • 1: 三角形
  • 2: 四角
  • 3: 円
  • 4: ×
  • 5: "?"の記号
  • 6: 横線
  • 7: 縦線
  • 8: 斜め、左上から右下
  • 9: 斜め、左下から右上
  • 0x1000: 黒で描く(色指定)
  • 0x2000: 白で描く (色指定)

で、最後の色指定なんだが、

0x1000 | 1

と論理和を取れば 黒の三角 といった指定になる。

最後に 第8引数 は、数字を置くというのもある。

0 以外の正の整数が描画されるのかと思う。2桁の数字は置けるが、3桁はどうだったか。

返り値

返り値は 石を置く場所。0x0304 とか。パスなら 0。

これでもうだいたい CgfGoBan を使えるのではないか

盤さえ読めれば 数字を返せばいいだけだwww

あとは自殺手やコウなど ちょっとだけ 囲碁のルールを覚えればいける。

他に 初期化終了処理 のための関数があるが 説明は省略するwww

CgfGoBan をいじっている様子は 別のブログでも書いた。
http://kifuwarabe.warabenture.com/2015/12/14/%E3%80%90%E5%9B%B2%E7%A2%81%E3%80%91%E3%81%8D%E3%81%B5%E3%82%8F%E3%82%89%E3%81%B9%E3%81%8C%E3%83%9D%E3%83%8A%E3%83%B3%E3%82%B6%EF%BC%88%E3%81%AE%E5%BC%9F%EF%BC%89%E3%82%92%E5%80%92%E3%81%99%E2%98%86-3/

なんとなく分かるだろう。