モンクDPS予想3

既に、何回かDPS予想プログラムを載せているけれど、今回やっとファーストブロー(以下、FB)、ブラスティングブロー(以下、BB)、フィニッシュブロー(以下、FnB)の全部を付けた状態でのプログラムが完成。FnBにはデフォルトで5秒間のCTがあるので、その辺をきちんと扱うのが難しかった。

N=10000                  # 実験回数

FB=0.45*(1.21+0.05)      # FB発動率
BB=0.05*(1.21+0.05)      # BB発動率
FnB=0.05*(1.21+0.05)     # FnB発動率

DM_N  = 371              # 通常攻撃与ダメ
DM_FB = 824              # FB与ダメ
DM_BB = 1396             # BB与ダメ
DM_FnB= 2634             # FnB与ダメ

ST_N  = (2+1)*1.3*1.3    # 通常スタ攻
ST_FB = (4+1)*1.3        # FBスタ攻
ST_BB = (6+1)*1.3        # BBスタ攻
ST_FnB= (8+1)*1.3        # FnBスタ攻

TM_N  = 1.04             # 通常攻撃の時間
TM_FB = 0.53             # FBの時間
TM_BB = 0.53             # BBの時間
TM_FnB= 0.53             # FnBの時間

CT_FnB= 5*0.8            # FnBのCT

CRI=0.8                  # クリ率
CRI_DM=1.5+1.0+0.07      # クリダメ増
GRO_DM=1.0+1.2           # グロダメ増

MaxStamina = 280         # かかしの最大スタミナ

DM_Hash={:normal => DM_N, :fb => DM_FB, :bb => DM_BB, :fnb => DM_FnB}
ST_Hash={:normal => ST_N, :fb => ST_FB, :bb => ST_BB, :fnb => ST_FnB}
TM_Hash={:normal => TM_N, :fb => TM_FB, :bb => TM_BB, :fnb => TM_FnB}

$frand=Random.new()
def occ(q)
  $frand.rand(1.0) < q
end

# 攻撃の種類を決める
def at_type(prev, time, fnb_ct)
  fnb = time >= fnb_ct    # FnBのCTが終わっているか
  case prev
  when :normal
    return :fnb if fnb && occ(FnB)
    return :bb if occ(BB)
    return :fb if occ(FB)
  when :fb
    return :fnb if fnb && occ(FnB)
    return :bb if occ(BB+0.45)
    return :fb if occ(FB)
  when :bb
    return :fnb if fnb && occ(FnB+0.30)
    return :fb if occ(FB)
  when :fnb
    return :bb if occ(BB)
    return :fb if occ(FB)
  end
  return :normal
end

def sim (max_time)
  type=:start
  stamina=MaxStamina
  gro_time=0
  time=0
  total=0
  fnb_ct=0
  
  while time < max_time
    type=at_type(type, time, fnb_ct)

    fnb_ct = time+CT_FnB if type==:fnb
    dm = DM_Hash[type]
    dm *= CRI_DM if occ(CRI)

    if time <= gro_time then   # グロ中
      dm *= GRO_DM
    else                       # グロ中でない
      stamina -= ST_Hash[type]
    end

    total +=dm.to_i
    time  +=TM_Hash[type]

    if stamina < 0 then
      stamina = MaxStamina
      gro_time = time + 5      # 5秒間グロ
    end
  end
  total
end

N.times do
  p sim(2*60)
end

まだプログラムを書いてみただけなので検証はまた後日。