将棋の定跡を勉強するためのアプリ「Kifu Notebook」を作った
最近3月のライオンを見て、子供の頃以来の将棋を始めるなどした。
最近は将棋も改めて勉強してる。直接のきっかけは3月のライオンを見たことだけど、大人になってからボードゲームをやると子供の頃とは違うように見えることに気づいたというのもある
— かと (@orangain) 2017年3月7日
適当なアプリをダウンロードしてコンピューターと対戦すると、ちょっと悪い手を指すだけで付け込まれて負けてしまう。序盤の定跡というものの理解が足りていない。相手の指す手に合わせて最適な手を指し続けなければならないので、1つの戦法だけ知っていても意味がない。
図書館で将棋の本を借りてきたり、勉強のためのアプリを購入するなどしてみた。解説されている個別の戦法は理解できるものの、考えられるすべての指し手(ここでは指し手空間*1と呼ぶことにする)における、その戦法の位置づけが把握できない。もちろん指し手空間は膨大なのだが、それをある程度限定するのが序盤の定跡という考え方のはずだ。
というわけで、指し手空間を樹形図のような形で可視化したかった。世の中の人はどうやって勉強しているのだろう。よくわからないので、とりあえず自分で樹形図的にメモを取れるアプリを作ってみた。それがKifu Notebookである。Pythonの人には自明かと思うがJupyter Notebookにインスパイアされている*2。
使い方
GitHubのReleasesから自分のOS用のバイナリをダウンロードしてきて、以下のように起動する。引数にはメモを保存するJKFファイルのパスを指定する。最初はサンプルファイルをダウンロードするとわかりやすいと思う。存在しないファイルのパスを指定したらまっさらな局面から始まり、Saveしたときにファイルが作成される。
kifu-notebook joseki.jkf
ブラウザーで以下のような画面が開く。
主な使い方は次のとおりである。
- 盤面でドラッグ&ドロップして(ルール通りに)駒を動かすと指し手が画面下部の樹形図に追加される。
- 樹形図の指し手をクリックするとその局面に移動できる。
- 既に次の指し手がある局面で別の手を指すと、分岐として記録される。
- 樹形図の指し手にホバーした時に表示されるボタンで、指し手を左右に移動したり、削除したりできる。
- 右のコメント欄にその指し手のコメントを書ける。コメントがある指し手には
*
がつき、ホバーするとツールチップでコメントが表示される。 bad:
で始まるコメントがある指し手はそれ以降薄い色になる。指し手はいけない手を記録するのに役立つ。- 右上のSaveボタンをクリックすると、コマンド起動時の引数に指定したJKFファイルに現在の状態を保存できる。
- Auto Saveにチェックを付けておけば、変更する度に自動的に保存される。
実装
ソースコードはorangain/kifu-notebookに置いてある。
Kifu for JS
将棋盤はKifu for JSのものを使用している。Reactのコンポーネント自体はライブラリとしてエクスポートされていなかったので、とりあえずforkしたものを使用している。
Kifu for JSはReactで作成されており、コンポーネント単位でいい感じに再利用できたので非常に助かった。
JSON棋譜フォーマット (JKF)
メモを記録するファイル形式としてJSON棋譜フォーマット (JKF) を使用している。Kifu for JSと同じくna2hiroさんのライブラリである。こうやって1人で界隈の必要なものを作っているのはカッコよくて憧れる。
JKFはKifu for JSにおける標準形式?であり、指し手の分岐やコメントなどの必要な要素が満たされており、JSONで使いやすかったので使わせてもらった。ただ、JKFはメインの棋譜があってそこに分岐を付け足す形なので、分岐を平等に扱うKifu Notebookで求められるデータ構造とは若干異なっていた。このため内部的には別の木構造を使っており、入出力の際にJKFと相互変換している。
shogi-piece-images
Kifu for JSでは将棋の駒画像として将棋アプリ用クリエイティブコモンズ画像が使われているが、PNG形式で解像度が低いのでRetinaディスプレイではちょっと気になった。錦旗一字駒はベクター形式も公開されているが、あまり好みじゃなかった。
そこでWikimedia Commonsに公開されていたHari Seldonさんによる駒のSVG画像を改変(枠の除去、背景色・影の追加など)して使用した。shogi-piece-imagesとして、CC BY-SA 3.0 Unportedで公開している。
React
Web UIにはReactを使っている。これまで使ったことなかったけど、Kifu for JSで使われていたので触ってみた。最初はKifu for JSを直接書き換える形で作っていたが、差分が大きくなってきた頃にcreate-react-appを使って1から作り直した。
最初はLocal Stateを使っていたが、複数のコンポーネントで状態を共有したほうが綺麗になる気がしたのでReduxを使うことにした。Presentational ComponentとContainer Componentを分けるという考え方は、propsとstateが混ざっていて気持ち悪かったので納得感があった。React/Redux界隈から漏れ聞こえてくるMiddlewareが重要だなという問題意識までは追いついたが、特に解決できているわけではない。
Go
コマンドはGo言語で書いた。みんなのGo言語に書かれていたgo-assets-builderを使ってビルドしたReactアプリを含めただけのコマンドにしている。
なんとなくブラウザで動かしたかったのでコマンドにしたけど、ユーザー層を考えるとElectronアプリとかのほうが使いやすかったかもしれない。この辺は検討の余地がある。
まとめ
Kifu Notebookという将棋の定跡を勉強するためのアプリを作った。将棋の指し手を樹形図のように可視化してメモできる。
Reactでの開発が面白くて将棋の勉強は放ったらかしになっている。早めにKifu Notebookを使って勉強を始めないと将棋への熱が冷めてしまう。
もしご存知の方がいれば、iPhoneで以下の条件をなるべく満たすオススメの将棋アプリを教えてもらえるとありがたい。
- 有償で構わないので広告がない
- 1人でコンピューターと対戦できる
- 待ったができる
- 相手のコンピューターの強さを調整できる
- (可能なら)相手のコンピューターの戦法を指定できる(例えばコンピューターを先手にして居飛車で戦ってほしいなど)
*1:コンピューター将棋における探索空間と同じ意味で使っているが、探索という言葉はしっくりこない。適切な言葉があれば知りたい。
*2:参考: https://twitter.com/orangain/status/839398377410326528