OpenShogiLib をつかってみる

将棋ライブラリをつかってみる(けど将棋の話はほぼない)。

経緯

強化学習の勉強に、「風が吹く格子世界(教科書の例)」のような模式的な例でなく、経済データの学習のような「これは学習が上手くいっているのか」がよくわからないものではなく、実感をもてる題材がほしい。
→ バッグギャモンも囲碁もポーカーも知らないので将棋にする。流行り廃りじゃなく親しみをもてることが大事。
→ 一から書くと設計に悩むし、人対人アプリケーションをつくるだけでも結構手間。それも楽しいけど目的と違う。
→ 人生は短いので既にあるものを活用するべき。
OpenShogiLib

環境準備

作業環境: Mac 上の Docker。全面的に以下のブログ記事を参考にさせていただきました。
コンピュータ将棋を始めるにあたって便利な「OpenShogiLib」をサクッと動かしてみた - 圧倒亭グランパのブログ

それで Docker というものをつかうのがはじめてだったのでメモ。
今からでも間に合うDockerの基礎。コンテナとは何か、Dockerfileとは何か。Docker Meetup Tokyo #2 - Publickey
Docker とは: コンテナという隔離された環境で開発する。仮想マシンではない。
コンテナをつくって(build)、起動して(run)、中に入る(attach)という順序を踏めばよい(雑)。
先頭のブログ記事の Dockerfile をつくって(よくわからなかったので下3行は省いた/ユーザを作成しなかったのでrootで作業することになる)以下のコマンドを打つとコンテナに入れる。
$ boot2docker up # boot2docker 自体の起動
$ alias dl='docker ps -l -q' # 最後に起動したコンテナのIDへのエイリアス
$ docker build -t shogi . # Dockerfile をもとにコンテナイメージを作成(Dockerfile の隣で) shogiはイメージに付ける名前で何でもよい
$ docker run -d -t -i shogi # コンテナの起動
$ docker attach `dl` # コンテナへの接続
これで osl をインクルードした cpp コードが書ける。
この記事の最初で紹介したブログ記事が参照するまた別のブログ記事にあるコード例で動作確認できる。
ちなみに自分は Docker で動作確認 → Macでできないか模索 → 無理だったのでやはり Docker という手順を辿ったんだけど、Mac に boost を入れたりしたからか以下のビルドエラーが出るようになった。

$ g++ shogi.cpp -losl
/usr/lib/gcc/x86_64-linux-gnu/5/../../../../lib/libosl.so: undefined reference to 
`boost::gregorian::greg_month::get_month_map_ptr[abi:cxx11]()'
collect2: error: ld returned 1 exit status

以下のように引数を追加すると直った。
c++ - undefined reference to boost::gregorian::greg_month::as_short_string() const - Stack Overflow

$ g++ shogi.cpp -losl -lboost_date_time

それでコンテナ上で何か作業したら保存しておかないと次の日に作業の続きができない。以下を参考にする。
Docker で コンテナの保存(commit)AICS | AICS
このページを参考にすると好きな名前でイメージが保存できるので、次の日には boot2docker を起動して、前日に保存した名前のコンテナイメージを指定して run → attach すればよい。

中身を少しみてみる

上記のコード例にあったように、平手で盤面を初期化するコードは以下。

state::SimpleState sstate(osl::HIRATE);
std::cout << sstate << std::endl;

40個の駒には駒番号というものがふられているらしい。i番目の駒が何なのか見てみると、

std::cout << sstate.pieceOf(i) << std::endl;

以下の右のように番号がふられている。番号のふり方が妙だけどまあいいや。

P1-KY-KE-GI-KI-OU-KI-GI-KE-KY     P1 35 21 25 29 31 28 24 20 34
P2 * -HI *  *  *  *  * -KA *      P2 *  39 *  *  *  *  *  37 *
P3-FU-FU-FU-FU-FU-FU-FU-FU-FU     P3 01 03 05 07 09 11 13 15 17
P4 *  *  *  *  *  *  *  *  *      P4 *  *  *  *  *  *  *  *  *
P5 *  *  *  *  *  *  *  *  *      P5 *  *  *  *  *  *  *  *  *
P6 *  *  *  *  *  *  *  *  *      P6 *  *  *  *  *  *  *  *  *
P7+FU+FU+FU+FU+FU+FU+FU+FU+FU     P7 00 02 04 06 08 10 12 14 16
P8 * +KA *  *  *  *  * +HI *      P8 *  36 *  *  *  *  *  38 *
P9+KY+KE+GI+KI+OU+KI+GI+KE+KY     P9 33 19 23 27 30 26 22 18 32

でも最初は詰将棋をやりたいので盤面から駒を全部取り払う。

sstate.init();

そうすると全部敵の手持ちの駒になるっぽいので、詰将棋につかう駒を上の番号で指定して、敵味方も適切に設定し直して盤上に並べ直すことになると思われる。眠いのでまた別の日にやる。