今回は思考エンジンの仕組みからsfen文字列、”position”コマンドの説明まで。
思考エンジンの仕組み
思考エンジンは標準入出力経由で将棋所のようなGUIとやりとりをする。USIプロトコルについてもggrksである。
USI拡張コマンドについて
やねうら王miniでは、USIプロトコルに独自コマンドをいくつか追加してある。これらをUSI拡張コマンドと呼ぶ。
例えば、やねうら王miniの実行ファイルを起動して、
> eval
と入力してEnterキーを押すと、現在の局面の評価値が表示される。
※ 先頭の”>”は、ユーザーが入力したことを意味するためにつけているだけで、この文字は入力しないでください。
別の言い方をすれば評価値を計算するevaluate()関数(これが評価関数と呼ばれるもの)が呼び出される。
評価関数を呼び出せることがわかったので、あとは任意の局面をUSIコマンドで渡すことができれば、特定の局面に対する評価値を表示させて検算(?)するなどが出来るわけだ。
あるいは「ぼくのかんがえた最強の評価関数」に差し替えて、その評価関数に任意の局面を計算させることも出来るだろう。
それでは特定の局面を渡す方法を見ていこう。
盤面表示
USIコマンドとしてdと入力してEnterキーを押すと次のようになる。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
> d ^香^桂^銀^金^玉^金^銀^桂^香 □^飛 □ □ □ □ □^角 □ ^歩^歩^歩^歩^歩^歩^歩^歩^歩 □ □ □ □ □ □ □ □ □ □ □ □ □ □ □ □ □ □ □ □ □ □ □ □ □ □ □ 歩 歩 歩 歩 歩 歩 歩 歩 歩 □ 角 □ □ □ □ □ 飛 □ 香 桂 銀 金 玉 金 銀 桂 香 先手 手駒 : , 後手 手駒 : 手番 = 先手 sfen lnsgkgsnl/1r5b1/ppppppppp/9/9/9/PPPPPPPPP/1B5R1/LNSGKGSNL b - 1 |
※ このブログではWindows/Mac以外の環境では表示が崩れてしまっているかも知れないが、DOSプロンプトで等幅フォントが指定されていれば崩れないので安心して欲しい。
この「d」はデバッグ(debug)の頭文字である。
このコマンドにより現在の盤面を表示することが出来る。
見ての通り、「^」とついているのは後手の駒である。
盤面表示の日本語化
日本語を読むのが困難な環境にいる人は、次の部分を変えると盤面表示はアルファベット表記になる。
1 2 3 4 5 6 7 8 9 |
// shogi.h // -------------------- // コンパイル時の設定 // -------------------- // デバッグ時の標準出力への盤面表示などに日本語文字列を用いる。 #define PRETTY_JP // ↑ここをコメントアウト |
同じようにdコマンドで今度は…。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
> d l n s g k g s n l . r . . . . . b . p p p p p p p p p . . . . . . . . . . . . . . . . . . . . . . . . . . . P P P P P P P P P . B . . . . . R . L N S G K G S N L BLACK HAND : , WHITE HAND : Turn = BLACK sfen lnsgkgsnl/1r5b1/ppppppppp/9/9/9/PPPPPPPPP/1B5R1/LNSGKGSNL b - 1 |
このように表示された。
見ての通り、
P = Pawn = 歩
L = Lance = 香
N = kNight = 桂
S = Silver = 銀
G = Gold = 金
B = Bishop = 角
R = Rook = 飛
K = King = 王
という意味である。また、盤上、後手の駒はアルファベットの小文字で表現される。
USIプロトコルでは上の略字を用いる。またソースコード上は、駒の名前として上の英単語を用いる。ゆえに、いまのうちから、これらに慣れておいたほうが良いだろう。
成り駒の呼び名
ソースコード上、成り駒は次のように書かれていることを知っているとソースコードがさらに読みやすくなるだろう。
PRO_PAWN = と(成歩)
PRO_LANCE = 杏(成香)
PRO_KNIGHT = 圭(成桂)
PRO_SILVER = 全(成銀)
HORSE = 馬
DRAGON = 龍
盤面を日本語表示で出力させているときに「全」と表示されていればこれは成銀であり、これはソースコード上(の定数)には、PRO_SILVERと書かれているという意味である。
また、USIプロトコル上は、成り駒は先頭に”+”をつけて表す。例えば、先手の成銀であれば+S、後手の成桂であれば、+nと言った具合である。
sfen文字列
さきほど盤面を表示させたときにsfenと書かれている行があった。
これは、USIプロトコルに基いて盤面を符号化したものである。
何か現在の盤面でバグを見つけた場合は、この部分をコピペしてメモ帳などに貼り付けておく。
例)
sfen lnsgkgsnl/1r5b1/ppppppppp/9/9/9/PPPPPPPPP/1B5R1/LNSGKGSNL b – 1
sfen文字列について詳しいことは「USIプロトコル」でggrksである。
よく見ると、”/”が段の区切りであり、数字は空白の升の数、あとはさきほどの駒に対応する英単語の頭文字なので、わりと読みやすいと思う。
末尾についている「b – 1」はb(=black = 先手)、”-“(手駒なし)、”1″は棋譜の初手(1手目)という意味である。
先手のことはblack、後手のことはwhiteと呼ぶのも知っておくとソースコードが読みやすくなる。
positionコマンド
次に、USIコマンドとしてpositionコマンドというのがあって、sfenで局面を指定できるので、さきほどのsfen文字列の先頭に”position”と書き足して
> position sfen lnsgkgsnl/1r5b1/ppppppppp/9/9/9/PPPPPPPPP/1B5R1/LNSGKGSNL b – 1
のようにしてコマンドを入力をする。そうすると内部で保持している局面がこれに差し替わる。
> d
とすればその局面が表示されるので差し替わっていることがわかるだろう。(sfen文字列を適当に変更して試してみること)
また、positionコマンドは平手の開始局面(“sfen lnsgkgsnl/1r5b1/ppppppppp/9/9/9/PPPPPPPPP/1B5R1/LNSGKGSNL”)のalias(別名)として”startpos”というのが使える。
それと、局面のあとに”moves”と書いてそのあとに指し手文字列を書いていけばその指し手で進めた局面がセットされる。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
例) > position startpos moves 7g7f 8b3b 3i4h 3c3d 8h2b+ 3b2b 5i6h 3a4b 6h7g 5a6b 5g5f 6b7b 4h5g 4b3c 7g8h 9a9b 9i9h 7b8b 8h9i 4a5b 7i8h 2c2d 2g2f 3c4d 6i7i 8b9a 5g6f 7a8b 4i5i 6a7a 5i6h 5b6b 5f5e 4d4e 6f5g B*6e B*7g 6e4g+ 5e5d 2b1b 5d5c+ 6b5c 2f2e 5c4d 7g8f P*5f 5g6f 4e4f P*5h 2d2e 8f5c+ 1b2b 5c3a 2b2d 3a4b 2d2b 4b3a 2b2d 3a4b 2d2c > d ^玉^桂^金 □ □ □ □^桂^香 ^香^銀 □ □ □ 馬 □ □ □ ^歩^歩^歩^歩 □^歩 □^飛^歩 □ □ □ □ □^金^歩 □ □ □ □ □ □ □ □ □^歩 □ □ □ 歩 銀^歩^銀 □ □ □ 歩 歩 □ 歩 □^馬 歩 □ 歩 香 銀 □ 金 歩 □ □ 飛 □ 玉 桂 金 □ □ □ □ 桂 香 先手 手駒 : , 後手 手駒 : 2 歩 手番 = 先手 sfen kng4nl/ls3+B3/pppp1p1rp/5gp2/7p1/2PSps3/PP1P1+bP1P/LS1GP2R1/KNG4NL b 2p 61 |
任意の盤面のsfen文字列の生成
sfen文字列自体は将棋所で盤面編集をして、そのあと検討機能を用いて検討させると思考エンジンに現在の盤面が渡ってくる。そのときに、このposition sfen … というコマンドが思考エンジンに送られてくる。対局中であれば、初期局面からの指し手であるから、position startpos moves …というコマンドが思考エンジンに送られている。
将棋所のデバッグウィンドウを開くと、将棋所が思考エンジンに対して送信しているコマンドがわかる。
そこで、デバッグウィンドウのなかからコピペして、やねうら王miniに貼り付けるなどすれば、懸案の局面に対してやねうら王mini側でデバッグなどの作業を進めることが出来る。
ここまでのまとめ
以上で、やねうら王miniに任意の局面を設定する&現在の局面を表示することが出来るようになった。
やねうら王miniでは自分で詰将棋ルーチンを作って、指定した局面を解かせてみる、みたいなことも簡単に出来る。(ように作ってある) 近いうちに解説する。
次の記事に続く。
>S = Silver = 銀
G=Gold=金・・・を書かない理由は何でしょう?
修正しました!(`・ω・´)ゞ
もちろん平岡さんに、より良い実装方法を教えてあげるついでに
既婚者として、失恋から立ち直るアドバイスをしてあげたんですよね?
私の場合、恋愛も含めて、人生は全部ゲーム的なものだと捉えるような人生観なので、失恋も「ああ、こういうイベントあるんだ、へ~」ぐらいの感じなので何の参考にもならない気が…。
おぉ。NDFメソッドに光が!!
評価関数の形式って公開されてましたっけ。
自分で評価関数を作るのは夢がありますね!
3駒関係固定ではなく、評価関数を自由に設計できるような自由度を持たせるために、いまとても苦労しながらコードを書いてます。
応援してます。
自分がやると駒得以外の名案がないので、生かせるかなぁ。
より、妄想しておきます。
全くの素人なので成り駒のアルファベット略字表記についてggrksってみたところ、前に+を付けると出ました。
記事に追記していただけるとありがたいです。
USIプロトコルではそうですね…。本文に追記しときますね。
>世界で二番目に(1番目は平岡さん)Aperyのソースコードを理解している状態になった気がする。
ということは
初級講座「連載やねうら王miniで遊ぼう!」の次は
中級講座「Aperyのソースコード完全解説」ですね。
やねうら王miniが理解できればそのままAperyも理解できると思いますよ。
シンプルな思考エンジンが公開されるのをとても楽しみにしています
ただ何も知らない私にとっては、評価関数ファイルの存在が謎めいています
どのようなデータ構造をしていているファイルなのかを簡単に教えていただけないでしょうか
よろしくお願いします
評価関数、3駒ですとKPP/KKP用の配列がべたっとファイルに格納されているだけですね。
評価関数自体は、差分計算しなければ、30分でBonanzaの評価関数の要点を話しますの記事の末尾のソースコードに近いです。