将棋の棋譜や局面のフォーマット

# はじめに

将棋に関するソフトウェアを開発していると、その棋譜や局面などを何らかのフォーマットで表現する必要性が生じます。これまで色々なフォーマットが考案されており、それぞれ人間的な読みやすさやプログラム的な扱いやすさ、表現可能なメタ情報などが異なります。個々のアプリケーションが独自に使っているものまで含めると全種類を把握することはできませんが、本記事では主要なソフトウェアで用いられているものや仕様が公開されているものを紹介します。

# 棋譜フォーマット

## KIF (.kif / .kifu)

KIF 形式は柿木将棋や Kifu for Windows などの作者として知られる柿木氏が考案した棋譜のフォーマットで、歴史が長く、最もよく使われているフォーマットです。

- [棋譜ファイル KIF 形式](http://kakinoki.o.oo7.jp/kif_format.html)
- [人間に挑み続けて30年　古参ソフト「柿木将棋」は進化する - 日本経済新聞](https://www.nikkei.com/article/DGXNASFK1000Q_Q2A210C1000000/)

人間（特に日本語圏のプレイヤー）にとっての読みやすさを重視しており、漢字を含めた全角文字が多く登場します。出力例を次に示します。

```
# ----  Kifu for Windows V7 V7.70 棋譜ファイル  ----
開始日時：2023/01/01 00:00
戦型：四間飛車
持ち時間：30分＋30秒
手合割：平手　　
先手：わたし
後手：師匠
手数----指手---------消費時間--
   1 ２六歩(27)   ( 0:00/00:00:00)
   2 ３四歩(33)   ( 0:00/00:00:00)
   3 ７六歩(77)   ( 0:00/00:00:00)
   4 ４四歩(43)   ( 0:00/00:00:00)
   5 ４八銀(39)   ( 0:00/00:00:00)
   6 ４二飛(82)   ( 0:00/00:00:00)
   7 ６八玉(59)   ( 0:00/00:00:00)
   8 ３二銀(31)   ( 0:00/00:00:00)
   9 ２五歩(26)   ( 0:00/00:00:00)
  10 ３三角(22)   ( 0:00/00:00:00)
  11 ７八玉(68)   ( 0:00/00:00:00)
```

`２六歩(27)` の `27` は移動元が２七であることを示しています。なお「右」や「左」「上」「寄」などの移動元を限定するための修飾子は使いません。持ち駒を打つ場合だけ括弧を書かずに「打」と書きます。

KIF 形式は対局者情報やコメントに加えて「しおり」[^しおり]を扱うことができ、この記事で紹介しているフォーマットの中では最も多くのメタ情報を扱うことができます。

[^しおり]:「基本図」や「第1図」など局面や指し手に対するラベルを付ける目的で使用します。

指し手の分岐も扱えることや、任意の開始局面を扱えることなども知られています。しかし、それらの仕様はドキュメント化されていないようです。実際に柿木将棋や Kifu for Windows を使って棋譜を書き出すと、どのような記法が用いられるのかを知ることができます。例えば、開始局面には BOD 形式 (後述) が用いられています。

これまでの経緯からすると、厳格なドキュメントを作成したり公式のパーサーが公開されることはなさそうです。他の分野のデータフォーマット（例えば MP4）でもよくあることですが、一個人や一事業者から始まったフォーマットには細かい部分で方言が生まれてしまいがちです。 KIF 形式であれば「王」なのか「玉」なのか、スペースはどこに何個入るのかなど様々あります。自身のソフトウェアで KIF 形式に対応する場合、特に任意の KIF ファイルの読み込みを行うのであれば、どこまで柔軟に対応するのかをある程度割り切って判断することも必要だと思います。

文字コードに関して、拡張子が `.kif` [^kif-bkf] の場合は Shift_JIS を使うとされています。かつては将棋関連のソフトウェアのほとんどが Windows のアプリケーションだったこともあって、今でも Shift_JIS で書かれたファイルに遭遇することは多くあります。拡張子 `.kifu` が UTF-8 版だとされていますが、拡張子が `.kif` で中身は UTF-8 というケース [^kif-utf8] も実際にはあるようです。 Kifu for Windows の場合にはファイルの冒頭に `#KIF version=2.0 encoding=UTF-8` というヘッダーを入れておくことで、拡張子が `.kif` でも UTF-8 として読み込むことができるようになっています。 [^kif-encoding-header] しかしこの仕様も公式なドキュメントは出ていないと思われ、またヘッダーが無いファイルも出回っていることから、最近のアプリではデータの中身から自動判別するのが主流になっています。

[^kif-bkf]:東大将棋6では KIF 形式の拡張子として `.kif` 以外に `.bkf` （「分岐棋譜」の意）も選べますが、東大将棋以外に `.bkf` を用いるアプリは見たことがありません。歴史的経緯は不明ですが、分岐を含んだ棋譜の保存にも `.kif` を使うのが一般的です。

[^kif-utf8]:将棋所の設定で UTF-8 を選ぶと拡張子は .kif のまま UTF-8 で出力するようになります。また、81Dojoの棋譜 (.kif) をダウンロードすると UTF-8 で書かれています。

[^kif-encoding-header]: https://yaneuraou.yaneu.com/2018/08/31/%e3%80%8e%e5%b0%86%e6%a3%8b%e7%a5%9e%e3%82%84%e3%81%ad%e3%81%86%e3%82%89%e7%8e%8b%e3%80%8f%e3%81%a7%e6%9b%b8%e3%81%8d%e5%87%ba%e3%81%97%e3%81%9fkif%e3%83%95%e3%82%a1%e3%82%a4%e3%83%ab%e3%81%8c/#comment-26033

KIF 形式の注意点として持ち時間についても触れておきます。
先に示した例では `30分＋30秒` と書かれていますが、これも明確な取り決めはありません。 柿木将棋では対局機能を利用した時に自動で入力されるものの、編集画面上では改行を含まない任意の文字列を入力できます。従って `持ち時間：` に続く値をパースして例えば 1 手ごとの残り時間を計算しようと思っても、必ずしも想定したフォーマットで書かれているとは限らないということです。

## KI2 (.ki2 / .ki2u)

KI2 形式は KIF 形式をより伝統的記法に近づけたものです。専用のドキュメントは無いようですが、 Kif for Windows の紹介ページで言及されています。

- [Kifu for Windows の紹介](http://kakinoki.o.oo7.jp/KifuwInt.htm)

メタ情報は基本的に KIF 形式と同じですが、指し手ごとの消費時間を書く方法は用意されていません。指し手は一行に複数手書くことができ、適宜見やすいように改行やスペースを挿入します。次に例を示します。

```
開始日時：2023/01/01 00:00
戦型：四間飛車
持ち時間：30分＋30秒
先手：わたし
後手：師匠

▲２六歩    △３四歩    ▲７六歩    △４四歩    ▲４八銀    △４二飛
▲６八玉    △３二銀    ▲２五歩    △３三角    ▲７八玉    △６二玉
▲５八金右  △７二銀    ▲５六歩    △５二金左
```

KIF 形式と違って移動元の座標は無く、「右」や「寄」などの修飾子[^KI2の修飾子]を使います。手番を示す記号に `☗☖` ではなく `▲△` を使うのは Shift_JIS で扱える文字だけで構成するためだと思われます。なお、 Kif for Windows では次のような設定項目で KI2 形式の出力をカスタマイズすることが可能です。

[^KI2の修飾子]:細かい用法は [棋譜の表記方法 | よくある質問 | 日本将棋連盟](https://www.shogi.or.jp/faq/kihuhyouki.html) や [将棋のルール「棋譜について」 | 品川将棋倶楽部](https://ameblo.jp/written-by-m/entry-10365417107.html) が参考になります。「行」が使われているケースはあまり見ないので「上」に統一した方が無難です。

![スクリーンショット (180).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/78005/a132cebc-8a1b-6075-ddb7-82d1ba5a7193.png)

後手番で使用する記号を `△` ではなく `▽` に変更でき、数字も全角と半角を選べるようになっています。これらの表記の幅があることを考慮しないと KI2 形式の読み込みはうまくいかない場合があるので注意が必要です。

KI2 形式の読み書きを実装するのは大変なので対応しているソフトウェアは多くありませんが、メールや掲示板で棋譜を共有する際に読みやすくて、かつ短く書けるので、一時期は KI2 形式の棋譜がかなり多く出回っていた印象 [^ki2-share] です。

[^ki2-share]:特に某電子掲示板で大量に見つけることができると思います。

## CSA (.csa)

CSA 形式はコンピューター将棋協会（CSA: Computer Shogi Association) が定めるフォーマットです。おそらく、学術的な団体が策定した唯一の棋譜フォーマットと言って良いと思います。

- [CSA通信プロトコル](http://www2.computer-shogi.org/protocol/)
  - [CSA標準棋譜ファイル形式 第6版 バージョン2.2](http://www2.computer-shogi.org/protocol/record_v22.html)
  - [CSA標準棋譜ファイル形式 第7版 バージョン3.0](http://www2.computer-shogi.org/protocol/record_v3.html)

王は `OU`、金は `KI`、投了は `TORYO` といった具合に全て ASCII コードで扱える文字だけで設計されていて、主要なキーワードに日本語のローマ字表記が多く使われています。次に例を示します。

```
V2.2
N+PlayerA
N-PlayerB
$EVENT:Sample Game
PI
+
+2726FU,T1
-3334FU,T1
+7776FU,T2
-2288UM,T5
+7988GI,T3
-3122GI,T2
```

この例で `PI` は平手、 `+` は先手番を表していますが、任意の開始局面を表現する方法も明確に規定されています。「☗２六歩」を `+2726FU` と記述するように移動元と移動先それぞれの座標が書かれます。持ち駒を打つ場合は移動元が `00` になり、また駒が成る場合には成った後の駒種を使用します。「打」や「成」に相当する文字を後ろに付け足さないので、指し手を表す字数が常に一定となります。

`$` で始まるメタ情報や `T` で始まる消費時間に加えて、コメントを書くこともできます。 V2.2 までは単に

> ソフトが読み飛ばすコメントとする。

としか規定されていませんでした。しかし、 V3.0 では Floodgate の拡張仕様を取り込んで

> "'*"に続き、プログラムが読むコメントを記述する。
> 指し手、または、開始局面の後に記述する。

という記述が加わり、更に評価値や読み筋、ノード数を記載する方法（後述）も規定しています。

CSA 形式はコンピュータ将棋選手権の通信プロトコルで用いられ、将棋 AI 開発者の間では普及しているフォーマットです。一方で、指し手の分岐を扱うことができないことや、一般ユーザー向けの将棋アプリだとそもそも対応していないケースもあることから、エンジニア以外が意識的に利用することは多くありません。

### CSA 形式の文字コードについて

CSA 形式で使用する文字コードや改行コードについて、公式の文書から読み取りにくい事情を補足しておきます。

多くの CSA 形式のデータは ASCII コードで完結していますが、コメントや棋譜情報に日本語を含めることは許されているので、その場合には文字コードが関心ごとになります。

V2.2 では次のように書かれています。

> 文字コードと改行コードは、使用するOSや環境に依存する。コメントと棋譜情報(対局者名等)に日本語を使用してもよい。

一方で V3 では次のように書かれています。

> 先頭行で、次のように、CSA形式であることを示し、文字コードを記述する。
> `'CSA encoding=UTF-8`
> 文字コードは、"UTF-8" と "SHIFT_JIS" を指定できる。
> この行がない場合、過去の棋譜との互換性のため、文字コードは SHIFT_JIS とし、改行コードは CR LF とする。

これらの記述は単純に解釈すると矛盾しているように読めます。 V3 の記述では過去のバージョンが SHIFT_JIS だったように書かれていますが、 V2.2 では環境に従うと書かれているのみで SHIFT_JIS に限定するとは書かれていません。

V2 が作られた当時、将棋関連のソフトウェアは Windows 上で作られたものが圧倒的に多く、 SHIFT_JIS を使うのが通常でした。従って、この記述は文字コードが明記されない場合に SHIFT_JIS として読み込むことを促すものだと考えられます。

バージョンの宣言よりも先にコメントがあるかもしれないので、バージョンよりも先に文字コードを判断する必要があります。 V3.0 に従うなら SHIFT_JIS/CR+LF として読み込むことになりますが、 V2 の棋譜に対して本当に SHIFT_JIS として読み込むのが妥当なのか筆者は疑問を持っています。結局のところ、より多くの棋譜を正しく読み込むためには、実際に使われている文字から文字コードを判別する必要があると思います。

## JSON 棋譜フォーマット (.jkf)

JSON 棋譜フォーマット (以下「JKF」) は [Kifu-for-JS](https://kifu-for-js.81.la/) の作者によって考案されたフォーマットで、その名前の通り JSON を用います。

- [JSON棋譜フォーマット(JKF)](https://github.com/na2hiro/Kifu-for-JS/tree/master/packages/json-kifu-format)

次に例を示します。

```json
{
    "header": {
        "先手": "PlayerA",
        "後手": "PlayerB",
        "表題": "Sample Game"
    },
    "initial": {
        "preset": "HIRATE"
    },
    "moves": [
        {},
        {
            "time": { "now": { "m": 0, "s": 0 }, "total": { "h": 0, "m": 0, "s": 0 } },
            "move": { "color": 0, "piece": "FU", "to": { "x": 7, "y": 6 }, "from": { "x": 7, "y": 7 } }
        },
        {
            "time": { "now": { "m": 0, "s": 0 }, "total": { "h": 0, "m": 0, "s": 0 } },
            "move": { "color": 1, "piece": "FU", "to": { "x": 8, "y": 4 }, "from": { "x": 8, "y": 3 } }
        },
        {
            "time": { "now": { "m": 0, "s": 0 }, "total": { "h": 0, "m": 0, "s": 0 } },
            "move": { "color": 0, "piece": "KI", "to": { "x": 5, "y": 8 }, "from": { "x": 4, "y": 9 }, "relative": "R" }
        }
    ]
}
```

棋譜情報 `header` と初期局面 `initial`、指し手 `moves` で構成され、概ね KIF と同じ表現能力 [^jkf-表現能力]を持っています。

[^jkf-表現能力]:2023年10月時点では KIF 形式の「しおり」に対応する表現は無いようです。

各プログラミング言語に JSON のライブラリがあるため、字句の構造を読み書きする実装に労力を割く必要がありません。指し手には駒の移動元座標に加えて `relative` というプロパティで「右」や「寄」などに相当する情報を付加します。これらの冗長な情報の付与を必ずしも独自に実装する必要はなく、公式の Normalizer を使えば補完できるようになっています。

## USI (SFEN)

USI(Universal Shogi Interface) 及び SFEN(Shogi Forsyth-Edwards Notation) は棋譜フォーマットそのものではありません。 SFEN は FEN (Forsyth-Edwards Notation) というチェスの局面の記法を将棋に応用したものです。そして USI は将棋の AI と GUI が連携する際のプロセス間通信の内容を規定したものです。 USI の中で局面を送信するのに SFEN が使われています。

- 原案
    - [The Universal Shogi Interface](http://hgm.nubati.net/usi.html)
    - [The Universal Shogi Interface, draft 1 (2007-01-24)](https://web.archive.org/web/20080131070731/http://www.glaurungchess.com/shogi/usi.html) (INTERNET ARCHIVE)
    - [USIプロトコル原案の魚拓 | やねうら王 公式サイト](https://yaneuraou.yaneu.com/2020/03/09/usi%e3%83%97%e3%83%ad%e3%83%88%e3%82%b3%e3%83%ab%e5%8e%9f%e6%a1%88%e3%81%ae%e9%ad%9a%e6%8b%93/)
- 将棋所
    - [将棋所：USIプロトコルとは](http://shogidokoro2.stars.ne.jp/usi.html)

USI において局面や指し手を送る記法は、棋譜を保存するのにもよく流用されています。それを呼称する上で「USI」と呼ぶ派と「SFEN」と呼ぶ派があるようです。例えば、[将棋所](http://shogidokoro2.stars.ne.jp/index.html)では棋譜コピーのメニューに「SFEN」と表記されていますが、[ShogiGUI](http://shogigui.siganus.com/)では「USI」と表記されています。上記の将棋所のドキュメントでは SFEN に指し手の記法も含まれるように読み取れますが、FEN や SFEN は本来局面のフォーマットであり USI の原案でもそう扱われているようです。そういう意味では「USI」と呼んだ方が正しそうですが、将棋 AI の開発者の間では「SFEN」派が多いようで、拡張子にも `.sfen` が使われています。 [^.sfen]

[^.sfen]:拡張子については Blunder.Converter が `.sfen` を用いるので、その影響が強いのだと思います。

この形式について明確な取り決めはありませんが、一般的には USI の `position` コマンドと同じものを記述します。次に例を示します。

```
position startpos moves 2g2f 3c3d 7g7f 5c5d 3i4h 8b5b
```

先頭の `position` は USI で局面を AI へ送るときのコマンド名です。 `position` を含めるかどうかも流派があります。将棋所や ShogiGUI は含めますが、 [Blunder.Converter](https://github.com/ak110/Blunder.Converter) は含めません。

`startpos` は平手初期局面を意味するキーワードです。 `startpos` ではなく SFEN で表記する場合は次のようになります。

```
position sfen lnsgkgsnl/1r5b1/ppppppppp/9/9/9/PPPPPPPPP/1B5R1/LNSGKGSNL b - 1 moves 2g2f 3c3d 7g7f 5c5d 3i4h 8b5b
```

`moves` の後にスペース区切りで指し手が並びます。もともと USI の 1 コマンドということもあり、 1 つの棋譜を 1 行だけで記述することができます。将棋 AI では学習用データや定跡など大量の棋譜をまとめて扱うので、そういった用途に向いていると言えます。

他のフォーマットにあるようなメタ情報を含めることはできません。なお、末尾に「投了」を含めたい場合は USI の `bestmove resign` コマンドにならって `resign` と書くことがあるようです。

## USEN

USEN (Url Safe sfen-Extended Notation) は [Shogi Playground](https://play.mogproject.com/) の開発者によって考案されたフォーマットで、 URL にそのまま埋め込むことが可能な文字だけで構成されます。

- [フロントエンド初心者の大学生が Scala.js で Web アプリを作ってみた話](https://www.slideshare.net/slideshow/scalajs-web/92707205#15)
- [Query Parameters - mogproject/mog-playground Wiki](https://github.com/mogproject/mog-playground/wiki/Query-Parameters)

最初の局面が平手初形でない場合は SFEN の一部の文字を置き換えます。
前述の USI の position コマンドと異なり、分岐を表現することが可能です。

USEN は Shogi Playground の URL へ棋譜を埋め込むために使用されています。
URL に棋譜を埋め込んでいる Web アプリは他にもありますが、 USI を使っているものが多く、ぴよ将棋は [USI を URL エンコード](https://www.studiok-i.net/android/piyo_shogi_link.html) 、 SHOGI-EXTEND は USI を Base64 エンコードしています。
しかし、 USI は 1 手につき 5 文字も消費してしまうため文字列が非常に長くなります。
一方で USEN は 36 進数 3 文字で表すため、USI と比べると効率が良いと言えます。

# 評価値と読み筋のフォーマット

将棋 AI の発展と普及に伴って、読み筋や評価値を保存する機能の需要が増えました。しかし、KIF や KI2, JKF でそれらの情報を扱う方法は規定されていません。 CSA 形式も V2.2 までは規定がありませんでした。そのため、評価値や読み筋をコメントに書き込むための拡張仕様がいくつか提案・実装されています。

## Floodgate の記法

[Floodgate](http://wdoor.c.u-tokyo.ac.jp/shogi/floodgate.html) は東京大学が運用している将棋の対局サーバーです。対局には CSA プロトコルを用いているため、指し手や消費時間は CSA 形式で送信・記録されます。

その際、将棋 AI の読み筋や評価値も付与できるように CSA プロトコルにコメントを送信する拡張を加え、 CSA 棋譜ファイル形式のコメント内に評価値と読み筋を記載するルールを定めています。（後述するようにこの仕様は CSA V3.0 で正式に取り込まれました。）

- [評価値と読筋を記録する拡張](https://shogi-server.osdn.jp/protocol.html#record-pv)

次の例では `45` が評価値、 `+2625FU` 以降が読み筋を表しています。

```
** 45 +2625FU -8485FU +6978KI -4132KI +3938GI -7172GI +9796FU -3334FU +2524FU -2324FU +2824HI -8586FU +8786FU -8286HI +0087FU -8684HI +7776FU -0023FU +2428HI -5142OU +5968OU -7374FU +3736FU -8173KE +3837GI -9394FU +3746GI -1314FU +1716FU -0086FU +8786FU -9495FU +8822UM -3122GI +9695FU -8486HI +0087FU -8676HI +7988GI
```

## CSA V3 の記法

CSA 棋譜形式の V2.2 までにコメントの内容に関する言及はありませんでしたが、 [CSA V3.0](http://www2.computer-shogi.org/protocol/record_v3.html) で Floodgate の記法が取り込まれました。

Floodgate の評価値と読み筋に加えて `#` の後にノード数（≒探索した局面の数）を記述できます。

```
'** 30 +7776FU -9394FU +7968GI #1234
```

ちなみに CSA V3 の正式リリースに先立って、世界コンピューター将棋選手権 (WCSC) では 2023 年大会から Floodgate と同じ shogi-server ベースの対局サーバーを導入し、評価値や読み筋を公式ウェブサイトで閲覧できるようになっていました。

## ShogiGUI の記法

ShogiGUI で AI を使った対局や棋譜解析をすると独自の記法でコメントが記録されます。

- [ShogiGUI - コメント（思考）ウインドウ](https://sites.google.com/site/shogigui/%E3%83%9E%E3%83%8B%E3%83%A5%E3%82%A2%E3%83%AB/%E6%83%85%E5%A0%B1%E3%82%A6%E3%82%A4%E3%83%B3%E3%83%89%E3%82%A6/%E3%82%B3%E3%83%A1%E3%83%B3%E3%83%88%E6%80%9D%E8%80%83%E3%82%A6%E3%82%A4%E3%83%B3%E3%83%89%E3%82%A6)

棋譜解析をした場合の例を次に示します。

```
*解析 0  候補1 時間 00:03.0 深さ 17/22 ノード数 1136137 評価値 21 読み筋 △８四歩(83) ▲７八金(69) △８五歩(84) ▲２五歩(26) △３三角(22) ▲７六歩(77) △２二銀(31) ▲７七角(88) △同　角成(33) ▲同　桂(89) △３三銀(22) ▲８八銀(79) △４二玉(51) ▲６八玉(59) △７二銀(71) ▲４六歩(47) △６四歩(63) ▲４七銀(48) △６三銀(72) ▲５六銀(47) △５四銀(63) 
```

1 回の思考をスペース区切りで 1 行に記載し、アスタリスクが先頭に書かれます。一部の項目を除いて、属性名と値のペア（ただし読み筋等は値の中にもスペースが含まれる）が書かれるようです。読み筋は KIF 形式が用いられているようです。

[棋神アナリティクス](https://kishin-analytics.heroz.jp/lp/) も似た記法を使用しているようですが、互換性があるかは不明です。参考までに棋神アナリティクスの例を次に示します。

```
* Engine suisho Version Suisho5/YaneuraOu-V7.50 候補1 深さ 10/17 ノード数 107646 評価値 -170 読み筋 ▲２五桂(37) △５四歩(53) ▲７六歩(77) △２四歩(23) ▲６八金(58) △３七歩成(36) ▲同　銀(46) △２五歩(24) ▲同　飛(28)
```

## ぴよ将棋の記法（K-Shogi の記法）

[ぴよ将棋](https://www.studiok-i.net/piyo_shogi/) の記法を説明した公式なドキュメントは発見できていません。

実際の出力の例を示します。

```
#指し手[72]△１四歩  ▲６八銀  △３四歩  ▲７七銀  △３三角  ▲７八金  △８五歩  ▲６九玉  △２二銀  ▲４八銀  △４二角  
#推奨手[29]△４二銀  ▲５八金右  △３四歩  ▲２四歩  △同歩  ▲同飛  △３三銀  ▲２八飛  △２三歩打  ▲７七角  △５二金  ▲８八銀  △４四歩  ▲４八銀  
#定跡: △８五歩   △３四歩   
```

ぴよ将棋と同じ開発者の [K-Shogi](https://www.studiok-i.net/kshogi.html) でも類似の記法が用いられています。次はその例です。

```
#形勢[-27] △８六歩打  ▲同　歩  △同　飛  ▲９六歩  △８七歩打  ▲９七角
```

`#` で始まり、評価値は `[` `]` で括られています。読み筋は KI2 形式だと思われます。

## ShogiHome の記法

筆者が開発している [ShogiHome](https://sunfish-shogi.github.io/electron-shogi/)でも独自の記法を用いています。

- [思考コメントの仕様（ドラフト）](https://github.com/sunfish-shogi/electron-shogi/wiki/%E6%80%9D%E8%80%83%E3%82%B3%E3%83%A1%E3%83%B3%E3%83%88%E3%81%AE%E4%BB%95%E6%A7%98%EF%BC%88%E3%83%89%E3%83%A9%E3%83%95%E3%83%88%EF%BC%89)

既存の記法を用いることも検討しましたが、 Floodgate の記法は人間にとって読みづらく、 ShogiGUI やぴよ将棋は仕様の細かい部分（または全部）がドキュメント化されておらず、特に将来の拡張方針がわからないため採用しませんでした。

コメントの例を次に示します。

```
互角
#評価値=92
#読み筋=△８五歩▲７八金△８六歩▲同　歩△同　飛▲２四歩△同　歩▲同　飛△３二金▲３四飛△３三角▲５八玉△７六飛▲７七角△５二玉▲８四飛△８二歩▲８三歩△７二金▲８二歩成△同　銀
#深さ=15
#エンジン=たぬきHao や王7.6.1（検討用1スレ）

互角
*評価値=101
*読み筋=△８五歩▲７八金△３二金▲２四歩△同　歩▲同　飛△８六歩▲同　歩△同　飛▲３四飛△３三角▲６八玉△７六飛▲３六歩△５二玉▲３七桂△７四飛▲同　飛△同　歩▲３八銀△２八飛▲３三角成△同　桂▲８三角△２二飛成▲７四角成△２八龍
*深さ=23
```

先頭の文字 `*` と `#` はそれぞれ対局時、検討（棋譜解析）時に使用します。プログラムが読み取る情報は全て `キー=値` の形式で書くので、各行を 1 番目のイコール `=` で Split すればキーと値を取り出すことができます。また、読み筋を書く場合は KI2 形式を使用します。

# 局面フォーマット

## BOD (.bod)

BOD は Kifu for Windows や柿木将棋の局面フォーマットで、不定形の局面から棋譜が始まる場合には KIF 形式や KI2 形式にも使用されます。次に例を示します。

```
後手の持駒：なし
  ９ ８ ７ ６ ５ ４ ３ ２ １
+---------------------------+
|v香v桂v銀v金v玉v金v銀v桂v香|一
| ・v飛 ・ ・ ・ ・ ・v角 ・|二
|v歩v歩v歩v歩 ・v歩 ・v歩v歩|三
| ・ ・ ・ ・v歩 ・v歩 ・ ・|四
| ・ ・ ・ ・ ・ ・ ・ ・ ・|五
| ・ ・ 歩 ・ ・ ・ ・ 歩 ・|六
| 歩 歩 ・ 歩 歩 歩 歩 ・ 歩|七
| ・ 角 ・ ・ ・ ・ ・ 飛 ・|八
| 香 桂 銀 金 玉 金 銀 桂 香|九
+---------------------------+
先手の持駒：なし
手数＝4  △５四歩  まで
```

人間にとっての読みやすさを重視しており、段番号や筋番号などの冗長な情報も含まれています。駒の名前が漢字で書かれ、等幅フォントであればマス目の位置もきれいに揃うので（さすがに後手の駒を反転することはできませんが）一般的な局面図に見慣れていれば誰でも読みとることができると思います。

## SFEN

前述した通り、 SFEN は USI で用いられる局面の記法です。将棋所や Kifu for Windows で平手の開始局面をコピーすると次のような出力になります。

```
lnsgkgsnl/1r5b1/ppppppppp/9/9/9/PPPPPPPPP/1B5R1/LNSGKGSNL b - 1
```

一方で、 ShogiGUI では `sfen` を先頭につけて次のようになります。

```
sfen lnsgkgsnl/1r5b1/ppppppppp/9/9/9/PPPPPPPPP/1B5R1/LNSGKGSNL b - 1
```

これは USI のコマンドにならったものだと思いますが、 SFEN 自体に `sfen ` というプレフィクスは含めません。

SFEN の説明は [将棋所：USIプロトコルとは](http://shogidokoro2.stars.ne.jp/usi.html) がわかりやすいのですが、より厳格な定義は [The Universal Shogi Interface](http://hgm.nubati.net/usi.html) を参照してください。

SFEN は局面と手数に対して一意に定まることが知られています。ただし、そうするためには USI の原案通りに実装する必要があります。詳しくは [sfen文字列は本来は一意に定まる件 | やねうら王 公式サイト](https://yaneuraou.yaneu.com/2016/07/15/sfen%E6%96%87%E5%AD%97%E5%88%97%E3%81%AF%E6%9C%AC%E6%9D%A5%E3%81%AF%E4%B8%80%E6%84%8F%E3%81%AB%E5%AE%9A%E3%81%BE%E3%82%8B%E4%BB%B6/) を参照してください。

SFEN が広まる前は局面を記載する方法として BOD 形式か CSA 形式を使うケースがほとんどでした。それらと比べて SFEN は 1 行で書くことができて色々な用途に応用しやすい面があり、例えば [局面ペディア](http://kyokumen.jp/)では URL の一部に使用されています。

### 古将棋や変則将棋への応用

対局サイト [lishogi.org](https://lishogi.org/) では[中将棋](https://lishogi.org/variant/chushogi)や[京都将棋](https://lishogi.org/variant/kyotoshogi)にも SFEN を応用しています。中将棋の例を次に示します。

```
lfcsgekgscfl/a1b1txot1b1a/mvrhdqndhrvm/pppppppppppp/3i4i3/12/12/3I4I3/PPPPPPPPPPPP/MVRHDNQDHRVM/A1B1TOXT1B1A/LFCSGKEGSCFL b - 1
```

基本的な構造は本将棋と同じですが、駒の種類が多いので使用する文字の種類も増えています。例えば `e` は醉象を表します。どの駒にどの文字を当てているかは [scalashogi のソースコード](https://github.com/WandererXII/scalashogi/blob/main/src/main/scala/format/forsyth/SfenUtils.scala) を参照してください。京都将棋の場合、概ね本将棋で使用する文字と同じですが、と金を表すのに `+p` ではなく `t` を使用しています。

## Packed SFEN

膨大な量の教師データや定跡データを扱う上では、局面をより少ないデータ量で表現したくなります。その解決策としてハフマン符号を応用したバイナリフォーマットがしばしば用いられます。その一例は、やねうら王が実装している「Packed SFEN」です。

Packed SFEN の詳細は以下の実装やブログでわかります。

- [yaneurao/YaneuraOu](https://github.com/yaneurao/YaneuraOu/blob/v8.00-fukauraou/source/extra/sfen_packer.cpp)
- [ingktkhk/sfen_converter](https://github.com/ingktkhk/sfen_converter)
- [Aperyでやねうら王のPackedSfenValueを読み込む - TadaoYamaokaの開発日記](https://tadaoyamaoka.hatenablog.com/entry/2018/05/10/230851)

Packed SFEN は 256 bits (32 bytes) の固定長になる特徴があります。　256 bits というキリの良い長さは、大量のデータを扱う上で都合が良いと言えます。

このデータフォーマットは Packed SFEN という名前ですが、データ構造を見ると SFEN の特徴をそれほど引き継いでいるわけでもないように見えます。ただ、将棋 AI 関係者の間では Packed SFEN という名前で浸透しているようです。

## hcp

Packed SFEN と同様にハフマン符号を用いたフォーマットが hcp (Huffman Coded Pos) です。hcp に評価値を加えた hcpe (Huffman Coded Pos and Eval) が機械学習の教師局面データとして使われます。hcpe はもともと elmo が用いているもので、他の AI では dlshogi が採用しています。dlshogi では更に情報を加えた [hcpe3](https://tadaoyamaoka.hatenablog.com/entry/2021/03/16/235251) も用いられています。

# 定跡フォーマット

一般的に「定跡」と言う場合、過去に出現した局面と完全な同一局面には限定せず、類似局面（例えば端歩の位置が違う）に適用可能な場合にはそれも含む意味で用いられると思います。 [^定跡] しかしコンピューターで定跡を扱う場合、類似局面において同じ手が応用できるかどうかは先を読まないと判断できませんし、大量の定跡を積み込んで完全一致する局面を検索して使うケースが多いようです。

[^定跡]: 明確に言及している文献は見つかっていませんが、プロ棋士の解説や書籍等での表現からこのように解釈しています。

各種将棋 AI の開発者によって作られたものを挙げればたくさんのフォーマットがあると思いますが、ここではよく使われている定跡フォーマットを取り上げます。

## ShogiGUI の定跡フォーマット (.sbk)

拡張子 `.sbk` は ShogiGUI で用いられる定跡ファイルのフォーマットです。仕様は公開されていないようで、 ShogiGUI のソースコードも非公開です。ただし、 ShogiGUI の作者により定跡の変換ツール [BookConv](https://github.com/ai5/BookConv) が公開されており、ソースコードを読めば仕様がわかると思われます。

.sbk に含めることができる情報は、 ShogiGUI の定跡編集機能で入力できる項目に対応していると思われます。ShogiGUI の画面を見ると、局面に対する指し手だけでなく過去の対局における勝敗やコメントなどを含めることができるようです。

## やねうら王の定跡フォーマット (.db)

「やねうら王」で用いられている定跡フォーマットは開発者のブログで詳しく述べられています。

- [将棋ソフト用の標準定跡ファイルフォーマットの提案 | やねうら王公式サイト](https://yaneuraou.yaneu.com/2016/02/05/standard-shogi-book-format/)
- [やねうら王を使って定跡を作る | やねうら王公式サイト](https://yaneuraou.yaneu.com/2016/07/11/%E3%82%84%E3%81%AD%E3%81%86%E3%82%89%E7%8E%8B%E3%82%92%E4%BD%BF%E3%81%A3%E3%81%A6%E5%AE%9A%E8%B7%A1%E3%82%92%E4%BD%9C%E3%82%8B/)
- [やねうら王アップデート！テラショック定跡の生成に対応しました | やねうら王公式サイト](https://yaneuraou.yaneu.com/2019/05/28/generate-terashock-book/)

局面や指し手に SFEN や USI を用いたテキストベースのフォーマットです。

## Apery の定跡フォーマット

[Apery](https://github.com/HiraokaTakuya/apery) [^AperyRust版] の定跡フォーマットは複数の将棋 AI で用いられていて、やねうら王[^やねうら王のApery定跡対応]も対応しています。また、 [dlshogi](https://github.com/TadaoYamaoka/DeepLearningShogi) は定跡を含めたいくつかの基盤部分の実装に Apery のソースコードを使用しています。

[^AperyRust版]:現在は [Rust版](https://github.com/HiraokaTakuya/apery_rust) も作られていますが、この記事を書く上での調査は主に C++ 版の実装を参照しました。

[^やねうら王のApery定跡対応]:[開発者ブログ](https://yaneuraou.yaneu.com/2019/06/02/%E5%B0%86%E6%A3%8B%E3%81%AE%E5%AE%9A%E8%B7%A1%E3%81%A7gameply%E5%88%9D%E6%9C%9F%E5%B1%80%E9%9D%A2%E3%81%8B%E3%82%89%E3%81%AE%E6%89%8B%E6%95%B0%E3%81%A3%E3%81%A6%E8%A6%81%E3%82%8A%E3%81%BE%E3%81%99/)ではApery定跡のメンテナンスが負担になっていると述べられており、今後もサポートを継続するかは不明です。

Apery の定跡フォーマットは、いわゆるバイナリデータで構成されています。ゾブリストハッシュ (Zobrist hashing) と呼ばれる局面のハッシュ値をキーにして、その局面に対する指し手や関連する数値が記録されます。具体的には移動元、移動先、成るかどうか、出現回数、評価値を含みます。同じ局面に複数の手が登録されている場合は出現回数で重みづけしてランダムに選択します。評価値はApery自身が探索して出した値で、しきい値を下回る手を除外するために使用します。定跡を作成するときはキーでソートしてからファイルに保存しておき、検索時には `istream::seekg` で二分探索をしています。

## 技巧の定跡フォーマット

[技巧](https://github.com/gikou-official/Gikou) も Apery と類似の定跡フォーマットを使用しています。ソースコードを見ると全体の構造はほぼ同じですが各エントリーに含めている内容が異なり、技巧にある Frequency や OpeningStrategySet は Apery の定跡には無さそうです。

ゾブリストハッシュを定跡や置換表 (Transposition Table) に利用する手法は、将棋 AI 開発でよく行われてきました。そのため Apery や技巧と互換性は無くても、類似の構造を使ったソフトウェアは多いと思われます。筆者が開発した [Sunfish](https://github.com/sunfish-shogi/sunfish4) も旧バージョンではゾブリストハッシュを使っています。

しかし、ゾブリストハッシュを使っても大きなメモリの節約にはならない[^ハッシュとメモリ効率]ことや、ハッシュ値の衝突が問題になる可能性もあることから、 SFEN かその他の完全ハッシュを使用する開発者も増えているようです。

[^ハッシュとメモリ効率]:定跡データ自体は小さくなるのですが、探索に使用するデータの方が大きい傾向にあるので全体でみると節約する意義が薄いという趣旨です。置換表では現在もほとんどのケースでゾブリストハッシュが使われていると思います。

# その他のフォーマットの例

ここまでで取り上げなかったフォーマットの例を以下に示します。あまり使われるケースは無いと思いますが、これらの拡張子が付いたファイルを目にする場合があるかも知れません。

- PSN / PSN2 (.psn / .psn2)
    - チェスの記法を参考にしたフォーマットです。
    - 仕様の原文はサイトごとなくなっています。 Wayback Machine や [やねうら王 公式サイト](https://yaneuraou.yaneu.com/2021/06/22/what-is-the-shogi-game-format-psn/) にコピーがありますが、これらの文書が最新版なのかは不明です。
    - [将棋所](http://shogidokoro2.stars.ne.jp/) や [将棋神やねうら王](https://book.mynavi.jp/yaneura/) ([MyShogi](https://github.com/yaneurao/MyShogi)) で扱えます。
- .gam / .gbd
    - 柿木将棋や Kifu for Windows で扱えるフォーマットです。
    - 詳細は不明で、使用されているケースを見たことはありません。
- .kj2 / .kj3
    - 柿木将棋や Kifu for Windows の定跡フォーマットです。
- .kfk
    - [将棋所](http://shogidokoro2.stars.ne.jp/) が出力する棋譜解析結果のフォーマットです。
    - 棋譜自体は CSA 形式がそのまま埋め込まれており、 XML のタグで評価値やその他のメタ情報を付与しているようです。

# ツール・ライブラリ

将棋の棋譜等のフォーマットを扱うためのツールやライブラリをいくつか紹介します。将棋 AI 開発者の間で知られているものから選んでいますが、必ずしも筆者が動作を確認していないものを含んでいます。ライブラリに関してはあくまでもライブラリの形態で提供されているものを選びました。オープンソースの各種AIやGUIのアプリケーションにも有用な実装がたくさんあります。いずれにしてもライセンスに留意して使ってください。

- ライブラリ
  - [cshogi](https://github.com/TadaoYamaoka/cshogi) (Python: C言語実装)
  - [python-shogi](https://github.com/gunyarakun/python-shogi) (Python)
  - [tsshogi](https://www.npmjs.com/package/tsshogi) (JavaScript / TypeScript)
  - [json-kifu-format](https://github.com/na2hiro/Kifu-for-JS/tree/master/packages/json-kifu-format#json%E6%A3%8B%E8%AD%9C%E3%83%95%E3%82%A9%E3%83%BC%E3%83%9E%E3%83%83%E3%83%88jkf---) (JavaScript / TypeScript)
  - [shogi-kifu-converter](https://github.com/sugyan/shogi-kifu-converter) (Rust)
  - [scalashogi](https://github.com/WandererXII/scalashogi) (Scala)
- 複数棋譜一括変換ツール
  - [ShogiHome](https://sunfish-shogi.github.io/electron-shogi/)
      - 筆者が開発しています。
      - KIF や KI2, CSA, JKF の相互変換と SFEN の書き出しが可能です。
      - やねうら王定跡フォーマット2016(.db)の読み込みと書き出しが可能です。
  - [Blunder Converter](https://github.com/ak110/Blunder.Converter)
      - SFEN, KIF, CSA の出力が可能です。
      - 複数棋譜を 1 ファイルにまとめたり 1 ファイルを複数ファイルに分割することも可能です。
  - [柿木将棋IX](https://www.vector.co.jp/soft/winnt/game/se505030.html)
      - 「棋譜情報の一括設定」から KIF と KI2 の出力が可能です。入力は CSA や BOD も対応しています。
- 定跡変換ツール
  - [BookConv](https://github.com/ai5/BookConv)
- その他
  - [なんでも棋譜変換 - SHOGI-EXTEND](https://www.shogi-extend.com/adapter)