python-shogiは、Pythonで扱える非常に役立つ将棋ライブラリですが、速度が遅いのが用途によっては欠点になります。
公式サイトにも記述されていますが、速度よりもシンプルに抽象的に扱えることが目的となっています。
しかし、機械学習の用途に使用しようとする速度の遅さがネックになります。
そこでPythonからもできるだけ高速に動作する将棋ライブラリを作成することにしました。
python-shogiの内部では、盤面はビットボードで表現されていますが、Pythonのビット演算は非常に遅くボトルネックとなっています。
ビット演算部分をC++で開発して、Pythonから呼び出せるようにすることで速度の改善が見込まれます。
C++で将棋ライブラリを一から作成するのもロマンがありますが、ほとんど既存のライブラリをまねるだけになるため、C++部分にAperyのソースコードを使用させてもらい、AperyをPythonから呼び出せるようにする形で作成することにします。
C++とPythonのブリッジの方法には、Boost.PythonやPyBind11やcythonなどがありますが、cythonを使うことにしました。
理由は、cythonではインストール時に自動でビルドすることが可能で、Google Colabのようなクラウドでのインストールも容易になるためです。
C++とPythonのバインディング
cythonでC++のクラスや関数を呼び出すことは比較的容易で、拡張子が、.pyxのファイルを作成して、Pythonとほぼ同じ構文で
cdef extern from "cshogi.h": cdef cppclass __Board: __Board() except + __Board(const string& sfen) except + bool set_hcp(const char* hcp)
のように、extern宣言を行うだけでPythonで定義したクラスとほぼ同様に扱うことができます。
型の変換も自動で行われるため、ほとんど気にすることはありません。
ただし、ポインタで配列を渡す場合などは、少しトリックが必要になります。
Pythonからポインタを渡すには、cythonのメモリビュー機能を使って、Numpyのndarrayからポインタに変換します。
def func(data) cdef char[::1] = data c_func(&data[0])
Aperyから借用したソース
Aperyのソースコードから盤面管理と合法手生成の部分を残して、それ以外は削除しました。
PositionクラスはSearcherと密結合になっていましたが、Searcherが不要になるように修正を行いました。
Aperyにある局面を圧縮形式(HuffmanCodedPos)で保存、読み込みする機能も、Pythonから使用できるようにしています。
これにより、機械学習での局面の保存、読み込みが速くなります。
hcpでの保存、読み込みの例
import cshogi import numpy as np board = cshogi.Board() # save hcp = np.empty(1, dtype=cshogi.HuffmanCodedPos) board.to_hcp(hcp[0]['hcp']) # load board.set_hcp(hcp[0]['hcp'])
独自に追加した機能
独自に追加した機能としては、python-shogiと同じようにCSAファイルの読み込みが行える機能を用意しました。
また、やねうら王の学習局面データ形式(PackedSfen)も読み込めるようにしました。
インストール
GitHubからcloneして、pipでインストールします。
git clone https://github.com/TadaoYamaoka/cshogi.git cd cshogi pip install -e .
直接GitHubからインストールすることもできます。
pip install git+https://github.com/TadaoYamaoka/cshogi --no-cache-dir
インストールパッケージ名前は、cshogiで、importする際のモジュール名も、cshogiになります。
※2019/2/28 インストールパッケージ名をモジュール名と合わせました。
使用例
盤を作成して、開始局面で合法手を生成して表示し、1手指す処理の例です。
import cshogi board = cshogi.Board() # legal moves for move in board.legal_moves: print(cshogi.move_to_usi(move)) # move move = board.push_usi('7g7f') # print board print(board)
注意点
合法手チェック
速度を重視して着手を適用する際、合法手チェックを行っていません。
誤ったmoveを渡すと盤面データが壊れて、その後アクセス違反などでプログラムが異常終了する場合があります。
undo処理
python-shogiと異なり、局面を戻す際に、moveが必要になります。
# undo move
board.pop(move)
駒の扱い
駒に対応する数値もAperyに準拠しています。python-shogiとは異なるので注意が必要です。
詳細は、cshogi.pyxのPIECES、PIECE_TYPESの定義を確認してください。
速度比較
python-shogiと速度を比較しました。
比較には、機械学習を想定して、CSA形式の棋譜を読み込んで、棋譜を再生して、局面をリストに格納する処理を使用しました。
python-shogiでは、ビットボードをコピーしてリストに保存し、cshogiでは、hcpe形式でリストに格納します。
比較用コード:cshogi/read_csa.py at master · TadaoYamaoka/cshogi · GitHub
今後の予定
Google ColabでPythonオンリーでAlpha Zeroと同じ強化学習ができるようにすることを目標にしています。
そのために必要な機能拡充を行っていく予定です。
技術書典6に当選したので、強化学習をテーマに本を出す予定です。
本にするには、読者の実行環境を考慮する必要がありますが、誰でも同じように実行できるGoogle Colabが最適だと思います。
作ったのは、そのための準備でもあります。
今のところ使用方法とか説明がないので、使い方の詳細はソースを読む必要があります。
余裕ができたら使い方の説明も作成したいと思います。
2019/2/11 追記
Google Colabで使用する方法
現状PyPIに登録していないため、Google Colabで使用するには、GitHubからcloneしてローカルのファイルでインストールする必要がある。
そのためには、ノードブックで以下のコードを実行する。
!git clone https://github.com/TadaoYamaoka/cshogi.git %cd cshogi !pip install -e . %cd ..
これで、cshogiをimportして使用できるようになる。
2019/2/16 追記
直接GitHubからインストールすることもできる。
!pip install git+https://github.com/TadaoYamaoka/cshogi --no-cache-dir
アンインストール
ランタイムをクリアすれば、インストールの状態もクリアされるが、個別にアンインストールしたい場合は、
!pip uninstall cshogi
を実行すればよい。ロード済みのモジュールはそのまま使用される。再インストールして再読み込みさせるにはランタイムの再起動が必要になる。