もう忘れない！ココフォリア（resp. Tekey）でダブルクロスをやるときに侵蝕率ボーナスを忘れないチャパレの作り方

# 想定する読む人のレベル
- TRPGを知っている
- CCOFLIA or tekeyを利用したことがある
- CCOFOLIAのパラメータや変数・チャットパレットという機能を知っている（または，Tekeyの類する機能をしっている）
    - 知らない人は以下を見てください
        - [CCFOLIAのパラメータ](https://docs.ccfolia.com/pl-tutorial/character-edit/status-setting) [CCFOLIAのチャットパレット](https://docs.ccfolia.com/pl-tutorial/character-edit/chat-pallet)

# はじめに
早速ですが，ダブルクロスで一番難しいことってなんですか？そうですね。**侵蝕率ボーナスを忘れること**ですね。
私は侵蝕率ボーナスを覚えてたことは生まれてから一度もありません。というわけで，今回は侵蝕率ボーナスを忘れないように侵蝕率のパラメータから全自動で計算してくれるAI（最近はなんでもAIと言って許されるので……）を作りました。

## 忙しい人のために先に貼り付けるだけのコピペを作る
結論から言うと，
```
//侵蝕率ボーナス（ダイス）=(({侵蝕率}/60F)/({侵蝕率}/60F+1)C*(1-({侵蝕率}/100F)/({侵蝕率}/100F+1)C)*(({侵蝕率}-60)/20F+1)+({侵蝕率}/100F)/({侵蝕率}/100F+1)C*(1-({侵蝕率}/160F)/({侵蝕率}/160F+1)C)*(({侵蝕率}-100)/30F+3)+({侵蝕率}/160F)/({侵蝕率}/160F+1)C*(1-({侵蝕率}/240F)/({侵蝕率}/240F+1)C)*(({侵蝕率}-160)/40F+5)+({侵蝕率}/240F)/({侵蝕率}/240F+1)C*7+({侵蝕率}/300F)/({侵蝕率}/300F+1)C)
//侵蝕率ボーナス（エフェクトレベル）=(({侵蝕率}/100F)/({侵蝕率}/100F+1)C+({侵蝕率}/160F)/({侵蝕率}/160F+1)C)
```
これを判定の時に入れるだけです。ダイスの判定ボーナスはダブルクロスのルール上，肉体・射撃・精神・社会に紐づいているので，

```
//肉体=【肉体の値】+{侵蝕率ボーナス（ダイス）}
//感覚=【感覚の値】+{侵蝕率ボーナス（ダイス）}
//精神=【精神の値】+{侵蝕率ボーナス（ダイス）}
//社会=【社会の値】+{侵蝕率ボーナス（ダイス）}
```
これも追記して，

```
{肉体}DX10+{回避}
```

みたいに書けば勝手に侵蝕率ボーナスがついてくれます。
エフェクトレベルはエフェクト使った際にちゃんと書けば良いと思います。
（後述のテンプレート例の〈小さな塵〉あたりを参照）
## チャットパレットの作成例

テンプレートとしてはこんな感じです
```
///////////////////
//能力値・技能値
//侵蝕率ボーナス（ダイス）=(({侵蝕率}/60F)/({侵蝕率}/60F+1)C*(1-({侵蝕率}/100F)/({侵蝕率}/100F+1)C)*(({侵蝕率}-60)/20F+1)+({侵蝕率}/100F)/({侵蝕率}/100F+1)C*(1-({侵蝕率}/160F)/({侵蝕率}/160F+1)C)*(({侵蝕率}-100)/30F+3)+({侵蝕率}/160F)/({侵蝕率}/160F+1)C*(1-({侵蝕率}/240F)/({侵蝕率}/240F+1)C)*(({侵蝕率}-160)/40F+5)+({侵蝕率}/240F)/({侵蝕率}/240F+1)C*7+({侵蝕率}/300F)/({侵蝕率}/300F+1)C)
//侵蝕率ボーナス（エフェクトレベル）=(({侵蝕率}/100F)/({侵蝕率}/100F+1)C+({侵蝕率}/160F)/({侵蝕率}/160F+1)C)

//肉体=【肉体の値】+{侵蝕率ボーナス（ダイス）}
//感覚=【感覚の値】+{侵蝕率ボーナス（ダイス）}
//精神=【精神の値】+{侵蝕率ボーナス（ダイス）}
//社会=【社会の値】+{侵蝕率ボーナス（ダイス）}
///////////////////

///////////////////
//エフェクト
//CR：オルクスLV=2+{侵蝕率ボーナス（エフェクトレベル）}
・・・（技能値に併せて修正する）
///////////////////
```

具体例を挙げてみましょう。基本ルールブック1の「閃光の双弾」くん（[公式のpdf](https://www.fear.co.jp/dbx3rd/download/dc3_sc02.pdf "「閃光の双弾」くんのキャラクターシート"))でテンプレートを作ってみるとこんな感じです。
```
///////////////////
//能力値・技能値
//侵蝕率ボーナス（ダイス）=(({侵蝕率}/60F)/({侵蝕率}/60F+1)C*(1-({侵蝕率}/100F)/({侵蝕率}/100F+1)C)*(({侵蝕率}-60)/20F+1)+({侵蝕率}/100F)/({侵蝕率}/100F+1)C*(1-({侵蝕率}/160F)/({侵蝕率}/160F+1)C)*(({侵蝕率}-100)/30F+3)+({侵蝕率}/160F)/({侵蝕率}/160F+1)C*(1-({侵蝕率}/240F)/({侵蝕率}/240F+1)C)*(({侵蝕率}-160)/40F+5)+({侵蝕率}/240F)/({侵蝕率}/240F+1)C*7+({侵蝕率}/300F)/({侵蝕率}/300F+1)C)
//侵蝕率ボーナス（エフェクトレベル）=(({侵蝕率}/100F)/({侵蝕率}/100F+1)C+({侵蝕率}/160F)/({侵蝕率}/160F+1)C)

//肉体=(1+{侵蝕率ボーナス（ダイス）})
//射撃=(9+{侵蝕率ボーナス（ダイス）})
//精神=(1+{侵蝕率ボーナス（ダイス）})
//社会=(1+{侵蝕率ボーナス（ダイス）})

//回避=1
//射撃=4
//RC=1
//調達=3
///////////////////

///////////////////
//武器
//拳銃（攻撃修正）=3
//拳銃（命中修正）=-1
///////////////////

///////////////////
//エフェクト
//リザレクトLV=(1+{侵蝕率ボーナス(エフェクトレベル)})
//ワーディングLV=(1+{侵蝕率ボーナス(エフェクトレベル)})
//コンセントレイト：エンジェルハイロゥLV=(2+{侵蝕率ボーナス(エフェクトレベル)})

//小さな塵LV=3+{侵蝕率ボーナス（エフェクトレベル）})
//小さな塵（ダイス修正）=0
//小さな塵（攻撃修正）=(2*{小さな塵LV})
//小さな塵（命中修正）=0

//ハンドレッドガンズLV=(1+{侵蝕率ボーナス（エフェクトレベル）})
//ハンドレッドガンズ（ダイス修正）=0
//ハンドレッドガンズ（攻撃修正）=(4+{ハンドレッドガンズLV})
//ハンドレッドガンズ（命中修正）=0

//ペネトレイトLV=(1+{侵蝕率ボーナス（エフェクトレベル）})
//ペネトレイト（ダイス修正）=-1
//ハンドレッドガンズ（攻撃修正）=0
//ハンドレッドガンズ（命中修正）=0

//マルチウェポンLV=(1+{侵蝕率ボーナス（エフェクトレベル）})
///////////////////


//コンボ
フルライトジャケット（ハンドレッドガンズ使用後）：〈コンセントレイト：エンジェルハイロゥ〉＋〈小さな塵〉＋〈ペネトレイト〉＋〈マルチウェポン〉 拳銃＋ハンドレッドガンズ
({射撃}+{ペネトレイト（ダイス修正）})DX@(10-{コンセントレイト：エンジェルハイロゥLV})+({射撃}+{拳銃（命中修正）}+{ハンドレッドガンズ（命中修正）})+{小さな塵（命中修正）}) フルライトジャケット（判定）
(【出目】/10C)D10+({拳銃（攻撃修正）}+{ハンドレッドガンズ（攻撃修正）})+{小さな塵（攻撃修正）}) フルライトジャケット（ダメージ） 装甲無視
```

こんな感じです。下のフルライトジャケットを使えば判定が自動でできるわけです（ダメージだけは【出目】の分を判定の実数値に変えてもらう必要があります）。

# うまく働く仕組み
数学的（算数的？）には非常に単純です。特にエフェクトレベルの計算が単純なのでそちらを先に紹介しましょう：

## エフェクトレベルの計算の仕組み
以下を計算しているだけです：

```math
\left\lfloor\frac{\left\lceil\frac{侵蝕率}{100}\right\rceil}{\left\lceil\frac{侵蝕率}{100}\right\rceil+1}\right\rfloor+\left\lfloor\frac{\left\lceil\frac{侵蝕率}{160}\right\rceil}{\left\lceil\frac{侵蝕率}{160}\right\rceil+1}\right\rfloor
```
ここで，$(\lfloor x\rfloor)$は床関数，$\lceil x\rceil$は天井関数です（詳しくは後述）。

### ダブルクロスにおけるエフェクトレベル計算の仕組み
通常（起源種などではない限り），ダブルクロスのエフェクトは
1. 侵蝕率が100%を超えたら+1
1. 160%を超えたら，さらに+1する（つまり合計でLVが+2される）という処理を行なっています。


そこで，与えられたパラメータ（自然数）$n$に対して，ある数値を超えたら1，それ未満で0になるようにすれば勝ちなわけです。
結論から言うと，$n$に対して$\left\lfloor\frac{\left\lceil\frac{侵蝕率}{n}\right\rceil}{\left\lceil\frac{侵蝕率}{n}\right\rceil+1}\right\rfloor$がそれを満たします。
さて，それが成り立つ理由を説明していきます。まず，$\left\lceil\frac{侵蝕率}{n}\right\rceil$とは，**侵蝕率をnで割った値で小数点以下を切り捨てる**という意味です。
例えば，
- $\left\lceil\frac{5}{2}\right\rceil = \lceil 2.5\rceil = 2$
- $\left\lceil\frac{120}{6}\right\rceil = \lceil 20\rceil = 20$
- $\left\lceil\frac{60}{100}\right\rceil = \lceil 0.6 \rceil = 0$

こんな感じですね。
今回は，**侵蝕率が100%未満で$\left\lceil\frac{侵蝕率}{n}\right\rceil = 0$になる**という性質を使います。
しかし，これだけだと，例えば侵蝕率が10億とかになると，$\left\lceil\frac{侵蝕率}{n}\right\rceil = 1億$とかになりおしまいです。
そこで，$\frac{\left\lceil\frac{侵蝕率}{n}\right\rceil}{\left\lceil\frac{侵蝕率}{n}\right\rceil}$を考えることで，常に1にしてやることを画策するわけです。

しかし，ここでもうひとつ問題が発生します。$\left\lceil\frac{侵蝕率}{n}\right\rceil = 0$なら（つまり侵蝕率が100%以下なら），$\frac{0}{0}$，つまり$0\div 0$となりこの世界は崩壊します。
つらいね。くるしいね。

崩壊させないために分母に1を加えます。つまり，$\frac{\left\lceil\frac{侵蝕率}{n}\right\rceil}{\left\lceil\frac{侵蝕率}{n}\right\rceil+1}$とするわけです。
確かにこれだったら$\left\lceil\frac{侵蝕率}{n}\right\rceil = 0$なら$\frac{0}{0+1} = 0$で問題ありません。しかし，もし$\left\lceil\frac{侵蝕率}{n}\right\rceil = 1$とかだったら
$\frac{1}{1+1} = \frac{1}{2} = 0.5 < 1$となってこれまた困っちゃいますね。そこで，今度は**小数点以下を切り上げする**というテクニックを使って無理やり$1$にします。
（$\left\lceil\frac{侵蝕率}{n}\right\rceil$が1以上なら数学的には必ず$0 < \frac{\left\lceil\frac{侵蝕率}{n}\right\rceil}{\left\lceil\frac{侵蝕率}{n}\right\rceil+1}　< 1$の範囲に収まるので切り上げで1になるのは確定しています）。ここで，**実数$a$に対して$a$を切り上げる**という操作を$\lfloor a\rfloor$と書きます。つまり，今回は$\frac{\left\lceil\frac{侵蝕率}{n}\right\rceil}{\left\lceil\frac{侵蝕率}{n}\right\rceil+1}$を切り上げするので

```math
\left\lfloor\frac{\left\lceil\frac{侵蝕率}{n}\right\rceil}{\left\lceil\frac{侵蝕率}{n}\right\rceil+1}\right\rfloor
```
となるわけです。あとは，$n$に100を代入したら100%以上で+1，100%未満で0というやつが作れるね！やったぁ!で試合終了です。160%を超えたらさらに+1もこれを加算すれば終わりですね。やったぁ！

### ココフォリア（resp. Tekey，というかbcdice）での実装
足し算を```+```，引き算を```-```，掛け算を```*````，割り算を```/```で表現します。そして，割った値を切り捨てるときは末尾に```F```をつけ，切り上げるときは末尾に```C```をつけます。
例えば，

- ```5/2F = 2```（2.5を切り捨ててるので）　```5/2C=3```
- ```120/6F=20```　```120/6C=20```
- ```60/100F=0```　```60/100C=1```

のようになるわけです。なので，それを組み合わせると，$
\left\lfloor\frac{\left\lceil\frac{侵蝕率}{100}\right\rceil}{\left\lceil\frac{侵蝕率}{100}\right\rceil+1}\right\rfloor$は

```
({侵蝕率}/100F)/({侵蝕率}/100F+1)C
```

とかけます。160も100を変えれば同様ですね。

## ダイスボーナスの計算の仕組み
エフェクトレベルより**ちょっとだけ**複雑です。

```math
\left\lfloor\frac{\left\lceil\frac{侵蝕率}{60}\right\rceil}{\left\lceil\frac{侵蝕率}{60}\right\rceil+1}\right\rfloor\times\left(1-\left\lfloor\frac{\left\lceil\frac{侵蝕率}{100}\right\rceil}{\left\lceil\frac{侵蝕率}{100}\right\rceil+1}\right\rfloor\right)\times\left(\left\lceil\frac{侵蝕率-60}{20}\right\rceil+1\right)
\\\quad + \left\lfloor\frac{\left\lceil\frac{侵蝕率}{100}\right\rceil}{\left\lceil\frac{侵蝕率}{100}\right\rceil+1}\right\rfloor\times\left(1-\left\lfloor\frac{\left\lceil\frac{侵蝕率}{160}\right\rceil}{\left\lceil\frac{侵蝕率}{160}\right\rceil+1}\right\rfloor\right)\times\left(\left\lceil\frac{侵蝕率-100}{30}\right\rceil+3\right)
\\\qquad + \left\lfloor\frac{\left\lceil\frac{侵蝕率}{160}\right\rceil}{\left\lceil\frac{侵蝕率}{160}\right\rceil+1}\right\rfloor\times\left(1-\left\lfloor\frac{\left\lceil\frac{侵蝕率}{240}\right\rceil}{\left\lceil\frac{侵蝕率}{240}\right\rceil+1}\right\rfloor\right)\times\left(\left\lceil\frac{侵蝕率-160}{40}\right\rceil+5\right)
\\ + \left\lfloor\frac{\left\lceil\frac{侵蝕率}{240}\right\rceil}{\left\lceil\frac{侵蝕率}{240}\right\rceil+1}\right\rfloor\times 7 + \left\lfloor\frac{\left\lceil\frac{侵蝕率}{300}\right\rceil}{\left\lceil\frac{侵蝕率}{300}\right\rceil+1}\right\rfloor
```

### ダブルクロスにおける侵蝕率ボーナス計算の仕組み
通常，ダブルクロスは
1. 侵蝕率が60%以上で+1
    - 60%から100%未満の間では20%上がるごとに更に+1（つまり80〜99%のときは+2）
1. 侵蝕率が100%以上で+3
    - 100%から160%未満の間では30%上がるごとに更に+1（つまり130〜159%のときは+4）
1. 侵蝕率が160%以上で+5
    - 100%から160%未満の間では30%上がるごとに更に+1（つまり130〜159%のときは+6）
1. 侵蝕率が240%以上で+7
    - 侵蝕率が300%以上で更に+1（つまり+8になる）

というわけで，4番目以降（つまり240%を超えた）処理はエフェクトレベルと簡単で優しいのですが，それに行くまでが苦しいですね。
このために，60%以上かつ100%未満で+1，それ以外で0になるものを作ってみましょう。結論から言うとそれがこちらになります：

```math
\left\lfloor\frac{\left\lceil\frac{侵蝕率}{60}\right\rceil}{\left\lceil\frac{侵蝕率}{60}\right\rceil+1}\right\rfloor\times\left(1-\left\lfloor\frac{\left\lceil\frac{侵蝕率}{100}\right\rceil}{\left\lceil\frac{侵蝕率}{100}\right\rceil+1}\right\rfloor\right)
```

$\left\lfloor\frac{\left\lceil\frac{侵蝕率}{60}\right\rceil}{\left\lceil\frac{侵蝕率}{60}\right\rceil+1}\right\rfloor$はいいですね。簡単です。
では$\left(1-\left\lfloor\frac{\left\lceil\frac{侵蝕率}{100}\right\rceil}{\left\lceil\frac{侵蝕率}{100}\right\rceil+1}\right\rfloor\right)$が何者かわかればいいですね。
これは単純で**100%未満で1，100%以上で0になる**ものです。なぜそうなるかは期末試験の問題にします（Hint：計算結果が1になるのは$\left\lfloor\frac{\left\lceil\frac{侵蝕率}{100}\right\rceil}{\left\lceil\frac{侵蝕率}{100}\right\rceil+1}\right\rfloor$がどんなときか？また0になるのは$\left\lfloor\frac{\left\lceil\frac{侵蝕率}{100}\right\rceil}{\left\lceil\frac{侵蝕率}{100}\right\rceil+1}\right\rfloor$がどんなときか？）

そして，それに$\left\lceil\frac{侵蝕率-60}{20}\right\rceil+1$をかけることでどうにかしています。$\left\lceil\frac{侵蝕率-60}{20}\right\rceil$は60を引いてから20で割った値を求めています。つまり，60〜79%のときは0，80%〜99%のときは+1……となります。そこに+1をたすことで判定ダイスを求めてるわけですね。これを100〜160%，160〜240%の三つに場合に造ることでどうにかしてるわけです。

### ココフォリア（resp. Tekey，というかbcdice）での実装
というわけで実装がこれです：

```
(({侵蝕率}/60F)/({侵蝕率}/60F+1)C*(1-({侵蝕率}/100F)/({侵蝕率}/100F+1)C)*(({侵蝕率}-60)/20F+1)+({侵蝕率}/100F)/({侵蝕率}/100F+1)C*(1-({侵蝕率}/160F)/({侵蝕率}/160F+1)C)*(({侵蝕率}-100)/30F+3)+({侵蝕率}/160F)/({侵蝕率}/160F+1)C*(1-({侵蝕率}/240F)/({侵蝕率}/240F+1)C)*(({侵蝕率}-160)/40F+5)+({侵蝕率}/240F)/({侵蝕率}/240F+1)C*7+({侵蝕率}/300F)/({侵蝕率}/300F+1)C)
```

# そもそもどうしてこんなことやったの？
ココフォリア（というかダイスボット）が四則演算＋除算の切り上げ・切り捨てにしか対応してなかったので苦しかったが頑張った。if文なり条件分岐が欲しい……

# 期末試験

1. $\left(1-\left\lfloor\frac{\left\lceil\frac{侵蝕率}{100}\right\rceil}{\left\lceil\frac{侵蝕率}{100}\right\rceil+1}\right\rfloor\right)$がどのような振る舞いをするか，理由も踏まえて答えよ（20点）
1. ココフォリア（というかダイスボットであるbcdice）は浮動小数点計算したものを丸めて結果を算出している。そのため，侵蝕率が非常に大きなオーダーではこの計算がうまく働かない。うまく働かなる侵蝕率を実際に求めよ（30点）
1. ダイスの侵蝕率ボーナスはより簡単な表現が存在する。この記事の実装より簡単な表現を実際にかけ（50点）

# さいごに
なにかどこかに怒られたら消します。ごめんなさい（初手ごめん）