【崩坏学园2】是一款萌萌的良心(骗氪)手游,不花钱氪金(滑稽)就能够成为一位大佬,一枪21亿。
七星凝视的问世让崩坏学园2的数据急剧膨胀,凝魔纹的伤害成为玩家们追捧的对象,那么,凝魔纹具体的计算逻辑是怎样的呢?
为了提高计算的效率,以及分析不同徽章破度对最终dps的影响,闲来无事就写了写代码,希望能帮助有兴趣的小伙伴更好的了解凝魔心所。
本文利用python分析了凝魔心所的输出。
如图所示,凝视暴击的输出为37614164(凝视max暴)或者18807082(凝视max-1爆),接下来利用python分析凝魔心的具体计算。
导入所需的包
import pandas as pd
import numpy as np
测试装备的数据导入
#data_test 包含测试的7件装备的属性
data_test = pd.DataFrame(pd.read_csv(r'/Users/macbookair/Desktop/mihoyo/data_mihoyo/data_sample1.csv',encoding = 'gbk',sep = ','))
#装备破度情况
break_info = data_test[['装备名称','破度1','破度2']]
#基础移速
base_speed = 250
#基础暴击率
base_crit_rate = 5 * 0.01
#基础暴击伤害
base_crit_harm = 2
#基础闪避率
base_miss_rate = 0
#琪亚娜全伤害加成
damage_kiana = 0.05
#琪亚娜圣痕暴击率加成
crit_rate_kiana = 0.4
# 加特林基础攻击力(满级不含亲密、追加)
atk_base = data_test[data_test['装备名称'] == '加特林']['面板'][1]
# 加特林+99、满亲密(觉醒)
atk_plus_rate = (data_test[data_test['装备名称'] == '加特林']['追加'] + data_test[data_test['装备名称'] == '加特林']['亲密度.1']) * 0.002
# 加特林最终面板
atk = atk_base * (1 + atk_plus_rate)[1]
# 此处之所以取int,是因为加特林在计算亲密度和+99之后的实际面板有小数点,游戏实际显示将0.2舍弃了
atk = int(atk)
# 总负重
weight_all_1 = 286
# 琪亚娜圣痕加成20负重
weight_all = weight_all_1 + 20
# 已使用负重
weight_used = np.sum(data_test['负重'])
# 未使用负重
weight_unused = weight_all - weight_used
# 魔术师2技能计算的已使用负重
weight_used_magic = (45 + 50) * 0.2 + 25 + 20
# 魔术师2技能计算的未使用负重
weight_unused_magic = weight_all - weight_used_magic
# 总觉醒数(用于心所一技能计算)
sk_num = np.sum(break_info['破度1']) + np.sum(break_info['破度2'])
# 总觉醒数(用于心所二技能计算)
wake_num = np.sum(data_test['是否觉醒'])
# 主武器是否觉醒
wake_flag = data_test[data_test['装备名称'] == '加特林']['是否觉醒'].reset_index(drop = True)[0]
注意:心所对已经满级突破的装备不能再产生破度增益
(此处可以写循环,后期优化代码)
MACHI_break1 = break_info[break_info['装备名称'] == '加特林']['破度1'].reset_index(drop = True)[0] + 1
MACHI_break2 = break_info[break_info['装备名称'] == '加特林']['破度2'].reset_index(drop = True)[0] + 1
MM_break1 = break_info[break_info['装备名称'] == '米梅']['破度1'].reset_index(drop = True)[0] + 1
MM_break2 = break_info[break_info['装备名称'] == '米梅']['破度2'].reset_index(drop = True)[0]
magic_break1 = break_info[break_info['装备名称'] == '魔术师']['破度1'].reset_index(drop = True)[0] + 1
magic_break2 = break_info[break_info['装备名称'] == '魔术师']['破度2'].reset_index(drop = True)[0] + 1
barrow_break1 = break_info[break_info['装备名称'] == '凝视']['破度1'].reset_index(drop = True)[0]
barrow_break2 = break_info[break_info['装备名称'] == '凝视']['破度2'].reset_index(drop = True)[0] + 1
heart_break1 = break_info[break_info['装备名称'] == '心所']['破度1'].reset_index(drop = True)[0]
heart_break2 = break_info[break_info['装备名称'] == '心所']['破度2'].reset_index(drop = True)[0]
wen_break1 = break_info[break_info['装备名称'] == '纹章']['破度1'].reset_index(drop = True)[0] + 1
wen_break2 = break_info[break_info['装备名称'] == '纹章']['破度2'].reset_index(drop = True)[0] + 1
bp_break1 = break_info[break_info['装备名称'] == '背叛']['破度1'].reset_index(drop = True)[0] + 1
bp_break2 = break_info[break_info['装备名称'] == '背叛']['破度2'].reset_index(drop = True)[0] + 1
wen_close_rate = data_test[data_test['装备名称'] == '纹章']['亲密度'].reset_index(drop = True)[0]
# 加特林
# 输入:1、2技能破度
# 输出:加特林暴击率加成、加特林暴击伤害加成、加特林全伤害加成
def W_MACHI(sk1,sk2):
crit_rate = 1 * 0.01 * (30 + sk1)
crit_harm = 5 * 0.01 * (30 + sk1)
damage = 0.6 + 0.01 * sk2
return crit_rate,crit_harm,damage
# 背叛
# 输入:1、2技能破度
# 输出:背叛移速加成、背叛全伤害加成
def W_BP(sk1,sk2):
speed_plus = (35 + sk1 * 1.5) * 0.01
damage_plus = (100 + sk1 * 2.5) * 0.01
return speed_plus,damage_plus
# 纹章
# 输入:纹章亲密度、2技能破度
# 输出:纹章对主武器的面板攻击力加成
def W_WEN(close_rate,sk2):
atk_plus = close_rate * (3 + sk2 * 0.1)
return atk_plus
# 米梅
# 输入:未使用的负重、1 2技能破度
# 输出:米梅暴击率加成、米梅基础移速加成、米梅闪避率加成
def C_MM(weight_unused,sk1,sk2):
base_speed = weight_unused/weight_all * 100 * (0.7 * 0.01 + sk1 * 0.03 * 0.01)
crit_rate = weight_unused/weight_all * 100 * (0.7 * 0.01 + sk1 * 0.03 * 0.01)
miss_rate = weight_unused/weight_all * 100 * (1 * 0.01 + sk2 * 0.05 * 0.01)
return crit_rate,base_speed,miss_rate
# 魔术师
# 输入:魔术师计算的未使用的负重,12技能破度
# 计算逻辑:计算魔术师1技能暴击率加成,如果暴击率超过50%,将暴击率扣除50%后按照比例转化为暴击伤害,最终的暴击率加成为50%(不满50%暴击率的pass是因为,如果连50%暴击率都不够,那还是别测试了。。)
# 输出:魔术师暴击率加成,魔术师暴击伤害加成
def H_magic(weight_unused_magic,sk1,sk2):
crit_rate = weight_unused_magic * (1 + sk1 * 0.25 * 0.1) * 0.01
if crit_rate > 50 * 0.01:
crit_harm = (crit_rate * 100 - 50) * (1.5 + sk1 * 0.03) * 0.01
crit_rate = 50 * 0.01
else:
pass
return crit_rate,crit_harm
# 凝视一技能
# 根据凝视1技能破度计算凝视产生的暴击率和暴击减益
def H_barrow_p1(sk1):
crit_rate = 1 + sk1 * 2 * 0.01
crit_harm = -0.2 + sk1 * 2 * 0.01
return crit_rate,crit_harm
# 心之所在
# 输入:全身装备技能突破数,觉醒装备数,主武器是否觉醒、心所12技能破度
# 输出:心所全伤害增益、心所常驻移速增益、心所暴击率增益、心所对觉醒且作为主输出武器的暴击伤害加成
def H_heart(sk_num,wake_num,wake_flag,sk1,sk2):
damage = sk_num * (1.5 + sk1 * 0.03) * 0.01
base_speed = wake_num * (5 + sk2 * 0.1) * 0.01
crit_rate = wake_num * (10 + sk2 * 0.2) * 0.01
if wake_flag == 1:
crit_harm = 1 + sk2 * 0.02
else:
crit_harm = 0
return damage,base_speed,crit_rate,crit_harm
将不同装备突破的增益储存在final_list中。
atk = atk + W_WEN(wen_close_rate,wen_break2)
final_list = []
for heart_break1 in range(11):
for barrow_break2 in range(11):
# 加特林增益
crit_rate_MACHI = W_MACHI(MACHI_break1,MACHI_break2)[0]
crit_harm_MACHI = W_MACHI(MACHI_break1,MACHI_break2)[1]
damage_MACHI = W_MACHI(MACHI_break1,MACHI_break2)[2]
# 米梅增益
crit_rate_MM = C_MM(weight_unused,MM_break1,MM_break2)[0]
base_speed_MM = C_MM(weight_unused,MM_break1,MM_break2)[1]
miss_rate_MM = C_MM(weight_unused,MM_break1,MM_break2)[2]
# 魔术师增益
crit_rate_magic = H_magic(weight_unused_magic,magic_break1,magic_break2)[0]
crit_harm_magic = H_magic(weight_unused_magic,magic_break1,magic_break2)[1]
# 凝视1技能增益
crit_rate_barrow = H_barrow_p1(barrow_break1)[0]
crit_harm_barrow = H_barrow_p1(barrow_break1)[1]
# 心所计算准备
sk_num = np.sum(break_info['破度1']) + np.sum(break_info['破度2'])
wake_num = np.sum(data_test['是否觉醒'])
wake_flag = 1
# 心所增益
damage_heart = H_heart(sk_num,wake_num,wake_flag,heart_break1,heart_break2)[0]
base_speed_heart = H_heart(sk_num,wake_num,wake_flag,heart_break1,heart_break2)[1]
crit_rate_heart = H_heart(sk_num,wake_num,wake_flag,heart_break1,heart_break2)[2]
crit_harm_heart = H_heart(sk_num,wake_num,wake_flag,heart_break1,heart_break2)[3]
# 背叛增益
speed_bp = W_BP(bp_break1,bp_break2)[0]
damage_bp = W_BP(bp_break1,bp_break2)[1]
#总增益汇总
crit_rate_sum = base_crit_rate + crit_rate_kiana + crit_rate_MM + crit_rate_MACHI + crit_rate_magic + crit_rate_barrow + crit_rate_heart
crit_harm_sum = (base_crit_harm + crit_harm_MACHI + crit_harm_magic + crit_harm_barrow \
+ crit_harm_heart ) * 2
damage_sum = (1 + damage_kiana) * (1 + damage_MACHI) * (1 + damage_heart) * (1 + damage_bp) * 1.1 * 1.02
miss_rate_sum = 1 - (1 - base_miss_rate) * (1 - miss_rate_MM)
base_speed_sum = base_speed_MM + base_speed_heart + speed_bp
# 输入:总暴击率、总暴击伤害、凝视2技能破度
# 计算逻辑:总暴击率取整+1,设为num,作为凝视的max暴击次数(求期望需将总暴击率的小数部分,不妨设为p1,作为n-1爆的概率,1-p1则为凝视max爆的概率,将p1和p2分别乘以对应的暴击输出后,求数学期望得出,此处仅考虑了max爆的输出情况),将凝视2技能的暴击下限作为临界值min,分别计算总暴击伤害经过一轮轮暴击伤害减益后,满足大于临界值的减益后暴击伤害与若干临界值,append至凝视num轮产生的暴击伤害list中,等待下一步处理。
def H_barrow_p2(crit_rate_sum,crit_harm_sum,sk2):
barrow_list = []
num = int(crit_rate_sum) + 1
crit_harm_min = (150 + 5 * sk2) * 0.01
for i in range(num):
crit_harm_dec = crit_harm_sum * (1 - (42 * 0.01 - sk2 * 0.7 * 0.01) * i)
if crit_harm_dec > crit_harm_min:
barrow_list.append(crit_harm_dec)
else:
barrow_list.append(crit_harm_min)
return num,crit_harm_min,barrow_list
#print(H_barrow_p2(crit_rate_sum,crit_harm_sum,barrow_break2))
barrow_list = H_barrow_p2(crit_rate_sum,crit_harm_sum,barrow_break2)[2]
#print(barrow_list)
def multi_list(l):
result = 1
for i in range(len(l)):
result *= l[i]
return result
def H_barrow_p3(barrow_list):
if len(barrow_list) == 1:
damage = barrow_list[0]
else:
damage = multi_list(barrow_list)
return damage
crit_harm = H_barrow_p3(barrow_list)
print(crit_harm)
def final_output(atk,damage_sum,crit_harm):
final_output = atk * damage_sum * crit_harm
return final_output
print(final_output(atk,damage_sum,crit_harm))
out = final_output(atk,damage_sum,crit_harm)
final_list.append(out)
final_list = np.array(final_list)
final_list = final_list.reshape([11,11])
心所12技能不同破度对应的输出数值见下图,由于测试装备中的心所12技能分别为10、10破,(此处可能存在bug,心所的一技能将自己的一技能也实现了突破,虽然是9-10,但是实际是10-10破)故结果为右下角数值,与木桩测试结果几乎一致。
木桩测试结果:37614164
附:不同装备破度的收益情况【其他测试装备除背叛、纹章,均为满破】
1、魔术师12技能破度从0-0到10-10对加特林的输出增益分布:
2、凝视12技能破度从0-0到10-10对加特林的输出增益分布:
3、加特林12技能破度从0-0到10-10对加特林的输出增益分布:
结合以上数据可见,凝视2技能的破度对装备输出的贡献最为明显。