CSA 形式
CSA 標準棋譜ファイル形式は、コンピュータ将棋協会(CSA)が定めた標準的な棋譜交換フォーマットです。異なる将棋ソフト間でのデータ交換を可能にするために設計されています。
公式仕様
- CSA標準棋譜ファイル形式 V2.1 - 2005年9月10日版
- CSA標準棋譜ファイル形式 V2.2 - 2008年1月12日版
- CSA標準棋譜ファイル形式 V3.0 - 2024年5月14日版(最新)
概要
CSA形式は以下の特徴を持ちます:
- テキストファイル形式で処理が容易
- プログラムによる解析を重視(人の可読性より機械処理を優先)
- 標準化された駒と位置の表記
- バージョン管理により仕様の拡張に対応
ファイル構造
CSA棋譜ファイルは以下の順序で構成されます:
- 文字コード宣言(V3.0以降)
- バージョン情報
- 棋譜情報(対局者名、棋戦名など)
- 開始局面(持駒、手番を含む)
- 指し手と消費時間
- コメント
セパレータ(/だけの行)で区切ることで、複数の棋譜を1ファイルに記録できます。
rsshogi では parse_csa_games() / parse_csa_games_bytes() /
Record.from_csa_games_str() / Record.from_csa_games_file() が全局を返します。
単一棋譜を返す parse_csa_str() / parse_csa_bytes() / Record.from_csa_str() は
最初の1局だけを返します。
基本表記
文字コード(V3.0以降)
ファイル先頭で文字コードを宣言します:
'CSA encoding=UTF-8
UTF-8またはSHIFT_JISを指定可能- この行がない場合は
SHIFT_JISと判断(過去の互換性)
rsshogi の読み込みは宣言行に依存せず、UTF-8 として解釈を試みて失敗したら Shift_JIS へフォールバックします。宣言行自体は読み飛ばします。書き出しは V3.0 を指定したときだけ 宣言行を出力し、その内容は実際の出力エンコーディングと一致します。
バージョン
V3.0
現在のバージョンは以下の通り:
- V3.0 (2024年5月14日) - 最新版
- V2.2 (2008年1月12日)
- V2.1 (2005年9月10日)
- V2 (2002年11月15日)
バージョンがない場合は、1997年8月25日の仕様と判断されます。
rsshogi の読み込みはバージョン行を読み飛ばし、V2.2 / V3.0 のどちらの記法も受理します。
書き出しの既定は V2.2 で、ExportOptions::with_csa_version(CsaVersion::V3_0)
(Python では record.to_csa(version="3.0"))を指定すると V3.0 を出力します。
なお $MAX_MOVES / $JISHOGI / $NOTE のような V3.0 追加キーは、V2.2 出力でも
保持したまま書き出します。厳密には V2.2 の仕様外ですが、キーを落とすとデータが
失われるため、互換性より情報の保存を優先しています。既存の読み手は未知の $ キーを
読み飛ばします。
駒の表記
| 駒種 | 表記 | 成駒 | 表記 |
|---|---|---|---|
| 歩 | FU | と | TO |
| 香 | KY | 成香 | NY |
| 桂 | KE | 成桂 | NK |
| 銀 | GI | 成銀 | NG |
| 金 | KI | - | - |
| 角 | KA | 馬 | UM |
| 飛 | HI | 龍 | RY |
| 玉 | OU | - | - |
位置の表記
- 2桁の数字で表記:
11(1一)~99(9九) - 駒台は
00 - 先手(下手)は
+、後手(上手)は-を付ける
例:
+2726FU:先手が2六歩(27→26)-8384FU:後手が8四歩(83→84)
棋譜情報
対局者名
N+先手の名前
N-後手の名前
各種情報($で開始)
$EVENT:棋戦名
$SITE:対局場所
$START_TIME:2024/05/05 15:05:40
$END_TIME:2024/05/05 15:31:22
$OPENING:戦型名
持ち時間(V3.0で改定)
$TIME:900+0+5
形式:(初期持ち時間)+(秒読み)+(フィッシャー方式加算)
- 単位は秒
- 小数点でミリ秒単位まで記述可能(最大3桁)
- 切れ負けの場合、秒読みを
0とする
例:
$TIME:1500+0+0 # 25分切れ負け
$TIME:1800+30+0 # 30分 + 秒読み30秒
$TIME:0+30+0 # 初手から30秒秒読み
$TIME:900+0+5 # フィッシャー方式: 初期900秒、加算5秒
先手と後手で持ち時間が異なる場合:
$TIME+:450+0+5 # 先手
$TIME-:900+0+5 # 後手
V3.0 仕様は本文で $TIMET+: / $TIMET-: と綴っていますが、同じ仕様の例は
$TIME+: / $TIME-: です。rsshogi はどちらの綴りも受理し、書き出しは例に合わせた
$TIME+: / $TIME-: に正規化します。
その他の情報(V3.0で追加)
$MAX_MOVES:320 # 最大手数
$JISHOGI:27 # 持将棋ルール(24点法/27点法)
$NOTE:備考1行目\n2行目\\ # 備考(\nで改行、\\で\)
開始局面
平手初期配置
PI
駒落ち
平手から落とす駒を指定:
PI82HI22KA # 二枚落ち
一括表現
1行ごとに駒配置を記述:
P1-KY-KE-GI-KI-OU-KI-GI-KE-KY
P2 * -HI * * * * * -KA *
P3-FU-FU-FU-FU-FU-FU-FU-FU-FU
P4 * * * * * * * * *
P5 * * * * * * * * *
P6 * * * * * * * * *
P7+FU+FU+FU+FU+FU+FU+FU+FU+FU
P8 * +KA * * * * * +HI *
P9+KY+KE+GI+KI+OU+KI+GI+KE+KY
- 1枡3文字で9枡分を記述
- 先後の区別が
+/-以外のとき、駒がないとする
駒別単独表現
個別に駒の位置を指定:
P-22KA # 後手の2二角
P+99KY # 先手の9九香
P+00KIOOFU # 先手の持駒:金と歩
P-00AL # 後手の残り全ての駒
手番
+ # 先手番
または
- # 後手番
手番の指定は必須です。
指し手
通常の指し手
形式:(先後)(移動前)(移動後)(駒名)
+2726FU # 先手 2六歩
-3334FU # 後手 3四歩
+2625FU # 先手 2五歩
先後を表す + / - は指し手表記の必須要素です。rsshogi の Move32.to_csa() は
この記号を含む形(+7776FU)を返します。手番は Move32 が保持する移動後の駒の色から
決まるため、駒情報を持たない Move32(Move32.from_usi() で生成したもの)では None を
返します。
読み込み側の Board.move_from_csa() は、記号付き(+7776FU)と記号なし(7776FU)の
どちらも受け付けます。記号付きの場合は局面の手番と一致することを検証します。
棋譜 parser(parse_csa_str() / Record.from_csa_str())は指し手行の記号を必ず検証し、
手番と食い違う行を CsaError::MoveSideMismatch で拒否します。指し手自体は合法でも拒否
するため、error は原文の行を保持します。
消費時間
T に続いて秒単位で記述:
+2726FU
T15
-3334FU
T6.123 # ミリ秒単位(V3.0以降)
消費時間は省略可能です。
rsshogi はミリ秒表記を読み込んで time_ms に保持します。書き出しでは、仕様が
「必要な場合だけ」と定めているのに従い、V3.0 を指定し、かつ端数がある場合だけ
小数を出力します。V2.2 出力では秒へ切り捨てます。消費時間を持たない指し手には
T 行を出力しません(T0 を捏造しません)。
終局状況
% で始まる特殊な表記:
%TORYO # 投了(消費時間記録可能)
%CHUDAN # 中断
%SENNICHITE # 千日手
%TIME_UP # 時間切れ(手番側の負け)
%ILLEGAL_MOVE # 反則負け(手番側)
%+ILLEGAL_ACTION # 先手の反則行為により後手の勝ち
%-ILLEGAL_ACTION # 後手の反則行為により先手の勝ち
%JISHOGI # 持将棋
%KACHI # 入玉宣言勝ち
%HIKIWAKE # 入玉宣言引き分け
%MAX_MOVES # 最大手数到達(V3.0)
%TSUMI # 詰み
%FUZUMI # 不詰
%ERROR # エラー
%... の終局行の直後に続く T...(消費時間)と '*...(プログラムコメント)も記録できます。
rsshogi ではこれらを終局特殊手に保持し、to_csa() で再出力します。
終局 %... 行が欠けた棋譜も受理でき、その場合は main_terminal == None /
result == GameResult::Invalid として保持します。
勝敗の割り当ては上のコメントどおりです。%ILLEGAL_MOVE は手番側の負けなので勝つのは
その相手、%+ILLEGAL_ACTION / %-ILLEGAL_ACTION は反則側を記号自身が示すため手番に
依存しません。
読み込んだ終局マーカーは原文のまま保持し、to_csa() はそれを優先して書き戻します。
%+ILLEGAL_ACTION のように内部表現へ畳むと戻せないマーカーがあるためです。
不戦勝・不戦敗・トライには CSA に対応するマーカーがないので、勝敗を主張しない
%CHUDAN として書き出します。
プログラムが読むコメント(V3.0追加)
通常のコメント
'* で始まる行はプログラムが読むコメント:
'*コメント1行目
'*コメント2行目
rsshogi では Record に保持する move / terminal comment を to_csa() で
この '*... 形式にして出力します。parser 側も CSA 3.0 の定義に合わせ、
'*... だけをプログラムが読むコメントとして取り込み、plain な '... は
読み飛ばします('CSA encoding=... は文字コード宣言)。
手番行(+ / -)の後から初手までに現れる '*... は開始局面コメントとして
Record.initial_comment / Record::initial_comment() に保持され、
to_csa() でも手番行直後へ書き戻されます。互換性のため、手番行より前の
'*... も受理して initial_comment に正規化します。
この理由は、CSA 3.0 では '*... と '... の意味が明確に分かれている一方、
既存ツールでは手番行前の '*... を開始局面コメントとして扱う例があるためです。
$NOTE: は RecordMetadata.comment に対応し、匿名の '... ヘッダ行は
メタコメントへは取り込みません。
終局特殊手がない Record を to_csa() すると、終局 %... 行は出力されません。
評価値・読み筋・ノード数
'** に続いて記述:
'** 30 +7776FU -9394FU +7968GI #1234
形式:'** (評価値) (読み筋) #(ノード数)
- 評価値は整数(先手有利がプラス、後手有利がマイナス)
- 先手勝ちの評価値は
30000、後手勝ちは-30000を推奨 - 読み筋は指し手を半角空白で区切る
- ノード数は
#の後に記述
読み筋内の特殊表記:
+PASS # 先手番のパス
-PASS # 後手番のパス
%TORYO # 投了
%KACHI # 入玉宣言勝ち
%SENNICHITE # 千日手
%MAX_MOVES # 最大手数
%REP_SUP # 優等局面
%REP_INF # 劣等局面
rsshogi では評価値を EngineInfo.eval、ノード数を EngineInfo.nodes に取り込みます。
読み筋は上記の特殊表記を含むうえ再生に局面が必要なため、型付けせず原文のまま
EngineInfo.extras["csa_pv"] に保持します。
CSA の評価値は先手視点ですが、CSA 入出力では既存の wire 互換性を維持するため数値を
符号変換せず保持します。このため、CSA から読み込んだ EngineInfo.eval は、着手前局面の
手番側視点という通常の契約に対する形式固有の例外です。
評価値として解釈できない '** 行は extras["csa_analysis_raw"] に原文を退避し、
to_csa() でそのまま書き戻します。Eval は i16 なので、範囲外の評価値('** 100000
など)も数値化せず原文で往復させます。同じ指し手に複数行あっても上書きせず全て保持します。
終局行の直後に付く '** は終局特殊手に保持します。開始局面に付く '**(初手より前)は
保持できず読み飛ばします。
非標準の '**評価値=30 表記も読み込みだけ受理し、書き出しは仕様形式の '** 30 に
正規化します。数値として読めない '**評価値= は原文のまま退避します。
プログラムが読み飛ばすコメント
'(アポストロフィー)で始まる行:
'これはコメントです
マルチステートメント
,(カンマ)で複数行を1行にまとめることができます:
+2726FU,T15
ファイル例
'CSA encoding=UTF-8
'----------棋譜ファイルの例 "example.csa"---------------
'バージョン
V3.0
'対局者名
N+先手
N-後手
'棋譜情報
'棋戦名
$EVENT:34th World Computer Shogi Championship
'対局場所
$SITE:INTERNET
'開始日時
$START_TIME:2024/05/05 15:05:40
'終了日時
$END_TIME:2024/05/05 15:31:22
'持ち時間:フィッシャー方式、初期持ち時間:900秒、加算:5秒
$TIME:900+0+5
'戦型:矢倉
$OPENING:YAGURA
'最大手数:320
$MAX_MOVES:320
'持将棋ルールは、27点法
$JISHOGI:27
'備考
$NOTE:備考1行目\n2行目
'平手の初期局面
P1-KY-KE-GI-KI-OU-KI-GI-KE-KY
P2 * -HI * * * * * -KA *
P3-FU-FU-FU-FU-FU-FU-FU-FU-FU
P4 * * * * * * * * *
P5 * * * * * * * * *
P6 * * * * * * * * *
P7+FU+FU+FU+FU+FU+FU+FU+FU+FU
P8 * +KA * * * * * +HI *
P9+KY+KE+GI+KI+OU+KI+GI+KE+KY
'先手番
+
'指し手と消費時間
+2726FU,T0
'評価値、読み筋、ノード数
'** 30 -8384FU +2625FU -8485FU +6978KI -4132KI +3938GI -7172GI #1234
-3334FU
'ミリ秒単位の消費時間
T6.123
'*プログラムが読むコメント1行目
'*プログラムが読むコメント2行目
%CHUDAN
'-------------------------------------------------
rsshogi での対応状況
サポート済み
- ✅ V2.1/V2.2/V3.0 形式のパース
- ✅ 基本的な棋譜情報の読み込み
- ✅ 平手・駒落ち局面の解析
- ✅ 指し手と消費時間の解析(手番記号と手番の一致を検証)
- ✅ 終局状況の解析
- ✅
'*...プログラムコメント行の取り込みと再出力(plain な'...は読み飛ばし) - ✅ 手番行前後の
'*...をinitial_commentとして往復 - ✅
%...終局行に続くT.../ コメント行の保持 - ✅
$TIME+/$TIME-/$MAX_MOVES/$JISHOGIの取り込み - ✅
$NOTEのRecordMetadata::commentへの取り込みと再出力 - ✅
/区切りのマルチ棋譜(parse_csa_games()/parse_csa_games_bytes()) - ✅ CSA 形式への出力(
ExportOptions::with_csa_version(CsaVersion)で V2.2 / V3.0 を選択) - ✅ 評価値・ノード数・読み筋(原文)を
'**行として書き戻す。解析できなかった'**行も原文のまま往復する
CSA writer は本手順を出力します。
バージョン間の主な変更点
V3.0 (2024年5月14日)
- 文字コード(UTF-8/SHIFT_JIS)の明示的な記述
- 持ち時間表記の改定(フィッシャー方式、ミリ秒対応)
- 消費時間のミリ秒単位対応
- 評価値・読み筋・ノード数の記録機能
- 棋譜情報に最大手数、持将棋ルール、備考を追加
- %MAX_MOVES の追加
- %MATTA の削除
V2.2 (2008年1月12日)
- %+ILLEGAL_ACTION の追加
- %-ILLEGAL_ACTION の追加
V2.1 (2005年9月10日)
- %TIME_UP の追加
- %ILLEGAL_MOVE の追加
V2 (2002年11月15日)
- バージョン表記の導入
- 棋譜情報の拡充