bcdice / BCDice

The most popular TRPG dice command engine in Japan
https://bcdice.org
BSD 3-Clause "New" or "Revised" License
140 stars 184 forks source link

テストデータのTOML化 #131

Closed ysakasin closed 4 years ago

ysakasin commented 4 years ago

Ver2ではテストデータは独自フォーマットで記述されているが、bcdice-jsなどの他言語のプロジェクトから利用する観点から好ましくないので、普及しているファイルフォーマットで記述したい。

Ver3からはTOMLを作用する

ShinobiGami.toml

[[ShinobiGami]]
input = "s2d6"
output = "5"
secret = true
rands = [[1,6],[4,6]]

[[ShinobiGami]]
input = "2d6"
output = "5"
rands = [[1,6],[4,6]]

上記をJSONで表すと以下のようになる

{
  "ShinobiGami" : [
    {
      "input" : "s2d6",
      "output" : "5",
      "secret" : true,
      "rands" : [[1,6],[4,6]]
    },
    {
      "input" : "2d6",
      "output" : "5",
      "rands" : [[1,6],[4,6]]
    }
  ]
}

懸念点や検討された他の案

Ref.

ochaochaocha3 commented 4 years ago

シークレットダイスかどうかについて、シークレットダイスでないテストケースがほとんどなので、以下のような規則にすると書きやすいです。

opparco commented 4 years ago

rands をどのように書くかのアイデア出しです。

現行

rands = [[1,6],[4,6]]

pros: オブジェクトとして処理しやすい cons: 入れ子を書くのが面倒

d6rands d10rands で指定

d6rands = [1,4]
d10rands = [2,3,1,10]

pros: 入れ子解消 cons: 特化ルールは処理が面倒

default_rand_max を追加

default_rand_max = 6
rands = [1,4]

pros: 入れ子解消 指定なしなら現行も使える(はず) cons: 特になし

文字列で指定

rands = "1/6,4/6"

pros: 入れ子解消 互換性 cons: 字句解析が必要

ysakasin commented 4 years ago

面と値を分けて書く

rand_values = [1, 4, 4, 3]
rand_sides = [6, 6, 6, 6]
ysakasin commented 4 years ago

各案に対する私見

現行

妥当

d6rands d10rands で指定

解釈するツールの負担が大きいのでやめたほうがいい

default_rand_max を追加

現行と二重で表記できるようにしないと、実用できないので、解釈する時に若干面倒そう。記述量の少なさはピカイチ。

文字列で指定

自分で考えといて、本末転倒感がすごい。ただ、パースの難易度は相当低いはず

面と値を分けて書く

独自記述のなさと、解釈の容易さの両方を兼ね備えているが、記述および視認に難あり。

ysakasin commented 4 years ago

現行案でも、randsを複数行で書けば見辛さ等の問題は緩和できるかもしれない

[[ShinobiGami]]
input = "s2d6"
output = "5"
secret = true
rands = [
  [1, 6],
  [4, 6],
]
ochaochaocha3 commented 4 years ago

d6rands、d10randsのように種類ごとに書く方法と、default_rand_maxを指定する方法は、現実的ではないです。実はテストケースの中に、途中でダイスの種類が変わるものがあります。この場合の表現が不可能であるか、できても非常に複雑になりそうです。

例:ダブルクロスの感情表(ET) https://github.com/bcdice/BCDice/blob/v2.03.05/src/test/data/DoubleCross.txt#L574

ysakasin commented 4 years ago

一応書きますが default_rand_max 方式だと、以下のように現行方式との併用を想定していました。

[[ShinobiGami]]
input = "s2d6"
output = "5"
secret = true
default_rand_max = 6
rands = [1, 4]

[[ShinobiGami]]
input = "s2d6"
output = "5"
secret = true
default_rand_max = 6
rands = [1, [4,6]]

[[ShinobiGami]]
input = "s2d6"
output = "5"
secret = true
rands = [[1,6], [4,6]]
ochaochaocha3 commented 4 years ago

rands = [1, [4,6]]

TOMLでは、配列の中に複数の型を混ぜると構文エラーになるようです…😥

toml_parse_error

ochaochaocha3 commented 4 years ago

配列の配列は大丈夫でした。

toml_array_of_array

ysakasin commented 4 years ago

その仕様忘れてました……

配列は角括弧で囲まれた値の集まりです。空白は無視されます。各要素はカンマで区切られます。各データ型を混合させることは出来ません(文字列は全て同じ型だと考えてください。また中の要素がそれぞれ異なる配列同士も同じ型とします)。

https://qiita.com/minoritea/items/c0de47b8beb813c655d4#%E9%85%8D%E5%88%97

ochaochaocha3 commented 4 years ago

とはいえ、default_rand_max は便利ですね! rands の型が固定されることを逆手に取って、以下の2つを選べるようにするのも手かもしれません。

raa0121 commented 4 years ago

ふと思いついたのですが、こんな記載もできますね

[[ShinobiGami]]
input = "s2d6"
output = "5"
secret = true
  [[ShinobiGami.rands]]
    max = 6
    rand = 1
  [[ShinobiGami.rands]]
    max = 6
    rand = 4

パースすると、こうなります

{"ShinobiGami"=>[{"input"=>"s2d6", "output"=>"5", "secret"=>true, "rands"=>[{"max"=>6, "rand"=>1}, {"max"=>6, "rand"=>4}]}]}
ysakasin commented 4 years ago

インデントしないとテストケースの境界がわかりづらいので、その書き方は避けたい気がします。 インデントを許容するならYAMLを採用するところですが、このテストケースを読み書きするであろう方々のことを考えるとインデントは採用したくないですね。

ysakasin commented 4 years ago

:memo:

[[a]]
[[a.b]]
c=1
[[a]]
[[a.b]]
c=2

みたいな書き方も可能で、jsonに直すと以下のようになる。

{
  "a": [
    {
      "b": [
        {
          "c": 1
        }
      ]
    },
    {
      "b": [
        {
          "c": 2
        }
      ]
    }
  ]
}

[[a.b]]がどのオブジェクトに紐づくかはTOMLを見ただけでは自明ではないが、直前の [[a]] に紐づく仕様っぽい。 この仕様が直感的かという言われると直感的ではあるんだけれでも、解釈の揺らぎが大きいので微妙な気がする。

ブラウザでTOMLを試せるやつ https://pseitz.github.io/toml-to-json-online-converter/

ysakasin commented 4 years ago

革新案がない限り以下の書き方にしようと思っている。

[[ShinobiGami]]
input = "s2d6"
output = "(2D6) > 5"
secret = true
rands = [
  [1, 6],
  [4, 6],
]
ysakasin commented 4 years ago

inline tableというのもあるらしい

[[ShinobiGami]]
input = "s2d6"
output = "(2D6) > 5"
secret = true
rands = [
  { sides = 6, value = 1 },
  { sides = 6, value = 4 },
]
ysakasin commented 4 years ago

テストデータを扱いやすくするために、対象ゲームシステムはKeyにしない方がいいかもしれない

[[test]]
game_system = "ShinobiGami"
input = "s2d6"
output = "(2D6) > 5"
secret = true
rands = [
  { sides = 6, value = 1 },
  { sides = 6, value = 4 },
]
ysakasin commented 4 years ago

https://discordapp.com/channels/597133335243784192/641274151780483092/753636176979820654

テストデータのTOMLの件で、以前出ていた default_rand_max が良い感じに見えたのですが、どうでしょうか? https://github.com/bcdice/BCDice/issues/131#issuecomment-599465063 GitHub テストデータのTOML化 · Issue #131 · bcdice/BCDice Ver2ではテストデータは独自フォーマットで記述されているが、bcdice-jsなどの他言語のプロジェクトから利用する観点から好ましくないので、普及しているファイルフォーマットで記述したい。 Ver3からはTOMLを作用する 例 ShinobiGami.toml [[ShinobiGami]] input = "s2d6" output = &qu...

多くの場合で sides は一種類なので、単に配列で指定するのをメインにして、必要な場合に詳細指定できると、より書きやすくなるかな、と考えました

ysakasin今日 00:24 書きやすくはなるのですが、乱数を指定する方法が複数あると特にデータを解釈する側に対して罠を仕掛けてしまうと懸念しています。

ocha今日 00:24 ここで書きましたが、TOMLの型の制約を逆手に取ると、どちらか見分けるのは容易かと https://github.com/bcdice/BCDice/issues/131#issuecomment-599475960 GitHub テストデータのTOML化 · Issue #131 · bcdice/BCDice Ver2ではテストデータは独自フォーマットで記述されているが、bcdice-jsなどの他言語のプロジェクトから利用する観点から好ましくないので、普及しているファイルフォーマットで記述したい。 Ver3からはTOMLを作用する 例 ShinobiGami.toml [[ShinobiGami]] input = "s2d6" output = &qu...

ysakasin今日 00:25 そういうことではなくて、 default_rand_max というのがあるというのをそもそも把握してないといけないというのが罠かと

ocha今日 00:26 そこをドキュメントと使用例でカバーできないかなぁ

ysakasin今日 00:26 書き方が複数あると、第三の書き方も容易に作れてしまうし、制限したい感

ocha今日 00:28 ところで最新の案ですと、 rands の中は [4, 6] と { sides = 6, value = 1 } では後者寄りでしょうか

ysakasin今日 00:30 後者寄りですが、優劣は 45:55 くらいの感覚です randsの記述はおちゃさん的にはどうですか

ocha今日 00:31 後者は分かりやすいですが、今後新しくケースを追加するときにちょっと長いかな、という感じも この辺りは感覚によるので、他の書かれる方にも聞いてみたいところです

ysakasin今日 00:34 前者は書き優先で、後者は読み優先だと私も思っています

ocha今日 00:35 rands を書くときの慣例が1行に1項目となるならば、コピペすれば問題ないかも

ysakasin今日 00:36 { sides = 6, value = 1 } 方式なら、一行一項目がデファクトになると思ってます

ocha今日 00:37 横に長くなるので、自然にそうなりそうですね まあ現在は書式の都合で横にずらーっと並べて書いているだけなので、TOMLで改行がOKになれば、配列でもHashでも1行ずつの方が分かりやすそう

ysakasin今日 00:39 まだ Ver3 の確定まで時間があるので、いったん default 無し、項目は inline hash の安全案でコンバートしてしまおうかなと この形式です [[test]] game_system = "ShinobiGami" input = "s2d6" output = "(2D6) > 5" secret = true rands = [ { sides = 6, value = 1 }, { sides = 6, value = 4 }, ]

ocha今日 00:40 読みやすいです:thumbsup: 見出しも [[test]] で良さそうです。こうすれば、必要な場合にファイルの分割も可能になりそう。

ysakasin今日 00:42 残された論点は

  • default_rand_max 相当の機能を採用するか
  • randsを [[1,6], [4,6]] か Hashにするか の二点ですと。

ocha今日 00:44 上の例のように rands が1行1項目でコピペ前提ならば、個人的には default_rand_max なし、Hashのみで問題ないかな、と思いました。

ysakasin commented 4 years ago

要検討事項は以下の二点

お試し版は最も安定している以下の形式にする。9月中くらいにはいったん以下フォーマットで全データをTOML化してみる。

[[test]]
game_system = "ShinobiGami"
input = "s2d6"
output = "(2D6) > 5"
secret = true
rands = [
  { sides = 6, value = 1 },
  { sides = 6, value = 4 },
]
ysakasin commented 4 years ago

TOML化した https://github.com/bcdice/BCDice/commit/ea9d8e6c5571336250b5c7696fcbdb3c4a206aea