# [Miner Gun Builder](https://hackmd.io/@6NWpke4BRK68dykzV2EFnQ/B1nOHR6EF)の検証
## Critical x 2
|アイコン| 名前 | 説明 |
| -- | -------- | -------- |
| | Critical x 2 | A chance of 33% to double the damage of tha passing projectile |
### 経緯
一部のサイトで、Critical x 2の効果を66%ダメージ増と説明しているのを見かけた。
念の為検証する。
### 検証方法
- Challenge ModeをONにすることで、CaptainやSkillでの底上げを無効にする。
- Critical x 2のみ搭載する

- Stage17を開始し。開始直後に前方に加速。これを数十回繰り返す。
繰り返しの都度Highest projectile damage(最大ダメージ)と、Projectiles Ejected(発射数)を記録。
Projectiles Ejectedは3もしくは4になるはず。
- Projectiles Ejected(A)の3,4それぞれで、最大ダメージが1、つまりCriticalが効かなかった場合、の数(B)と繰り返しの数(C)をだす。
- 方程式を解いて、Critical x 2が発動する確率xを求める。
$${(1-x)^A=\frac{B}{C}}$$
- 例
|Projectiles Ejected|Highest Damage|回数|
|-|-|-|
|3|1|9|
|3|2|23|
|4|1|7|
|4|2|23|
この時、Projectiles Ejected=3について下記が成り立つ。
$${(1-x)^3=9/23 (0<x<1)}$$
$${x=-\frac{ \sqrt[3]{2}\times3^\frac{2}{3} }{4}+1}$$
$${x\risingdotseq0.344814651}$$
Projectiles Ejected=4について下記が成り立つ
$${(1-x)^4=7/30 (0<x<1)}$$
$${x=-\frac{\sqrt[4]{189000}}{30}+1}$$
$${x\risingdotseq0.30498497}$$
### 検証結果
Criticalx2が発動する確率は66%よりも33%に近い。
### 補足
方程式は[Microsoft数学ソルバー](https://play.google.com/store/apps/details?id=com.microsoft.math&hl=ja&gl=US)で解いた。
## Critical x 10
同様に求めるとCritical x 10の発動する確率はおよそ4%だった。
###### tags: Miner Gun Builder
## Charge

### 経緯
ゲーム中の説明には
>Adds 20% of its damage to following projectiles.
とあるが、他の画面の説明には
> 20% of each passing projectiles damage is added to the damage pool of the item. Every projectile will receive 10% of this damage pool to its damage.
This results in a damage pool that increases till 20% of the added damage equals roughly 10% of the outgoing damage. It will smooth out damage spikes over multiple projectiles.
A strong projectile passes its damage to the following projectiles till the damage spike in the damage pool is used up and euilibrium is reached again
> (Deepl日本語訳)
通過する各投射物のダメージの20%がアイテムのダメージプールに追加される。すべての投射物は、このダメージプールの10%のダメージを受けます。
この結果、追加されたダメージの20%が発射されたダメージの約10%に相当するまで、ダメージプールが増加します。これにより、複数の投射物のダメージスパイクをスムーズにすることができます。
強力な投射物は、ダメージプールのダメージスパイクが使い切られて再び均衡状態になるまで、そのダメージを次の投射物に渡します。
と有る。この2つの説明の関係が不明。検証する。
### プログラムでの検証
Rubyのプログラムを作り検証した。
```ruby=
# 入力projectile毎のダメージ
d1 = 1000.0
d2 = 100.0
ary = [d1,d2] # damage1000,1000の2つのprojectileが入力
pool_damage = 0.0
1000.times{
total_out_damage = 0.0
ary.each{|projectile_damage_in|
pool_damage += 0.2 * projectile_damage_in
total_out_damage += projectile_damage_in + 0.1 * pool_damage
pool_damage = pool_damage * 0.9
}
puts sprintf("%5.3f",total_out_damage) #出力ダメージ
}
```
その結果とゲームの実行結果が一致したため、下記が言える。
- アイテムはダメージを出し入れするpoolを持っている
- 通過するprojectileのダメージの20%をコピーしpoolに蓄える
- この際、projectileのダメージは減らない
- 通過するprojectileにpoolの10%のダメージを与える
- この際、poolからその分ダメージが減る
さらにプログラムの実行から、Projectileとpoolの間のダメージのコピー/受け渡しは最初は増減し定まらないものの、いずれ平衡状態となることが確認できた。
平衡状態でのChargeアイテムからのprojectileの出力ダメージは計算でも求まる。
- 入力projectileのダメージを $$D_{in}$$
- 出力projectileのダメージを$$D_{out}$$
- projectile入力直前のpoolの蓄えるダメージを $$P_{1}$$
- projectile出力時点のpoolの蓄えるダメージを$$P_{2}$$
とすると、poolの蓄えるダメージのprojectileの入力/出力時の変化は前述の内容から下記。
$$P_{2}=P_{1}+0.2D_{in}$$
平衡状態ではpoolへの入力と出力が一致するので下記が成り立つ。
$$0.2D_{in}=0.1P_{2}$$
この2つから、 $$P_{2}=2D_{1}$$
これをprojectile出力時点のダメージを表す下記の式に代入。
$$D_{out}=D_{in}+0.1P_{2}$$
すると、
$$D_{out}=1.2D_{in}$$
よってChargeを用いると後続のダメージが20%増加するので、経緯に挙げたどちらの説明も正しい。
最初は増減するがいずれ出力ダメージは入力ダメージの20%増加に落ち着く。
なおprojectileが1つでも複数でも同じ。
## Adds an additional projectileで追加されるprojectileのダメージは幾つになるのか
### 検証

Damage+100の後に、Adds an additional projectileを置く。
結果、lowest projectile damageはHighest projectile damageと同じ101だった。

### 結論
Adds an additional projectileへの入力projectileの平均/ランダムに選んだprojectileから取得 など、Adds an additional projectileへの入力projectileから求めている。
具体的な決定方法は不明だが、いずれにせよ、base damageではない。
## legendaryのTier damageの10%の計算は四捨五入?
- 結果
YES。四捨五入。
## legendaryのMore when lowerは、ダメージが一様なら増えない?
YES
## legendaryのMore when lowerとCritical系を組み合わせた場合の最小/平均/最大ダメージは、何倍になるか
### 検証
```ruby=
base_damage = 1.0
def generate(base_damage)
yield base_damage
end
def critical2(damage)
if rand(100) < 33
damage * 2
else
damage
end
end
def critical10(damage)
if rand(100) < 4
damage * 10
else
damage
end
end
def critical_random(damage)
case rand(13)
when 0
0.0 * damage
when 1,2,3,4,5,6,7,8,9
1.0 * damage
when 10
2.0 * damage
when 11
3.0 * damage
when 12
4.0 * damage
else
raise StandardError.new
end
end
class MoreThanLower
def initialize
@last_damage = nil
end
def proc(damage)
if @last_damage
if @last_damage > damage
@last_damage = damage * 4
else
@last_damage = damage
end
else
@last_damage = damage
end
@last_damage
end
end
max_damage = 0
min_damage = nil
last_damage = nil
obj = MoreThanLower.new
total_damage = 0.0
i = 0
10000000.times{
generate(base_damage){|damage|
#damage = obj.proc(critical2(damage))
#damage = obj.proc(critical10(damage))
damage = obj.proc(critical_random(damage))
max_damage = damage > max_damage ? damage : max_damage
min_damage = (min_damage == nil || damage < min_damage) ? damage : min_damage
total_damage += damage
i += 1
}
}
puts "min:" + min_damage.to_s
puts "avg:" + (total_damage/i).to_s
puts "max:" + max_damage.to_s
```
### 結果
|item|最小ダメージ|平均ダメージ|最大ダメージ|
|-|-|-|-|
|Critical x2|1倍|5.32倍(Critical x2単独の1.33の4倍)|8倍(Critical x2単独の4倍)|
|critical x10|1倍|4.24倍(Critical x10単独の3.12倍)|10倍(Critical x10単独の1倍)|
|Random critical|0倍|3.88倍(Random Critical単独の1.38の2.8倍)|16倍(Random critical単独の4.12倍)|
## Slow damage

- Itemの効果
More damage, x2 at 1 speed to x5 at 0.2 speed, for slower projectiles.
- 検証
Damageの加算は、item通過時点と、eject時点の、どちらで行われる?
- 結果
Item通過時点ではなくeject時点のspeedで倍率を計算する。