SGF解析

SGF解析

上級

説明

Smart Game Formatの文字列を解析します。

SGFは、ボードゲームのファイル、とくに囲碁の棋譜を保存するための標準フォーマットです。

SGFは比較的シンプルなフォーマットです。SGFファイルには通常、ノードの木構造が1つだけ含まれており、各ノードはプロパティリストです。プロパティリストにはキーと値のペアが含まれ、各キーは1回しか登場しませんが、複数の値を持つことができます。

この演習では、SGFの文字列を解析し、プロパティの木構造を返します。

SGFファイルは次のようになっています。

(;FF[4]C[root]SZ[19];B[aa];W[ab])

これは3つのノードを持つ木構造です。

  • 最上位のノードには3つのプロパティがあります。FF[4](キーは"FF"、値は"4")、C[root](キーは"C"、値は"root")、SZ[19](キーは"SZ"、値は"19")です。(FFはSGFのバージョン、Cはコメント、SZは盤面のサイズを表します。)
    • 最上位のノードには子が1つだけあり、その子はプロパティを1つだけ持ちます。B[aa]です。(黒が"aa"としてエンコードされた交点、つまり1-1の点に打ちます。)
      • B[aa]のノードには子が1つだけあり、その子はプロパティを1つだけ持ちます。W[ab]です。

ご想像のとおり、SGFファイルには子を1つだけ持つノードがたくさんあります。だからこそ、そのための省略記法が用意されています。

SGFは、手順のバリエーションを表現できます。囲碁を打つ人は検討の中で何度も手を戻します(これを試してみよう、うまくいかない、ではあれを試そう)し、SGFはそうした手順のバリエーションを扱えます。たとえば、次のようになります。

(;FF[4](;B[aa];W[ab])(;B[dd];W[ee]))

ここでは、ルートノードに2つのバリエーションがあります。1つ目(慣例により、実際に打たれた手を示します)は、黒が1-1に打つものです。黒は先生からこのファイルを受け取りました。先生は、ルートノードの2つ目の子にある、より理にかなった手を指摘しました。それがB[dd]です(4-4の点で、隅を取るごく標準的な布石です)。

1つのキーに複数の値を関連付けることができます。たとえば、次のとおりです。

(;FF[4];AB[aa][ab][ba])

ここでは、AB(黒を追加)を使って、盤面に黒石を3つ追加しています。

プロパティの値はすべてSGF Text型です。他の値の型を実装する必要はありません。Text型の完全なドキュメントも読めますが、重要な点のまとめを以下に示します。

  • 改行は、\の直後にある場合は削除され、それ以外の場合は改行のまま残ります。
  • 改行以外の空白文字はすべてスペースに変換されます。
  • \はエスケープ文字です。\の後にある空白以外の文字は、そのまま挿入されます。\の後にある空白文字は、上記のルールに従います。SGFには、\tや\nのような空白文字のためのエスケープシーケンスはありません。

次の2つを混同しないよう注意してください。

  • テスト内で文字列リテラルとして表現されている文字列
  • SGFパーサーに渡される文字列

文字列リテラル内のエスケープシーケンスは、SGFパーサーに渡される前に、そのプログラミング言語のパーサーによってすでに処理されている場合があります。

SGFには(そして一般に解析には)、もう少し複雑な点がいくつかありますが、ほとんどは無視してかまいません。入力はUTF-8でエンコードされているものと想定してください。テストにはcharsetプロパティが含まれないので、そこは気にしなくて大丈夫です。さらに、改行はすべてunixスタイル(\nで、テストに\rや\r\nは含まれません)であり、プロパティやノードなどの間の省略可能な空白もテストには含まれないものと想定してかまいません。

GitHubで編集する リンクは新しいウィンドウまたはタブで開きます
Roc Exercism

SGF解析を始める準備はできましたか?

Exercismに登録すれば、120個の演習、そして本物の人間によるメンタリングとともに、Rocを学んでマスターできます。すべて無料です。