Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RerollDiceの未定義動作 #65

Closed
ysakasin opened this issue Jul 22, 2019 · 3 comments
Closed

RerollDiceの未定義動作 #65

ysakasin opened this issue Jul 22, 2019 · 3 comments

Comments

@ysakasin
Copy link
Member

ysakasin commented Jul 22, 2019

RerollDiceに未定義動作およびREADMEの説明と反する挙動があるため修正が必要。

READMEでの説明

  ・個数振り足しロール (xRn)
   ダイスをバラバラにロールして、その成功数の個数分さらにロールして成功度を
   加算するロール(天羅万象など)にも対応しました。
   振り足し回数はゲーム設定で対応になっています。(デフォルトは無限)
   BのかわりにRを使うことで使用できます。
   条件式は必須で、ダイスの括弧内前処理も使えます。

説明にそぐわない例

2R3+3R6>=3 : (2R3+3R6[3]>=3) > 3,1,5,1,2 + 4,5 + 1,1 > 成功数4

振り直しがR3で振り直し条件を満たしても、R6で振り直される

2R6[3] : (2R6[3]) > 4,3 + 2,2 > 成功数0

[]を使うと振り直しが発生しても成功数にカウントされない

3R6+2R4<2 : (3R6+2R4[2]<2) > 3,5,4,1,1 + 2,2,4 + 2,1,2 + 3,1 + 4 + 1 > 成功数5

振り直し条件は必ず >= になってしまう

再定義

READMEの記述と直感的に期待される挙動から、仕様を再定義する。

  • ダイスの指定はnRxのようにし、+で複数繋げられる
  • ダイス指定の直後に成功条件式を >=6<2 のように記述する
  • 指定された条件式を用いて各ダイスの成否判定が行われる
  • 成功したダイスは振り直される
  • 成功した回数をカウントし、成功数とする
  • []をつかった2R3+4R5[6]のような式は2R3+4R5>=6 の糖衣構文とする
  • 式中の数値は、0以上のみ受け付ける
@ysakasin
Copy link
Member Author

シャドウラン的にはもともとの挙動であってるらしい。

以下の挙動が 6R6[6]>=5 で記述される。

具体事例で書きます
6面サイコロを6つ振り、結果が 3,4,2,6,6,5 の場合
シャドウランでは達成値は 5 をしきい値としているので 6,6,5 が採用されて 3 ヒット
ここでさらに、 6 の目が採用されたうえで振りたされる
追加の出目が 4,5 となり、 5 が採用されて合計で 4 ヒットになる
上方無限なので6の目が出れば続きます

@ochaochaocha3
Copy link
Member

現在の閾値決定の手順は以下のようになっていました。

  • マッチする正規表現:/(^|\s)S?([\d]+R[\d\+R]+)(\[(\d+)\])?(([<>=]+)([\d]+))?(\@(\d+))?($|\s)/
  • 説明のため、入力文字列を 2R6[5]>=4@3 と書きます。
    • 5の場所の数値を「[]値」と呼びます。
    • 「>=4」の部分をまとめて「条件式」と呼びます。
    • 4の場所の数値を「条件値」と呼びます。
    • 3の場所の数値を「@値」と呼びます。

手順:

  1. 前準備:条件式が存在せず、かつゲームシステム固有の既定の条件式(DiceBot#defaultSuccessTarget)が存在する(空文字列以外である)場合、既定の条件式から条件値を設定します。
  2. []値が存在する場合、[]値を閾値とします。
  3. @値が存在する場合、@値を閾値とします。
  4. ゲームシステム固有の既定の閾値(DiceBot#rerollNumber)が存在する(0 以外である)場合、既定値を閾値とします。
  5. 条件値が存在する場合、条件値を閾値とします。
  6. 閾値の候補が存在しなかったため、例外(固定のメッセージ付きの RuntimeError)を発生させます。

@値に関する説明は簡単に見つけられませんでした。何かのゲームシステムの独自コマンドから xRn に変換される際に付加される部分かもしれません。@値の優先度が条件値(条件式)より高く、重要であることがうかがえるため、@値を付加するゲームシステムがどれか把握しておくことが必要だと思われます。

参考:

  • m = /(^|\s)S?([\d]+R[\d\+R]+)(\[(\d+)\])?(([<>=]+)([\d]+))?(\@(\d+))?($|\s)/.match(string)
    unless m
    debug("is invaild rdice", string)
    return '1'
    end
    string = m[2]
    rerollNumber_1 = m[4]
    rerollNumber_2 = m[9]
    judgeText = m[5]
    operator = m[6]
    diff = m[7]
    if judgeText
    diff = diff.to_i
    signOfInequality = @bcdice.marshalSignOfInequality(operator)
    elsif @diceBot.defaultSuccessTarget != ""
    m = /([<>=]+)(\d+)/.match(@diceBot.defaultSuccessTarget)
    if m
    operator = m[1]
    diff = m[2].to_i
    signOfInequality = @bcdice.marshalSignOfInequality(operator)
    end
    end
    rerollNumber = getRerollNumber(rerollNumber_1, rerollNumber_2, judgeText, diff)
  • def getRerollNumber(rerollNumber_1, rerollNumber_2, judgeText, diff)
    if rerollNumber_1
    return rerollNumber_1.to_i
    elsif rerollNumber_2
    return rerollNumber_2.to_i
    elsif @diceBot.rerollNumber != 0
    return @diceBot.rerollNumber
    elsif !diff.nil?
    return diff
    else
    raiseErroForJudgeRule()
    end
    end

@ysakasin
Copy link
Member Author

複数のダイスを振った時の動作のみを修正しました。他は仕様であるため、今後ドキュメントに明記することにします。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants