Python分析【崩坏学园2】凝魔纹心所输出

Python分析【崩坏学园2】凝魔纹心所输出

前言

【崩坏学园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']]

主要装备的数据情况
Python分析【崩坏学园2】凝魔纹心所输出_第1张图片

Part1 基础指标:

基础指标:
#基础移速
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
加特林面板计算(不含纹章2技能加成):
# 加特林基础攻击力(满级不含亲密、追加)
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]

Part2 装备破度:

注意:心所对已经满级突破的装备不能再产生破度增益
(此处可以写循环,后期优化代码)

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]

Part3 装备技能定义:

# 加特林
# 输入: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

Part4 计算各装备各技能的增益(暴击率、暴击伤害等):

将不同装备突破的增益储存在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破)故结果为右下角数值,与木桩测试结果几乎一致。
Python分析【崩坏学园2】凝魔纹心所输出_第2张图片
木桩测试结果:37614164

附:不同装备破度的收益情况【其他测试装备除背叛、纹章,均为满破】

1、魔术师12技能破度从0-0到10-10对加特林的输出增益分布:
Python分析【崩坏学园2】凝魔纹心所输出_第3张图片
2、凝视12技能破度从0-0到10-10对加特林的输出增益分布:
Python分析【崩坏学园2】凝魔纹心所输出_第4张图片
3、加特林12技能破度从0-0到10-10对加特林的输出增益分布:
Python分析【崩坏学园2】凝魔纹心所输出_第5张图片

结合以上数据可见,凝视2技能的破度对装备输出的贡献最为明显。

你可能感兴趣的:(崩坏学园2)