1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

特殊処理を行うサイコロを振る関数

Last updated at Posted at 2017-06-22

前提知識:nDm

TRPGでは頻繁にサイコロを使う。nがサイコロを振る個数、mが使用するサイコロの最大出目である。
例として、チンチロリンでは6面体サイコロ3つを用いる。よって、3D6と略称する。
サイコロだけでなく、固定数値を足し引きしたい時もある。
そのような場合、例として6面体サイコロ1つと固定数値3を足し合わせるのであれば1D6+3と表記する。
Dはdiceを意味する。変数n,mとの区別の為にこの項では大文字のDとしたが、ゲーム上では小文字でも構わない。当記事でも以後小文字で表記する。

前提知識:クリティカルとファンブル

https://www16.atwiki.jp/takugedic/pages/37.html#mugenjouhou
▼クリティカルとファンブル
ダイスロールの結果によって、クリティカルとファンブルという処理が存在します。

基本的にダイス目で6が出た時がクリティカル。つまりより良い結果が期待される処理です。
ダイス目で1が出た時がファンブル。判定結果が悪い結果に転がってしまう処理となります。

▼クリティカル 【 無限ロール方式 】
ダイス目6が出続ける限り、ダイス追加して数値を加算する。
※クリティカル後のダイス目1はファンブル扱いにはせずにそのまま数値を加算する。
▼ファンブル 【 マイナス方式 】
ダイス目1が出た場合、ダイスをもう一度振って合計値からマイナスする。
はじめに出たダイス目1はそのまま加算して良い。
例) ファンブルロールでダイス目4を出した場合は-3。
※ファンブルロールでは追加のファンブルやクリティカルは発生しない

土台関数

「クリティカル・ファンブル処理を行うnd6」のことを"C"ritical & "F"umble nd6 から略し、cfnd6と呼称する事にする。
まずは基本となる「Rでcf1d6」。
単独でも使えるが、出力結果に解説を入れていない。
実行例に出力結果のベクトルの各値の表す意味を記す。

cf1d6
cf1d6 <- function(x) {    # x = Upper limit of critical chain
    ans <- 1:x            # Total value
    dice <- 1:x           # Dice value
    cr <- 0               # Critical count
    fa <- 0               # Fumble count
    for(i in 1:x) {
        ans[i] <-  sample(c(1:6), 1, replace=TRUE)    # sample(~) is Dice roll
        dice[i] <- ans[i]
    }
    ans0 <- ans[1]
    dice0 <- dice[1]
    if(ans[1] == 1) {     # Fumble calculation
        ans0 <- ans0 - ans[2]
        dice0 <- paste(dice0, "-", dice[2],sep="")
        fa <- fa + 1     # Fumble count +1
    } else {
        for(j in 1:(x-1)){        # Critical calculation
            if(ans[j] == 6) {
                ans0 <- ans0 + ans[j+1]
                dice0 <- paste(dice0, "+", dice[j+1],sep="")
                cr <- cr + 1        # Critical count +1
            } else break
        }
    }
    cat(dice0, "\n", sep = "")
    return(c(ans0,cr,fa))
}

実行例1 1、ファンブル→2。
達成値+1-2=-1、クリティカル0回、ファンブル1回

> cf1d6(10)
1-2
[1] -1  0  1

実行例2 6、クリティカル→クリティカル→クリティカル→連鎖終了。
達成値+6+6+6+1=19、クリティカル3回、ファンブル0回

> cf1d6(10)
6+6+6+1
[1] 19  3  0

次に別関数用に内蔵する用のもの。単独での使用は非推奨。

cf1d6_connect
cf1d6_connect <- function(x) {
    ans <- 1:x
    dice <- 1:x
    cr <- 0
    fa <- 0
    for(i in 1:x) {
        ans[i] <-  sample(c(1:6), 1, replace=TRUE)
        dice[i] <- ans[i]
    }
    ans0 <- ans[1]
    dice0 <- dice[1]
    if(ans[1] == 1) {
        ans0 <- ans0 - ans[2]
        dice0 <- paste(dice0, "-", dice[2],sep="")
        fa <- fa + 1
    } else {
        for(j in 1:(x-1)){
            if(ans[j] == 6) {
                ans0 <- ans0 + ans[j+1]
                dice0 <- paste(dice0, "+", dice[j+1],sep="")
                cr <- cr + 1
            } else break
        }
    }
    cat(dice0, ", ", sep = "")
    return(c(ans0,cr,fa))
}

本題

そして、本命の「Rでcfnd6」。
例としてcfnd6(5) + 10と記述する事で、cf5d6+10が可能。
5つの6面体のサイコロを振り、サイコロ一つずつにクリティカル・ファンブル処理を適応。そして出した合計値に固定数値10を加える、というものになる。

cfnd6
cfnd6 <- function(n) {
    dice0 <- 0
    dice <- matrix(NA, n, 3)
    for(i in 1:(n-1)) {
        dice[i,] <- cf1d6_connect(10)
    }
    dice[n,] <- cf1d6(10)
    for(j in 1:n){
        dice0 <- dice0 + dice[j,]
    }
    cat("cr:", dice0[2], ", ", sep = "") # Critical count
    cat("fa:", dice0[3], "\n", sep = "") # Fumble count
    return(dice0[1])
}

実行例1 ダイスのみの値は出ず、固定数値を計算した達成値のみがreturnされる事に注意。

> cfnd6(5)+10
3, 6+3, 2, 5, 2
cr:1, fa:0
[1] 31

実行例2 Rでの処理ならば、このようなやや複雑な計算式も一回の実行で処理可能。

> (cfnd6(3)+15) / 2
5, 4, 4
cr:0, fa:0
[1] 14

次は複数ダイスを連ねる
=関数を連ねcfnd6(3) + cfnd6(2) + 10のようにしても表示が壊れない関数を作成したい。

おまけ:assign関数を利用したバージョン

試行錯誤中にできたモノ。クリティカル・ファンブル処理こそ行っているが、それぞれ発生した回数を記録していない段階。
これをそのまま「Rでcfnd6」関数内部の「Rでcf1d6」の代用とはできないので注意。

cf1d6_old
function(x){        # x = Upper limit of critical chain
    for(i in 1:x) {
        assign(paste("ans", i, sep = ""), sample(c(1:6), 1, replace = TRUE))
    }
    ans0 <- ans1
    if(ans1 == 1)
        ans0 <- ans0 - ans2
    for(j in 1:(x-1)) {
        if(eval(parse(text = paste("ans", j, sep = ""))) == 6) {
            ans0 <- ans0 + eval(parse(text = paste("ans", j+1, sep = "")))
        } else
            break
    }
    return(ans0)
}
おまけ:ギャンブル対応版の関数内部

こちらも「Rでcf1d6」同様、固定数値を予め足したり一度の入力で計算が可能。

cfg1d6
function(x) {      # x = Upper limit of critical chain
    ans <- 1:x     # Total value
    dice <- 1:x    # Dice value
    cr <- 0        # Critical count
    fa <- 0        # Fumble count
    for(i in 1:x) {
        ans[i] <-  sample(c(1:6), 1, replace=TRUE)
        dice[i] <- ans[i]
    }
    ans0 <- ans[1]
    dice0 <- dice[1]
    if(ans[1] <= 3) {    # Fumble calculation
        ans0 <- ans0 - ans[2]
        dice0 <- paste(dice0, "-", dice[2], sep="")
        fa <- fa + 1     # Fumble count +1
    } else {
        if(ans[1] >= 4){    # Critical calculation(first time)
            ans0 <- ans0 + ans[2]
            dice0 <- paste(dice0, "+", dice[2], sep="")
            cr <- cr + 1 #Critical count +1
            for(j in 2:(x-1)){    # Critical calculation (second and subsequent)
                if(ans[j] == 6) {
                    ans0 <- ans0 + ans[j+1]
                    dice0 <- paste(dice0,"+",dice[j+1],sep="")
                    cr <- cr + 1 #Critical count +1
                } else break
            }
        }
    }
    cat(dice0, "\n", sep = "")
    return(c(ans0,cr,fa))
}
1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?