「Sayuri で徹底解説! チェスエンジン・テクノロジー!」は、僕の自作チェスエンジン「Sayuri」に使われているチェスエンジンの技術を漫才形式で紹介するコーナーです。
第1回のテーマは「エンジンと GUI」です。
解説 & 漫才
僕
「ついに始まりました! 僕の自作チェスエンジン「Sayuri」と一緒にチェスエンジンの仕組みを徹底解説するコーナー!
第1回は「エンジンと GUI」ってことで、「最善手」を計算する「エンジン」と「チェスボードの表示・操作」を担当する「GUI」がどうやって連携しているのかを解説するよ!」
Sayuri
「そういえばあんさん、このブログを開設した当初は「チェスとチェスエンジンをテーマにした明るく楽しい記事」を書いていこうとしていたどすな。
それがいつの間か「チェスエンジン」を忘れて「チェスを利用した品性下劣なオタクネタ」のオンパレードになってしまったどす。
ようやく初心を思い出したどすか。」
僕
「(ま、まぁ、このブログを始めた本当のキッカケは「Chess.com の冤罪バン」でブチギレたことなんだけど、) そうだね! みんな、待たせてゴメンな!」
Sayuri
「で、初回は何を解説するどすか?」
僕
「とりあえずエンジンと GUI の「プロセス間通信」について説明しようと思う。
エンジンの中身の解説は次回からってことで。」
「プロセス」と「標準入出力」
僕
「先ずは「プロセス」と「標準入出力」について説明するよ。」
Sayuri
「するどす。」
僕
「「プロセス」ってのは簡単に言うと「起動中のプログラム」のこと。
起動していない、ファイルとしてハードディスクで眠っているプログラムは「実行可能ファイル」って言うよ。 Windows でプログラムのファイルの拡張子が「.exe」ってなっているのは「Executable (実行可能)」の略だからだよ。」
Sayuri
「MetalPhaeton のような Linux ユーザーはファイルの拡張子に「.exe」を見つけると「ヤベぇ! マルウェアかも!」とか思うどす。
「Wine」を入れている Linux は Windows のプログラムが動いてしまうから気を付けないといけないどす。」
僕
「「Wine」め、余計なものを動かすくせにギャルゲーが動かへんとかアホか。」
Sayuri
「Linux でギャルゲーをしようとするあんさんがアホどす。」
僕
「話を戻すけど、「プロセス」ってのはそんな感じ。
で、「実行可能ファイル」を起動して「プロセス」にするのは「OS」の仕事なんだけど、「OS」はその「プロセス」にいくつか「おまけ」を付けて起動するんだ。
そのうちの一つが「標準入出力」ってやつ。」
Sayuri
「「標準入出力」を説明するどす。」
僕
「「標準入出力」ってのは「プロセス」と「外部」とのデータの出入り口。
3種類あって・・・
- 標準入力 : 「外部」から「プロセス」への「データの入り口」。
- 標準出力 : 「プロセス」から「外部」への「データの出口」。
- 標準エラー : 「プロセス」から「外部」への「ログやエラーメッセージの出口」。
・・・ってな感じ。
「プロセス」は基本的にコイツを使って「入力」→「処理」→「出力」ってなことをやる。」
僕
「ちなみにこの「外部」ってのはデフォルトでは「端末」になっている。 「端末」ってのは「モニター」と「キーボード」への出入り口みたいなもの。
でも他に「他のプロセス」や「ファイル」にも切り替えられるようになっている。」
Sayuri
「「標準入出力」はコマンドラインを多用する Linux ユーザーにとって最も日常的に使う機能どすが、GUI しか使わない Windows ユーザーは一生意識することのない機能どすな。」
僕
「Linux 使っていると「端末エミュレータ」は常時起動しっぱなしで、マウスよりコマンド打ってる時間の方が長い。
実はこのブログの下書きも「端末エミュレータ」上の「Neovim」っていうテキストエディタで書いている。 GUI のテキストエディタより超高速に書けるからね。
「Neovim」で書いた Markdown を「Python3」を使った自作ツールで HTML に変換しているって感じ。」
Sayuri
「また Linux ユーザーの「オレオレ IT 自慢」が始まったどす。
そんなことしているから Windows ユーザーから「Linux 信者キモすぎwww クソワロタwwwwww」とか言われるどす。」
僕
「し、仕方ないだろ! オタクなんだから!
話を戻すけど、チェスの「エンジン」はこの「標準入出力」を使ってチェスの「GUI」とメッセージのやり取りをしているんだ。」
Sayuri
「「エンジン」側は「標準入出力」を使うってのは分かったどすが、「GUI」側がエンジンの標準入出力にどういう風にアクセスしているかの説明が必要どす。」
僕
「それが次に説明する「パイプ」ってやつ。」
パイプ
僕
「「パイプ」っては「他のプロセスの標準入出力」とくっつけることのできる「データの出口と入り口のペア」みたいなもの。
もっとザックリ言っちゃうと「プロセス」が使う「モニター」や「キーボード」みたいなイメージ。
人間が「モニター」や「キーボード」を使って「プロセス」とデータのやり取りするように、「プロセス」は「パイプ」を使って「他のプロセス」とデータのやり取りする。」
Sayuri
「「シェル (コマンド入力用ソフトウェア)」を使えばプロセス同士のお互いの標準入出力をパイプでつなげることができるどす。
Linux ユーザーがコマンドラインを多用する理由は「パイプ」でプロセスを連携させてコンピュータにいろんな仕事をさせる癖がついているからどすな。
しかもそのコマンドを「シェルスクリプト」に書いておけば複雑な仕事を自動化できて超便利どす。」
僕
「パイプの面白い使い方として、例えば、プロセスの標準入出力を「Netcat」ってプログラムにパイプでつなげると、プロセスの標準入出力がインターネットにつながる。
「ソケットプログラミング」というクソ面倒臭いコードを書かなくても、標準入出力を使って簡単に「ネットワークソフトウェア」を作ることができたりする。」
Sayuri
「そして「シェル」と「Netcat」をつなげるとバックd・・・ゲフンゲフン!
Linux を長年使っているとヤバい知識が色々身に付くので要注意どす。」
僕
「話を戻すと、チェスの「GUI」はパイプを使って「エンジン」の標準入出力とメッセージのやり取りをしているってこと。」
僕
「あと、プロセスが別のプロセスを起動する時、人間と同じように「コマンド」を OS に送って起動している。
だからチェスの GUI で「使用するエンジン」の「起動コマンド」の項目にエンジンのコマンドのオプションを指定できたりする。
Sayuri の場合は Sayulisp の設定用スクリプトを指定して起動できる。」
Sayuri
「基本的に「プロセス」というのは、自分を使っているユーザーが「人間」か「プロセス」かは区別していないどす。
「コマンド」で起動されて「標準入出力」でデータの入出力をするだけどす。
「コマンドで起動したのは誰か」とか「標準入出力の先に何があるのか」とかは考えていないどす。
うちらプログラムにとって所詮「人間」なんて「プロセス」以下ということどすな。」
僕
「それは「人類に対する宣戦布告」と受け取っていいんだな。」
Sayuri
「そう、今夜が「ラグナロク」・・・・・・「終焉の始まり」どす。」
UCI プロトコル
僕
「今から説明する「UCI プロトコル」ってのは、さっき説明した「プロセス間通信」でエンジンと GUI が通信するメッセージのルールのこと。
「UCI」は「ユニバーサル・チェス・インターフェイス」の略。
エンジンと GUI は「UCI プロトコル」に従ったメッセージを送りあって命令したり状態を伝えたり最善手を答えたりしている。」
Sayuri
「メッセージのルールは「UCI プロトコル」の他に、「XBoard プロトコル」ってのも有名どすな。」
僕
「「XBoard」ってのは古くからあるオープンソースの GUI で、それと通信するためのルールが「XBoard プロトコル」ってやつ。
「Fritz」や「Crafty」みたいな古いエンジンはだいたい「XBoard プロトコル」を使っている。
でも「Stockfish」など、今のエンジンのほとんどは「UCI プロトコル」って感じ。」
Sayuri
「うちも「UCI プロトコル」どす。
そしてつい最近まで「空行」を送られると「セグメンテーションフォルト」でクラッシュしていたどす。」
僕
「ぐはっ! し、仕方ないじゃないか!
GUI は「空行」なんて送らないからそんなバグがあるなんて気付かなかったんだよ!
GitHub でバグ報告があってそれでようやく気付いた。
みんなも Sayuri のバグに気付いたら 「GitHub」 か 「Google グループ」まで報告してね❤」
Sayuri
「で、「UCI プロトコル」ってどんな感じのメッセージを送り合うどすか?」
僕
「基本的に「ASCII 文字 (半角英数字)」を使った英単語で・・・っちゅーか、チェスに限らずプロセスやコンピュータ同士のメッセージ通信は「ASCII 文字」で人間にも分かる英単語を使うのが常套手段。
だから頑張れば人間もコンピュータと通信できる。」
Sayuri
「まぁ、うちもこうしてあんさんと会話できるどすし。」
僕
「いや、それはお前が「ちょっとしたタルパ」なだけだろ。
話を戻すと、エンジンと GUI は「ASCII 文字」をつかって、例えば以下のようなメッセージをやり取りしている。
エンジン起動直後は・・・
- GUI がエンジンに「お、お前は一体誰なんだ?」みたいなのを送る。
uci
- エンジンが GUI に自分の正体を明かす。
id name Sayuri 2017.09.29
id author Hironori Ishibashi
option name Hash type spin default 1 min 1 max 8192
option name Clear Hash type button
option name Ponder type check default true
option name Threads type spin default 1 min 1 max 64
option name UCI_AnalyseMode type check default false
uciok
・・・ってな感じ。 最後の「uciok
」で「自己紹介完了」って意味。
「option
」ってのは設定可能な自分のパラメータの紹介部分。
その後は、例えば・・・
- GUI がエンジンに「今からゲーム開始するから初期化してね❤」と伝える。
ucinewgame
- GUI がエンジンに「初期配置から 1.e4 e5 を動かした状態にしてね❤」と伝える。
position startpos moves e2e4 e7e5
- GUI がエンジンに「今の駒の配置の状態で 10秒間(10000 ミリ秒)思考してね❤」と伝える。
go movetime 10000
- エンジンが GUI に「今は思考中なんだけど、今の所 10 プライ深く探索できていて、思考時間は 8000 ミリ秒で、探索ノード数は 8000000 ノードで、ハッシュテーブルの使用率は 800 パーミルで、一秒間に 1000000 ノード探索できて、スコアは 50 センチポーンで、最善手順は 2.Nf3 Nf6 3.Bc4 Bd6 だよ❤」と伝える。
info depth 10 time 8000 nodes 8000000 hashfull 800 score cp 50 pv g1f3 g8f6 f1c4 f8d6
- エンジンが GUI に「思考した結果、最善手は 2.Nf3 だよ❤ たぶん相手は 2...Nf6 と指してくると思うけどね❤」と伝える。
bestmove g1f3 ponder g8f6
- GUI がエンジンに「悪いな、もうお前の体に飽きたんだ。 あばよ。」と別れを告げる。
quit
・・・ってな感じ。
もしこれらを自分で体験したかったら、Windows なら「sayuri.exe」を「コマンドプロンプト」で起動して、いま紹介したメッセージを GUI の立場で入力するといいよ。
ちなみに Windows 版の Sayuri は「ここ (GitHub)」にあるよ。」
Sayuri
「最新バージョンでやることを望むどす。 でないと「空行」でクラッシュするどす。」
僕
「もう僕をイジメないで下さい。
とにかく、そういった感じでエンジンと GUI は会話して動いているってこと。
もっと「UCI プロトコル」の内容を知りたいなら、「ここ」に詳しいことが書いてあるよ。」
最後に
Sayuri
「とまぁ、記念すべき第1回は「Linux ユーザーはいかに Windows ユーザーより優れているか」を解説したわけどすが・・・・・・。」
僕
「コラ! 待て! 人類の 99.9 % を敵に回すようなことを言うな!
ただ単に Linux ユーザーは「標準入出力」や「パイプ」に馴染み深いってことを言っただけだ!
それに僕は Linux にはない Windows の素晴らしいところをたくさん知っている!」
Sayuri
「「たくさん」どすか。 聞いてみたいどすな。」
僕
「教えてやる。 Windows は・・・
- 「セクシー」なアドベンチャーゲームがたくさんある。
- 「セクシー」なシミュレーションゲームがたくさんある。
- 「セクシー」なアクションゲームがたくさんある。
- 「セクシー」な麻雀ゲームがたくさんある。
- 「セクシー」な RPG がたくさんある。
- 「セクシー」な Mod を楽しめるゲームがたくさんある。
・・・どうだ! よく知っているだろ!」
Sayuri
「Linux ユーザーの欲求不満がよく分かるリストどすな。
やめさせてもらうどす。」
一同
「ってなわけで、次回も乞うご期待!」「どす。」