元のKIFと,それをJSONに直したときの例です.
もっとも,今のままでは不便な所があります.
例えば,
・連想配列のキーが日本語なので,プログラムで利用する時にobj["対局ID"]のように日本語で書かなければならないので,英単語などに置き換える
・消費時間やリーグ成績は先手と後手に属する情報にしたほうが良さそう
→たとえば
"players": [
{
"name": "広瀬章人",
"result": {"win": 3, "lose": 3},
"time": 479
},
{
同様に後手
}
]
のようにする等.これだとプレイヤーの属性について,例えば段やタイトルの情報も付け加える事が出来ます.
・駒取りの時,取った駒の情報を入れないと,手順の逆再生時に困るか?
・成も成る前の駒情報を入れる?
ちなみに,今考えているのは,会合のほうでも少しお話ししましたが,設定ファイルを分離して持つものです.
ルール(本将棋,どうぶつしょうぎ,・・・)ごとにルール情報ファイルを決めておきます.
棋譜自体のほうには,どのルールの棋譜なのか,rule: "shogi.rule.json"などと書いておくようにします.
こうすることで,新しいルールへの対応が非常に簡単になります.
例えば大将棋の棋譜を手に入れたが,自分が普段使っているソフトでは対応してなかったとします.
ソフトはファイルのrule部分を見て,「"daishogi.rule.json"には対応していません」と文句を言います.
そんな時,daishogi.rule.jsonというファイルをググってきて誰かが公開した(規格の公式サイトに
置けるようにしているなら,そこからでも)ダウンロードしてきて,自分のソフトのrulesディレクトリに
保存すれば,もうこのソフトは何のルールでどんな駒があるのかを理解できるというわけです.
もちろん,大将棋も対応するとなったら,9x9より大きくてもインターフェイスが
変にならないように気を使う必要がありますが,まあ嫌ならルールファイルに書いてあるサイズを見た後に
「盤面がでかすぎるのでダメです」とか言えばいいでしょう.
そのルールファイルの例です.
駒の表記(伝統形式,PSNのようなチェスライク形式)も切り替えられるように,
traditionalとchesslikeの2つの情報が入っています.kanaというのを増やして"fu" "kyo"のようにできてもいいかもしれません.
shogi.rule.json:
{
size: [9, 9], //9かける9
species: {
traditional: {
"0": "歩",
"1": "香",
~~~中略~~~
},
chesslike: {
"0": "P",
"1": "L",
~~~中略~~~
}
},
initial: { //初期情報
"ban": [ //初期局面
{player: 1, species: 1}, {player: 1, species, 2}, ~~~//香,桂
~~~
]
}
}
doubutsushogi.rule.json
{
size: [3, 4],
species: {
traditional: {
"0": "ひよこ",
"1": "きりん",
"2": "ぞう",
"3": "ライオン",
"4": "にわとり",
},
english: {
"0": "baby bird",
~~~
}
},
"init": {
~~~
}
}
init.banのところでさらりと盤面の表記をしてしまいましたが,1マスを
{player: 1, species: 2}
で表すのは冗長なので,
[1, 2]
のように「0番目はplayerで1番目は種類だよ」と確約しておいてもいいかもしれません(将棋ったーではそうしています)
まあ,おおざっぱにはこんなところです.
2011年9月15日0:39 ginsho <kzde...@gmail.com>:
> --
> ginsho会(仮) - http://groups.google.com/group/shogi-developers
>
--
na2hiro (http://81.la)
twitter: @na2hiro
「きりん +」「ぞう x」「らいおん o」「ひよこ '」「にわとり *」
を考えたのですが、これだとプログラムは書きにくいですか?
1手ごとに局面を持つのは冗長すぎる気がします.指し手情報だけで順・逆方向の盤面再生ができれば
十分ではないかと思います.
Hidetchiさんの提案とも関係してきますが,この棋譜に初期の局面,持ち駒,手番を持てるようにしてから,
この棋譜形式自体を配列として持つ「棋譜集」形式のようなものを定義すればいいのではないかと思います.
具体的には,棋譜形式を
{
"init": {
"ban": [
初期配置
],
"mochigoma": [
初期持ち駒
],
"teban": 初期手番
},
"players":
~~~以下同様
}
のように開始時の盤面を持てるようにします.
そして,
{
"title": "1手詰め集", //棋譜集に関する情報
"author": "誰々",
"collection": [ //実際の棋譜集
{ //棋譜1
"init": {~},
~
},
{ //棋譜2
"init": {~},
},
~
]
}
という,棋譜を内包する「棋譜集」形式を使って,局面の集合を表すと良いのではないでしょうか.
これなら,それぞれの要素は普通の棋譜形式なので,棋譜やコメント,プレイヤー情報等を持たせる事も出来ます.
これで箇条書きであげられたそれぞれのものを表す事ができるのではないでしょうか.
> それからもうひとつ。棋譜とルール定義の分離で思いついたのですが、
> これ、完全な指し手情報を持つ「親棋譜」と、任意の指し手に対する任意のパラメータしか持たない「子棋譜」
> を用意し、組み合わせて利用することにも使えるでしょうか?
>
> 例えば、ライブ中継されている親棋譜に対して、棋譜ビューア側が
> ・コメントのみ記述された子棋譜をミックス表示して、多言語同時中継
> ・AIの形勢判断のみ記述された子棋譜をミックス表示して参照
> ・変化手順のみを記述された子棋譜をミックス表示して本筋と比較参照
継承とか上書きのようなものですね.面白そうです.
子棋譜中に override: "親棋譜ファイル名" と書いておき,子棋譜が読まれたらまず親棋譜を読み込んだ後に
上書きするような感じですか.ファイル側ではこれさえ書いておけば十分かと思います.
> どうぶつしょうぎ=3x4将棋の棋譜ですが
> 「きりん +」「ぞう x」「らいおん o」「ひよこ '」「にわとり *」
> を考えたのですが、これだとプログラムは書きにくいですか?
表示側の話なので,どんな記号でも問題ないと思います.
Hidetchiさんのおっしゃる通り,見た目がどうかという話になります.
> 棋譜ファイルを使って何かソフトを作る側からの意見をいいますと,
> 「手」の情報のみから色々なことが分かる方が有難いです.
> たとえば,英語の表記では
> ・単に▲5五角 → B-5e
> ・駒を取りながら▲5五角 → Bx5e
> と変化します.
> つまり駒を取る手かどうかの情報を「手」の中に入れてくれないと,
> ただ英語表記にしたいだけなのに,いちいち前の局面を参照しないといけません.
> (つまり初手から再生しないといけません)
> 日本語でも,「同」をつけるかどうかの判断には,1手前の参照が要りますね.これも面倒です.
> CSA形式はその面でもっと不便で,その手が成りなのか,もとから成り駒だったのかすら,
> 前の局面を参照しないと分からないです.
同意です.
・取った駒の種類を持つ
・成った時に分かるようにする
・「同」が曖昧なので元の座標も持つようにする
が必要ですね.
あと,
> ※成った前と後の駒の種類を記録しておく件は,その必要があるかどうかよく分かりません.
> ルールファイルに「歩⇔と」などの対応関係を定義してもよい気もします.
ですが,確かにそうですね.将棋ったーで100種類のルールを作ってきましたが,
駒の表裏の関係が崩れたことは一度もなかったので,表裏対応をルールファイルに書くのは良い案だと思います.
それなら,通常の移動情報に加えて成ったというフラグを1つ持たせるだけで良いですね.
ルールファイルに持たせる表記としては,例えば
0が歩, 9がと金となっていたとして,
"nari": {
"0": 9, //歩: と金
"1": 10, //香: 成香
~~~
}
というのがひとつの方法ですね.
> ※ところで,本将棋とどうぶつしょうぎでルールファイルを分けるのは分かりましたが,
> 駒落ちも全て分けるのですか? (初期局面がそちらに入っていたので)
> ルールファイルは統一して,初期局面と初手の手番のみ
> 棋譜ファイルの方に書いても良い気がします.
> 詰将棋などの場合もあるので,初期局面と手番を棋譜ファイルが保持できないようでは
> 使い道がせばまると思います.
初期局面を指定できるようにするのは作ったほうがいいと思いますが(上のほうでも書きましたが),
駒落ちの棋譜ファイル全てに初期局面を指定する必要があるのはスマートではないと思います.
それに,もしルールで分けずに初期局面で分けるとなると,プログラムはそれが香落ちであっても
平手なのか香落ちなのか分かりません.といって,"teai": "香落ち"と棋譜に持たせようとするのは,
外国語環境向きでないので,何かの記号に置き換えればいいわけですが,それならいっそ
rule: "kyoochi.rule.json"を持てば良いのではないでしょうか.そしてルールファイルのほうで多言語の表記を
用意しておくわけです.
1手ごとに局面を持つのは冗長すぎる気がします.指し手情報だけで順・逆方向の盤面再生ができれば
十分ではないかと思います.
・「同」が曖昧なので元の座標も持つようにする
が必要ですね.
駒落ちの棋譜ファイル全てに初期局面を指定する必要があるのはスマートではないと思います.
それに,もしルールで分けずに初期局面で分けるとなると,プログラムはそれが香落ちであっても
平手なのか香落ちなのか分かりません.といって,"teai": "香落ち"と棋譜に持たせようとするのは,
外国語環境向きでないので,何かの記号に置き換えればいいわけですが,それならいっそ
rule: "kyoochi.rule.json"を持てば良いのではないでしょうか.そしてルールファイルのほうで多言語の表記を
用意しておくわけです.
棋譜が局面情報を持たないという選択はこのような高い検索性を捨てることになるのですが、ずいぶんもったいない話だと思いませんか?
確かに同の座標はあってもなくてもいいですね.
JSONならパースの時点で内部的な(メモリ上の)構造になってしまうので,全ての手で前後へのポインタを
持つのはあまり冴えないと思いますが,分岐は擬似的にポインタのようなものが必要そうですね.
例えば
{
0: [ //メイン
{kifu: 1手目},
{kifu: 2手目},
{kifu: 3手目, bunki: [1]},//1番の分岐へ
{kifu: 4手目}
]
1: [ //1番の分岐
{kifu: 3手目2},
{kifu: 4手目2}
]
}
という感じです.
> 「同」よりも面倒なのが「上」とか「直」とかですが、これは1手前の局面を参照しなければいけないですよね。
> こういうのまで手の中で保持するのはさすがにスマートではないとなると、結局、前局面の生成は自分でやるしかないですか。。
同や上など,いちいち局面を生成しなくてはわからないけど人間が欲しい情報は,保存したいところですね.
> ところで、例えば次の1手のような問題図を表示したいとき、その局面を初期局面として棋譜ファイルを作った場合を考えますと、
> 図面の上には「○手目○○まで」という表示が要る場合があります。
> ということは、初期局面にも「前の手」や「○手目」などの情報が必要なのですね。
> それどころか「図は△2四同歩まで」などという場合もありますから、「同」を判断しようとすると、
> やはりフラグを立てるか、初期局面の2手前の手まで保持する必要が・・・
開始手数についてはinit配下にtesuu変数を用意すれば良いですね.
「△2四同歩まで」についてですが,最初に特に触れなかったのですが,慣例的に行われている「初期局面のコメント」
を実現するために指し手の0番目は指し手を書かずに初期コメントだけ書くようにしています.
たまたまですが,この0番目の位置に「△2四同歩」にあたる棋譜を書けばすっきり収まりそうです.
> 棋譜が指し手の局面情報を持つことのメリットを書いてみます。まず、高い検索性について。
なるほど.局面の一致検索を棋譜ファイルで行うのは気づきませんでした.確かにその用途となると便利ですね.
棋譜ベースではなく局面ベースのデータベースは@koudayuさんも着目されていますし,
(http://www.flatz.jp/archives/112 ※4年前) 自分も将棋ったーが一段落したら作ろうかと思っていました.
しかし,データベースに限らず,そこかしこに局面表記を埋め込んで検索でなんでも出てくるというのは
将棋界のユートピアかもしれませんね.全く知らないサイトでも,局面ハッシュの埋め込まれた棋譜さえ
張ってあれば,自分の探してる局面にすぐにたどり着ける訳ですね.
局面ハッシュは,少し前に局面データベースのために調べたので多少知っているのですが,
局面→ハッシュの単方向ならZobrist Hashingがコンピュータ将棋で使われる事が多いです.
http://yowaken.dip.jp/tdiary/20081001.html
予め11~99×歩~龍とでランダムなビット列を決めておき,動かすたびに局面の差分にあたるビット列を
局面ビット列に対しXORを取ります.76歩なら"77の歩"と"76の歩"にあたるビット列の2つをXORします.
どう経由しても同じ局面なら同じハッシュになり,その逆は,ハッシュ長で衝突を調整します.
1手ごとに数回XORするだけ非常に低コストかつ短いです.
この方法だと固定長で,多分やりやすい32bitsか64bitsでやることになると思います.
復元可能な圧縮としては,出現頻度を用いたハフマン符号化を行った方がいます.
http://www.geocities.co.jp/CollegeLife-Cafe/8331/shogi/index.html
可変長で,200bits程度だということです.
ちなみにWeb検索可能となると大文字小文字も区別できないので0-9a-zくらいでしょうか.
0-9a-vの32通りで5bitsを表せるので, バイト数=ビット数/5 程度の長さになりそうです.
前者なら7or13バイト,後者なら40バイト程度ですね.
自分は,横方向(ファイル間・サイト間)の一致検索さえできれば,あとはそれぞれの棋譜で縦(指し手)を辿れるので,
局面の逆算はそれほど必要ないのではないかと思いますが,何か逆算できたら嬉しい例などありますでしょうか.
いえ,棋譜ではなく1局面ごとに,11に玉がいる局面には"11玉"という文字列が含まれているような表現を考えていました.
とくに読み違いはないような気がします.
> p=1b000000000004001b0000001600000000001d00191d001d10001d000000171d001d00000e1d0000000800000005000e00000e0e000000000a0e0e0200000e000008000000000e000c000007001500000071;
>
> JSON棋譜が上記のような非圧縮のストレートな局面情報を持っている場合、1三の後手歩と3三の後手桂だけを選び、
> 複数の棋譜ファイルを対象に部分一致局面を探す場合は、
>
> /.{18}.{18}1d..19.{12}.{18}.{18}.{18}.{18}.{18}.{18}/
>
> みたいな正規表現で該当ファイルをピックアップできると思います。
> しかし非可逆のハッシュ、あるいはSFENのような圧縮記述ですと上記のようにシンプルな検索が
> 出来なくなるのでは?と思い、先の質問となった次第です。実際、研究用途の検索を考えると完全一致局面より
> は部分一致検索の方が重宝しする場面が多そうな気もしまして。
たしかに固定長で盤面符号を持てば正規表現で検索できます.
しかしJSONテキストのままの検索を常用するのが得策とは思えないのですが…
簡易的なものとしてあったほうがいいというならいいと思います.
他の方の意見も伺いたいです.
これを採用するなら,Web検索の局面一致のために大文字小文字を同一視すると,
だいたい0-9a-zの36通りを1バイトで表せます.マスの状態は 空白1+先後2*種類14=29なので
ちょうど1マス1バイトで表せますね.81マスで81バイト.
あとは手番と持ち駒ですが,単純にやると手番1バイト駒7種類1バイトずつ(36枚以下なので)で8バイト.
縮めるなら,手番1ビット,歩5ビット(0~18枚<=2^5),桂香銀金3ビット(0~4枚<=2^3)*4種,
飛角2ビット(0~2枚<=2^2)*2種
で22ビット,1バイトで5ビット表せるので5バイト分ですね.
1局面を86~89バイトで表すことになりそうです.
> わかりました。とりあえず現状のJSON棋譜についてはshogitterからダウンロードして予習しておきます。
将棋ったーのJSONはここで話しているのとは違って独特な部分があるので
あまり参考にならないかもしれません.
余談ですが,この新形式ができたら,将棋ったーもそれに沿うように変更できればと思っています.
新形式の拡張として,棋譜で,移動元,移動先,駒種の他に,他のマスの差分情報を持つものです.
将棋ったーの棋譜は移動元という区別はあまりしておらず,全てマスの差分なので
扱いづらい部分があったので,移動元移動先と差分を組み合わせると良いと思います.
(正確には,差分の1番目が移動先の座標,2番目が移動元になっています)
例えばキルケ(取られた駒が初期位置に戻る)で,24歩と角を取ってその角が22に戻る場合,
{
from: [2,5],
to: [2,4],
species: "歩",
diff: [
{
type: "持ち駒",
player: "先手",
species: "角",
num: -1
},
{
type: "盤面",
place: [2,2],
species: "角",
player: "後手"
}
]
}
ふつうに24歩と取った後,diffに従って先手の角を1枚減らして22に置く感じです.
diffがなければふつうの将棋と同じです.
> 拙作KZ制作時に、KIF、CSA、PSNの記述方法を比較するために作ったExcelの資料がありますので、dropboxに上げておきます。
> PSNの箇所など不正確&わかりにくい記述が多々あるかと思うんですが、なにかしらお役に立てましたら幸いナリです。
>
> http://dl.dropbox.com/u/2385159/kifu_format.zip
ありがとうございます.参考にしたいと思います.
--
na2hiro (http://81.la, http://shogitter.com)
twitter: @na2hiro
棋譜フォーマットの草案を拝見しました。
ハッシュ値を含む際に、1マス毎の表記を候補に入れているのは、
ginshoさんのSFENでは正規表現による部分局面検索がスマートに出来ないのでは?
という発言を受けてのことだと思いますが、SFENでも出来ると思います。
例えば、先手振り飛車穴熊 対 後手居飛車穴熊の例を考えてみます。
玉周辺部分だけを考えたものをSFENで表すと次のようになります。
6gnk/6gsl/6ppp/9/9/9/6PPP/6GSL/6GNK
これを局面図画像に直すと次のリンクになります。
http://sfenreader.appspot.com/sfen?sfen=6gnk%2F6gsl%2F6ppp%2F9%2F9%2F9%2F6PPP%2F6GSL%2F6GNK%0D%0A
そしてこれを含む局面図を検索したいと思ったら次のような正規表現になると思います。
.*gnk\/.*gsl\/.*ppp\/.*\/.*\/.*\/.*PPP\/.*GSL\/.*GNK
#間違い、反例があったらご指摘お願いします。
.*の部分はなんでもOKの意味で、/は正規表現では特別な文字なのでバックスラッシュでエスケープしてます。
banhashは同一局面図検索を高速に行うなどの目的で必要だと思いますが、
それとは別にsfenというフィールドを用意して、局面のsfen文字列をそのまま入れることは出来ないでしょうか。
ただ、膨大なsfen文字列を正規表現で検索して
高速に処理が出来るかどうかは一考の余地ありだとは思います。
>ginshoさん
以前出たsfenの拡張は最終着手の色分けだったと思いますが、
今回は棋譜データそのものの策定なので、
個人的にはsfenそのものの拡張には意味を見出していないのですがどうでしょうか
--
fantakeshi <fanta...@gmail.com>
はじめまして.よろしくお願いします.
脱退は参加者自らおこなえるようです.
http://groups.google.com/support/bin/answer.py?hl=jp&answer=46608
> さて、このトピックスで局面ハッシュの話が出ていました。
> 我々のところでは局面検索用にハッシュを考えていたのですが先日やめました。
> 局面はそのままでも530ビット程度で表現できるためです。(独自形式ですが 534bitで表現しています)
> そうするとハッシュの衝突も考慮しなくてよくなるので。
確かに単方向だと衝突する可能性はありますね.
ただハッシュ長を長くすれば十分対応できるのではないかと思います.
Zobrist Hashingは,XORをとるだけなので,今まで64bitだったのをあとから128bitに拡張すると
いうことになっても,頭の64bitはそのまま残して末尾64bitを足すだけで良いので,
最悪あとで衝突が見つかって伸ばしたくなったとしても,混乱は避けられると思います.
128bitになったあとでも,先頭の64bitだけ切り取って検索すれば,古い64bitのハッシュを使った
棋譜を検索できますので.
> 玉周辺部分だけを考えたものをSFENで表すと次のようになります。
> 6gnk/6gsl/6ppp/9/9/9/6PPP/6GSL/6GNK
>
> これを局面図画像に直すと次のリンクになります。
> http://sfenreader.appspot.com/sfen?sfen=6gnk%2F6gsl%2F6ppp%2F9%2F9%2F9%2F6PPP%2F6GSL%2F6GNK%0D%0A
>
> そしてこれを含む局面図を検索したいと思ったら次のような正規表現になると思います。
> .*gnk\/.*gsl\/.*ppp\/.*\/.*\/.*\/.*PPP\/.*GSL\/.*GNK
> #間違い、反例があったらご指摘お願いします。
それは探したいマスが両端にあるからできるのであって,例えばある段の5筋に歩があるのを検索する時,
/1P7/ と /4P4/ の区別を正規表現で行うのはかなり面倒くさい気がします.
> banhashは同一局面図検索を高速に行うなどの目的で必要だと思いますが、
> それとは別にsfenというフィールドを用意して、局面のsfen文字列をそのまま入れることは出来ないでしょうか。
うーん,やはり1手ずつ局面図自体を持つありがたみは,Web検索エンジン等の局面検索対応以外には
ないと思うので,仕様に含める必要があるとは思えないのですが・・・.
JSONとして読み込めば,初手から並べて行って局面を作れますので.何に使うのかがいまいちピンと来ていません.
すみません、書いてから自分でも布団の中で反例に気が付きました。
SFEN文字列で正規表現だけで部分一致検索を実現するのは、例示されたものだけでも不可能だと思います。。。
> うーん,やはり1手ずつ局面図自体を持つありがたみは,Web検索エンジン等の局面検索対応以外には
> ないと思うので,仕様に含める必要があるとは思えないのですが・・・.
> JSONとして読み込めば,初手から並べて行って局面を作れますので.何に使うのかがいまいちピンと来ていません.
JSONは冗長な情報を持てるので、無いよりあった方がいいのでは、くらいの気持ちで書きました。
しかし、局面の情報について直接JSONのテキスト検索をしないという方針に立てば、
確かに有効な場面が思いつきませんでした。
一晩立ってよくよくスレッドを見返してみたら一周遅れの議論だったかもしれません。
すみませんでした。
#スレッドの特定の発言に対してURLとか割り振られないんでしょうかね?
--
fantakeshi <fanta...@gmail.com>
当日の資料はこちらです.
http://bit.ly/jsonshogi
また,プレゼンでちょっと中途半端だったサンプルを補充したものをアップロードしました.
http://81.la/jsonshogi
柿木さんにも,概ねJSON棋譜の趣旨に理解を示していただきましたが,数年前からXML棋譜の構想を
持っていながらなかなか表に出そうということにならないことから,やはり既存のKIFが巨大になっていて
取って代わるのは相当の努力が必要という考えをお持ちであると感じられました.
局面ハッシュの埋め込みなど,JSONそのものに利用者にとっての直接のメリットをもたらす機能などに
これから議題をシフトしていく必要がありそうです.