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

加算ロールを負の数で割ることができない #59

Closed ochaochaocha3 closed 4 years ago

ochaochaocha3 commented 5 years ago

加算ロール nDx を負の数で割ることができません。これは構文解析上の問題のようです。

環境

コミットID 2b3d853d513da1cd1e94e6c6a4b579b49e7d9441

症状

加算ロールに対して乗数が負数の乗算、除数が負数の除算を行おうとした場合(例:2d6*(-1)2d6/(-1))、*/ が無視され、減算として処理されます。

@blhsrwznrghfzpr (trpg_yoshi)さんが確認した例:

bcdice_sum_roll_mul_div

テストケースを追加した例:

bcdice_testcase

原因

以下、除算で問題が発生する原因のみ示します。

原因は、AddDice#rollDiceAddingUp で負の乗数や除数が無視されることです。

https://github.com/bcdice/BCDice/blob/f8881ea551565592580bb1dd9d8348f2d2cdfb58/src/dice/AddDice.rb#L160-L164

負の乗数や除数が正規表現にマッチしないため、slashMarknil になります。

https://github.com/bcdice/BCDice/blob/f8881ea551565592580bb1dd9d8348f2d2cdfb58/src/dice/AddDice.rb#L236

ここで、getSlashedDice の第1引数に nil が渡されます。

https://github.com/bcdice/BCDice/blob/f8881ea551565592580bb1dd9d8348f2d2cdfb58/src/dice/AddDice.rb#L289-L291

/^\/(\d+)(.)?$/i === nilfalse となるため、除算が行われません。

ysakasin commented 5 years ago

これは、AddDiceが - を全て二項演算子として捉えていることを発端とした挙動のようです。以下のように、AddDiceでははじめに+-で式全体を区切ってから中身を評価しています。1D6/(-10)のように単項演算子としての - がサポートされていないため発生しています。

https://github.com/bcdice/BCDice/blob/65e7dae533007f7fcb1920e3a4097c11a16660eb/src/dice/AddDice.rb#L40-L45

この問題を解決するには、評価機構を刷新し、構文解析を導入する必要がありそうです。

ochaochaocha3 commented 4 years ago

147 のマージで解決しました。