BCDice#rollにおいて3番目以降の引数を使用する処理
「どどんとふのダイスボット」ことBCDiceのダイスロール処理(BCDice#roll
)には、多くの引数(7個!)がある。この処理を単純化して引数を減らしたかったため、その呼び出し方について調べた。
背景
BCDice#roll
の引数、返り値ともに個数が多すぎる。- 引数が多い分、処理が複雑。
- 引数を減らして処理を簡潔にできないか?
BCDice#roll
の引数の意味
dice_cnt [Integer]
:ダイスの個数dice_max [Integer]
:ダイスの面数dice_sort [Integer]
:並べ替え。0:ソートしない、1:足し算ダイスでソート有、2:バラバラロール(Bコマンド)でソート有。3:1+2。dice_add [Integer]
:BCDice#roll
内での振り足しの閾値?dice_ul [String]
:成功判定の演算子dice_diff [Integer]
:成功判定の目標値dice_re [Integer]
:振り足しロールの閾値
(参考)BCDice#roll
の返り値の意味
total [Integer]
:出目の合計dice_str [String]
:出目を並べた文字列numberSpot1 [Integer]
:1が出た個数cnt_max [Integer]
:最高値の出目の個数n_max [Integer]
:出目の最大値cnt_suc [Integer]
:成功数rerollCount [Integer]
:個数振り足しロールの振り足し数
目的
以上の背景から、「BCDice#roll
をどのような場合に多くの引数で呼び出さなければならないか」を把握することを目的として、ソースコードを調査した。通常、ダイスロールでは 2d6
のようにダイスの個数と面数を指定するため、それ以外の要素(dice_sort
以降)を引数で指定する場合、つまり引数を3個以上とする場合を「多くの引数で呼び出している」と定義した。
調査方法
次のコミット時点におけるソースコードを調査の対象とした。
https://github.com/bcdice/BCDice/tree/f1da744aea852e1ef4e6d79ef329b428f4757385
src
ディレクトリで以下のコマンドを実行した。その出力から手作業で、BCDice#roll
を3引数以上で呼び出している部分を抽出した。
git grep -n -P '\broll\('
結果(要約)
- 4番目以降の引数を使用する場合は非常に少ない。
- バラバラロール(bcdiceCore.rb:1083)
- 個数振り足しロール(dice/RerollDice.rb:61)
- 上方無限ロール(dice/UpperDice.rb:145)
- ゲームシステム固有ダイスボット
- diceBot/DoubleCross.rb(クリティカル(成功判定))
- diceBot/NinjaSlayer.rb(成功判定)→ リファクタリング(PR #84)で使わなくなった
- 4番目の引数
dice_add
を使用する(0以外にする)のは、上方無限ロールのみ。 - ゲームシステム固有ダイスボットで3番目以降の引数を使用する場合、ほとんどは3番目の引数
dice_sort
を使用するだけ。
考察
- ほとんどの場合、引数は
dice_cnt
、dice_max
、dice_sort
だけで十分。これだけが用意された単純なメソッドを用意することが、改善案として考えられる。 - 4番目以降の引数を使用する場合が非常に少ないため、それらの場合の処理を
BCDice#roll
の外に出すと、処理をより単純化できると考えられる。上で述べた単純なメソッドを使用してさらに複雑な処理を行うメソッドを用意するべき。- 特に
dice_add
を使用するのは上方無限ロールだけなので、この部分はUpperRoll
に移動できるはず。
- 特に
dice_sort
の指定ミスが散見されるので、見直すべき。
結果(詳細)
bcdiceCore.rb:1083: dice_dat = roll(dice_cnt, dice_max, (@diceBot.sortType & 2), 0, signOfInequality, diff)
- バラバラロール
dice/AddDice.rb:298: return @bcdice.roll(dice_wk, dice_max, sortType)
- 加算ロール
dice/RerollDice.rb:61: @bcdice.roll(x, n, (@diceBot.sortType & 2), 0, signOfInequality, diff, rerollNumber)
- 個数振り足しロール
dice/UpperDice.rb:145: @bcdice.roll(diceCount, diceMax, (@diceBot.sortType & 2), @upper, @signOfInequality, diceDiff)
- 上方無限ロール
diceBot/Airgetlamh.rb:81: dice, diceText = roll(rollCount, 10, @sortType)
diceBot/Alsetto.rb:77: dice, diceText = roll(rollCount, 6, @sortType)
diceBot/Avandner.rb:65: dice, diceText = roll(rollCount, 10, @sortType)
- 並び替え
diceBot/BeastBindTrinity.rb:200: _, dice_str, = roll(dice_tc, 6, (sortType & 1))
- ダイス数修正、並べ替えせずに出力
diceBot/BlindMythos.rb:140: _, diceText, = roll(diceCount, 6, isSort)
- 並び替え
diceBot/DoubleCross.rb:156: dice_dat = roll(dice_cnt, dice_max, (sortType & 2), 0, "", 0, critical)
- クリティカル(成功判定)
diceBot/DoubleCross.rb:182: dice_dat = roll(dice_cnt, dice_max, (sortType & 2), 0, "", 0, critical)
- クリティカル(成功判定)
diceBot/EmbryoMachine.rb:82: dice_now, dice_str, = roll(2, 10, (sortType & 1))
diceBot/GehennaAn.rb:56: diceValue, diceText, = roll(diceCount, 6, (sortType & 1))
diceBot/HatsuneMiku.rb:84: _, diceText, = roll(diceCount, 6, isSort)
- 並び替え
diceBot/Illusio.rb:53: dice, diceText = roll(diceCount, 6, @sortTye)
- 並び替え?(typoしている?)
diceBot/LiveraDoll.rb:81: dice, diceText = roll(diceCount, 6, @sortType)
diceBot/MeikyuDays.rb:90: _, dice_str, = roll(dice_c, 6, (sortType & 1))
diceBot/MeikyuKingdom.rb:178: _, dice_str, = roll(diceCount, 6, (sortType & 1))
diceBot/MonotoneMusium.rb:64: total, dice_str, = roll(2, 6, @sortType && 1)
diceBot/MonotoneMusium_Korean.rb:64: total, dice_str, = roll(2, 6, @sortType && 1)
diceBot/Nechronica.rb:100: _, dice_str, n1, cnt_max, n_max = roll(dice_n, 10, 1)
diceBot/Nechronica_Korean.rb:100: _, dice_str, n1, cnt_max, n_max = roll(dice_n, 10, 1)
diceBot/NightWizard.rb:127: dice_n, dice_str, = roll(2, 6, 0)
diceBot/NightWizard.rb:173: dice_n, dice_str, = roll(2, 6, 0)
- 並び替え
diceBot/NinjaSlayer.rb:110: dice = roll(m[1], 6, 0, 0, '>=', 2)
diceBot/NinjaSlayer.rb:130: dice = roll(m[1], 6, 0, 0, '>=', 3)
diceBot/NinjaSlayer.rb:149: dice = roll(m[1], 6, 0, 0, '>=', 4)
diceBot/NinjaSlayer.rb:168: dice = roll(m[1], 6, 0, 0, '>=', 5)
diceBot/NinjaSlayer.rb:187: dice = roll(m[1], 6, 0, 0, '>=', 6)
diceBot/NinjaSlayer.rb:206: dice = roll(m[1], 6, 0, 0, '>=', 4)
diceBot/NinjaSlayer.rb:226: dice = roll(m[1], 6, 0, 0, '>=', 2)
diceBot/NinjaSlayer.rb:245: dice = roll(m[1], 6, 0, 0, '>=', 3)
diceBot/NinjaSlayer.rb:264: dice = roll(m[1], 6, 0, 0, '>=', 4)
diceBot/NinjaSlayer.rb:283: dice = roll(m[1], 6, 0, 0, '>=', 5)
diceBot/NinjaSlayer.rb:302: dice = roll(m[1], 6, 0, 0, '>=', 6)
diceBot/NinjaSlayer.rb:321: dice = roll(m[1], 6, 0, 0, '>=', 4)
- 成功判定
diceBot/OrgaRain.rb:49: dice, diceText = roll(diceCount, 10, @sortType)
- 並び替え
diceBot/Postman.rb:87: dice, diceText = roll(diceCount, 6, @sortTye)
diceBot/Raisondetre.rb:79: dice, diceText = roll(rollCount, 10, @sortTye)
diceBot/Raisondetre.rb:133: dice, diceText = roll(rollCount, 10, @sortTye)
- 並び替え?(typoしている?)
diceBot/SRS.rb:56: total, dice_str, = roll(2, 6, @sortType && 1)
- 並び替えだが、値は常に
true
となる
- 並び替えだが、値は常に
diceBot/Strave.rb:79: dice, diceText = roll(diceCount, 10, @sortType)
diceBot/Torg.rb:102: dummy = roll(1, 20, 0)
diceBot/TunnelsAndTrolls.rb:165: rollTotal, rollDiceResultText, roll_cnt1, rollDiceMaxCount, roll_n_max, roll_cnt_suc, roll_cnt_re = roll(dice_wk, 6, (sortType & 1))
- 並び替え
diceBot/TwilightGunsmoke.rb:76: total, dice_str, = roll(2, 6, @sortType && 1)
- 並び替えだが、値は常に
true
となる
- 並び替えだが、値は常に