nR10ロール(0):解説と流れとCRT確率の計算

さて、DXといえばnR10ロール。
DXは通常のnDmロールの他に、「Rダイス」などと呼ばれる特殊なダイスロールを使用します。というか実プレイ的にはRダイスの方がよく振ってる気がします。

このエントリーでは、まず「Rダイス」についてご紹介。

特徴

Rダイスの特徴は以下のとおり。

  1. 10面ダイスをn個振り、その中で最大の出目を達成値とする。
  2. ただしPCの状態によって決められた値以上の出目のダイスは、出目を10として振り足しができる。この決められた値をクリティカル値と呼ぶ。
    • 通常は10がクリティカル値。
    • エフェクト使用や侵蝕率によって10未満がクリティカル値となることがある。この場合も出目を10として計算する
  3. 振り足しはクリティカル値が出続けている限り永遠に続く
  4. クリティカル値がエフェクトなどによって11以上になった場合はクリティカルしない
  5. 振ったダイスの出目がすべて「1」だった場合は「ファンブル」となる
例1

たとえば3つのダイスをクリティカル値10で振り、結果が「8,3,10」だった場合。
1つだけ「10」があるので振り足しが発生します。
で、振った結果が3だったらそこでおしまい。そして達成値は10+3=13になります。

例2

同じ3つのダイスを、今度はクリティカル値8で振った場合。
結果が同じ「8,3,10」であっても、その後の処理が変わります。
クリティカル値が8なので、8と10のダイスがクリティカルとして扱われ、2つのダイスを振り足します。
で、結果が「3,9」だったとする。するとまた8以上のダイスがあるので振り足しになる。
次の結果が「2」だとするとここでおしまい。
そして達成値はクリティカルが2回出たことを受けて、「10+10+2=22」になります。


かように、理論上は青天井も起こりうるダイスロールが「Rダイス」なのです。

Rダイスのクリティカル率を計算する

というわけでちょっと寄り道。任意のダイス数とクリティカル値を入力すると、1回以上クリティカルする確率を算出するスクリプトを作りました。

//nRmの1回以上のクリティカル率を計算して出力
function event::onChannelText(prefix, channel, text)
{

    if (text.match(/!\d+R\d+/i)){
    
        //該当文字列を配列arrMatchTextに格納
        var arrMatchText = text.match(/!\d+R\d+/i);
        
        //文字列からダイスの面数と個数を配列arrDiceTextに格納
        var arrDiceText = arrMatchText[0].match(/(\d+)/g);
        
        //個数と面数をそれぞれの変数に格納
        var faceDice = parseInt(arrDiceText[0]);	//個数(n)
        var numCritical = parseInt(arrDiceText[1]); //クリティカル値(m)
        
        //1回以上クリティカルする確率を計算
        var rateCritical = 0;   //クリティカル率
        rateCritical = Math.round((1 - ( Math.pow((numCritical-1)/10, faceDice)) ) * 100);
        
        //チャンネルにNoticeメッセージとして出力
        send(channel, 'ダイス' + faceDice +
            '個、クリティカル値' + numCritical +
            'で、1度以上クリティカルする確率:' + rateCritical + '%');
        
    }
}

ろあだいすの入力書式「#nRm(n:ダイス数/m:クリティカル値)」の、「#」を「!」に置き換えて、以降の書式はそのままです。
実行結果は以下の通り。

22:22 (ten-you) !1r10
22:22 (ten-you) ダイス1個、クリティカル値10で、1度以上クリティカルする確率:10%
22:23 (ten-you) !2r8
22:23 (ten-you) ダイス2個、クリティカル値8で、1度以上クリティカルする確率:51%
22:23 (ten-you) !6r10
22:23 (ten-you) ダイス6個、クリティカル値10で、1度以上クリティカルする確率:47%


ところで上記のスクリプト中では累乗の計算のためにMath.pow()使ってます。
Math.pow()とはMathオブジェクトのメソッドで、こんな関数(?)です↓

概要

base を exponent 乗した値、つまり、baseexponent の値を返します。


構文

Math.pow(base,exponent)


詳細

pow は Math オブジェクトの静的なメソッドなので、自ら生成した Math オブジェクトのメソッドとしてではなく、常に、Math.pow() として使用するようにしてください。

Math.pow() - JavaScript | MDN

が、師匠的存在にこのスクリプトの話をしたところ、「整数値の累乗なら関数使わずに自分でfor文使って作れ」といわれてしまいましたorz
いわく、『Math.pow()は少数累乗にも対応するので、その分処理が遅くなる』と。
……そこまで厳密な計算速度はいらんと思うのですがー。