一哥手游欢迎您
QQ登陆 注册 找回密码
查看: 723|回复: 1

[新人攻略] 天羽羽斩的验证和九头龙斩收益的理论计算

[复制链接]
  • TA的每日心情
    开心
    2022-10-5 18:24
  • 签到天数: 36 天

    [LV.5]

    管理员

    Rank: 9Rank: 9Rank: 9

    性别
    帅哥
    阳光
    1133
    人气
    22857
    G点
    9671
    任务金卷
    0
    居住地
    湖北省 宜昌市
    QQ
    QQ
    玩的手游
    刀塔传奇

    卓越贡献元老勋章

    发表于 2018-10-30 11:48:44 | 显示全部楼层 |阅读模式
    在还没有别的可靠来源验证前,先用自己测试验证的数据,有差错以后再修正
    先说静态性质的奥义和技能效果:
    奥义:
    给自己上一个5000HP的血盾,持续3回合
    25%几率给自己上一个九连斩buff,下回合行动3次并且必定三连
    终破追加的九头龙斩可以说是非常引人注目,之后会对这个九头龙斩的收益进行详细的推算

    技能1:
    攻中暴击中,天羽相比石油枪的一大优势就是不亏攻刃,15技的攻刃中暴击中还算可以

    技能2:
    连击时累计攻击up,独立成算,每次10%,最大80%。DATA皆可触发。
    连击时累计上限up,最大10%,每次的叠加有点难测,之后的计算中我们估算成一样最大8次,一次1.25%,最大10%
    类似石油枪的叠攻效果,倍率没有石油枪+200%那么高,不过+80%已经能在很多情况下摸到天花板了。
    终破追加的+10%上限up说多不多,总之算是缓解了那么一点摸上限的问题

    剑圣解放后会追加一个35%的追伤,类似的卡姐剑,六道刀都有同款追伤

    有了这些静态数据之后我们就开始计算这些技能的收益。
    考虑到现在天羽可以用的职业基本上只有荣光,跨职业的比较比较复杂也意义不大。
    作为自嗨型武器,为了方便计算,我们先只计算主角个人的伤害收益,队伍的总体收益则之后靠主角个人的收益进行估算。

    由于叠攻的随机性以及九头龙斩的随机性,直接算式计算比较麻烦,所以选择写个程序的方法来计算。
    基础思路是是定义一个状态 (回合数,当前奥义,叠攻层数)
    对于每个状态,有两个对应的参数,一个是该状态的触发几率,一个是该状态的期望伤害
    一个状态则可以根据一定规则计算出下一个状态的伤害。
    例如初始状态是(0,30,0)=(100%几率,0伤害)平砍44W,50DA 50TA
    该状态能衍生出来的新状态有:
    单击(1, 41, 0) = (25%几率, 44W),DA(1, 54, 1) = (25%几率, 88W), TA(1, 70, 1) = (50%几率, 132W)
    基于这样的规则就可以计算出任意回合任意状态下的伤害。
    具体代码
    − 点击显示隐藏的内容 ...
    Code c:
    1:
    2:
    3:
    4:
    5:
    6:
    7:
    8:
    9:
    10:
    11:
    12:
    13:
    14:
    15:
    16:
    17:
    18:
    19:
    20:
    21:
    22:
    23:
    24:
    25:
    26:
    27:
    28:
    29:
    30:
    31:
    32:
    33:
    34:
    35:
    36:
    37:
    38:
    39:
    40:
    41:
    42:
    43:
    44:
    45:
    46:
    47:
    48:
    49:
    50:
    51:
    52:
    53:
    54:
    55:
    56:
    57:
    58:
    59:
    60:
    61:
    62:
    63:
    64:
    65:
    66:
    67:
    68:
    69:
    70:
    71:
    72:
    73:
    74:
    75:
    76:
    77:
    78:
    79:
    80:
    81:
    82:
    83:
    84:
    85:
    86:
    87:
    88:
    89:
    90:
    91:
    92:
    93:
    94:
    95:
    96:
    97:
    98:
    99:
    100:
    101:
    102:
    103:
    104:
    105:
    106:
    107:
    108:
    109:
    110:
    111:
    112:
    113:
    114:
    115:
    116:
    117:
    118:
    119:
    120:
    121:
    122:
    123:
    124:
    125:
    126:
    127:
    128:
    129:
    130:
    131:
    132:
    133:
    134:
    135:
    136:
    137:
    138:
    139:
    140:
    141:
    142:
    143:
    144:
    145:
    146:
    147:
    148:
    149:
    150:
    151:
    152:
    153:
    154:
    155:
    156:
    157:
    158:
    159:
    160:
    161:
    162:
    163:
    164:
    165:
    166:
    167:
    168:
    169:
    170:
    171:
    172:
    173:
    174:
    175:
    176:
    177:
    178:
    179:
    180:
    181:
    182:
    183:
    184:
    185:
    186:
    187:
    188:
    189:
    190:
    191:
    192:
    193:
    194:
    195:
    196:
    197:
    198:
    199:
    200:
    201:
    202:
    203:
    204:
    205:
    206:
    207:
    208:
    209:
    210:
    211:
    212:
    213:
    214:
    215:
    216:
    217:

    #include <iostream>
    #include <string>
    #include <math.h>

    struct cell
    {
        double p = 0; // p for possibility
        double expect_dmg = 0;
    };

    int AutoCap(int base_dmg, double cap_boost) {
      double x1 = 30*(1+cap_boost/100.0)*10000;
      double x2 = 40*(1+cap_boost/100.0)*10000;
      double x3 = 50*(1+cap_boost/100.0)*10000;
      double x4 = 60*(1+cap_boost/100.0)*10000;
      if (base_dmg < x1) return round(base_dmg);
      if (base_dmg < x2) return round(x1 + (base_dmg-x1) * 0.8);
      if (base_dmg < x3) return round(x1 + (x2-x1) * 0.8 + (base_dmg-x2) * 0.6);
      if (base_dmg < x4) return round(x1 + (x2-x1) * 0.8 + (x3-x2) * 0.6 + (base_dmg - x3) * 0.05);
      return round(x1 + (x2-x1) * 0.8 + (x3-x2) * 0.6 + (x4-x3) * 0.05 + (base_dmg-x4) * 0.01);
    }

    int OugiCap(int base_dmg, double cap_boost) {
      double x1 = 150*(1+cap_boost/100)*10000;
      double x2 = 170*(1+cap_boost/100)*10000;
      double x3 = 180*(1+cap_boost/100)*10000;
      double x4 = 250*(1+cap_boost/100)*10000;
      if (base_dmg < x1) return round(base_dmg);
      if (base_dmg < x2) return round(x1 + (base_dmg-x1) * 0.6);
      if (base_dmg < x3) return round(x1 + (x2-x1) * 0.6 + (base_dmg-x2) * 0.3);
      if (base_dmg < x4) return round(x1 + (x2-x1) * 0.6 + (x3-x2) * 0.3 + (base_dmg - x3) * 0.05);
      return round(x1 + (x2-x1) * 0.6 + (x3-x2) * 0.3 + (x4-x3) * 0.05 + (base_dmg-x4) * 0.01);
    }

    int main() {
        // 计算器内伤害
        const int base_dmg_in_calculator = 2500000;
        // Boss防御率,低防满破甲/高防无破甲5,高防满破甲10
        const int enemy_def_rate = 5;
        // 基础平砍上限
        const int base_auto_dmg_cap_boost = 16;
        // 平砍追伤百分比
        const int auto_echo = 35;
         
        // 奥义倍率
        const int ougi_modifier = 5;
        // 基础奥义上限
        const int base_ougi_dmg_cap_boost = 16;
        // 基础DA
        const int base_da = 20;
        // 基础TA
        const int base_ta = 20;
         
        // 九连斩触发率,设置成0来模拟其他武器
        const int habakiri_ougi_possibility = 25;
        // 累计攻击up倍率,设置成0来模拟其他武器
        const double habakiri_stack_modifier = 0.1;
        // 累计上限up倍率,设置成0来模拟其他武器
        const double habakiri_stack_dmg_cap_boost = 1.25;
        // 累计up最大值,设置成0来模拟其他武器
        const int habakiri_max_stackable = 8;
         
        // 多少奥义值能使用奥义,设置成90 80 70之类的来模拟队友带的奥义
        const int ougi_threshold = 100;
        // 最大回合数
        const int total_turn = 30;
         
        cell f[total_turn + 1][102][habakiri_max_stackable + 1];
         
        // 设置初始状态
        f[0][30][0].p = 1;
        f[0][30][0].expect_dmg = 0;
         
        for (int turn = 0; turn<=total_turn-1; turn++)
            for (int ougi = 0; ougi<=101; ougi++)
                for (int stack = 0; stack<=habakiri_max_stackable; stack++) {
                    double p = f[turn][ougi][stack].p;
                    double expect_dmg = f[turn][ougi][stack].expect_dmg;
                    // 用101奥义来表示九连斩状态
                    if (ougi == 101) {
                        int next_ougi = ougi+ 100 > 100 ? 100 : ougi+ 100;
                        int next_stack = stack + 3 > habakiri_max_stackable ?
                                            habakiri_max_stackable :
                                            stack + 3;
                        double next_p = p;
                        // 计算器火力乘以累计攻up,除以防御率
                        int actual_dmg = round(base_dmg_in_calculator * (1+ habakiri_stack_modifier * stack) / enemy_def_rate);
                        // 实际上限up
                        int cap_up = base_auto_dmg_cap_boost + habakiri_stack_dmg_cap_boost * stack;
                        // 累计伤害 = 上回合伤害+衰减后伤害 × 追伤倍率 × 9
                        double next_dmg = expect_dmg + AutoCap(actual_dmg, cap_up)* (1 + auto_echo/100.0) * 9;
                        cell* next_cell = &f[turn+1][next_ougi][next_stack];
                        if (next_cell->p == 0) {
                            next_cell->expect_dmg = next_dmg;
                            next_cell->p = next_p;
                        } else {
                            next_cell->expect_dmg = (next_dmg * next_p + next_cell->expect_dmg * next_cell->p) / (next_p + next_cell->p);
                            next_cell->p += next_p;
                        }
                        continue;
                    }
                    // 使用奥义的情况
                    if (ougi >= ougi_threshold) {
                        int next_stack = stack + 0 > habakiri_max_stackable ?
                                            habakiri_max_stackable :
                                            stack + 0;
                        double next_p_2 = p * habakiri_ougi_possibility/100.0;
                        double next_p = p * (1 - habakiri_ougi_possibility/100.0);
                        // 计算器火力乘以累计攻up,除以防御率
                        int actual_dmg = round(base_dmg_in_calculator * (1+ habakiri_stack_modifier * stack) / enemy_def_rate);
                        // 实际上限up
                        int cap_up = base_auto_dmg_cap_boost + habakiri_stack_dmg_cap_boost * stack;
                        // 累计伤害 = 上回合伤害+衰减后伤害
                        double next_dmg = expect_dmg + OugiCap(actual_dmg * ougi_modifier, cap_up);
                        // 没有触发9连的情况
                        cell* next_cell = &f[turn+1][0][next_stack];
                        if (next_cell->p == 0) {
                            next_cell->expect_dmg = next_dmg;
                            next_cell->p = next_p;
                        } else {
                            next_cell->expect_dmg = (next_dmg * next_p + next_cell->expect_dmg * next_cell->p) / (next_p + next_cell->p);
                            next_cell->p += next_p;
                        }
                        // 触发9连的情况
                        next_cell = &f[turn+1][101][next_stack];
                        if (next_cell->p == 0) {
                            next_cell->expect_dmg = next_dmg;
                            next_cell->p = next_p_2;
                        } else {
                            next_cell->expect_dmg = (next_dmg * next_p_2 + next_cell->expect_dmg * next_cell->p) / (next_p_2 + next_cell->p);
                            next_cell->p += next_p_2;
                        }
                        continue;
                    }
                    // 单击
                    {
                        int next_ougi = ougi+ 11 > 100 ? 100 : ougi+ 11;
                        int next_stack = stack + 0 > habakiri_max_stackable ?
                                            habakiri_max_stackable :
                                            stack + 0;
                        double next_p = p * (1 - base_ta/100.0) * (1 - base_da/100.0);
                        // 计算器火力乘以累计攻up,除以防御率
                        int actual_dmg = round(base_dmg_in_calculator * (1+ habakiri_stack_modifier * stack) / enemy_def_rate);
                        // 实际上限up
                        int cap_up = base_auto_dmg_cap_boost + habakiri_stack_dmg_cap_boost * stack;
                        // 累计伤害 = 上回合伤害+衰减后伤害 × 追伤倍率 × 1
                        double next_dmg = expect_dmg + AutoCap(actual_dmg, cap_up)* (1 + auto_echo/100.0) * 1;
                        cell* next_cell = &f[turn+1][next_ougi][next_stack];
                        if (next_cell->p == 0) {
                            next_cell->expect_dmg = next_dmg;
                            next_cell->p = next_p;
                        } else {
                            next_cell->expect_dmg = (next_dmg * next_p + next_cell->expect_dmg * next_cell->p) / (next_p + next_cell->p);
                            next_cell->p += next_p;
                        }
                    }
                    // 二连
                    {
                        int next_ougi = ougi+ 24 > 100 ? 100 : ougi+ 24;
                        int next_stack = stack + 1 > habakiri_max_stackable ?
                                            habakiri_max_stackable :
                                            stack + 1;
                        double next_p = p * (1 - base_ta/100.0) * (base_da/100.0);
                        // 计算器火力乘以累计攻up,除以防御率
                        int actual_dmg = round(base_dmg_in_calculator * (1+ habakiri_stack_modifier * stack) / enemy_def_rate);
                        // 实际上限up
                        int cap_up = base_auto_dmg_cap_boost + habakiri_stack_dmg_cap_boost * stack;
                        // 累计伤害 = 上回合伤害+衰减后伤害 × 追伤倍率 × 2
                        double next_dmg = expect_dmg + AutoCap(actual_dmg, cap_up)* (1 + auto_echo/100.0) * 2;
                        cell* next_cell = &f[turn+1][next_ougi][next_stack];
                        if (next_cell->p == 0) {
                            next_cell->expect_dmg = next_dmg;
                            next_cell->p = next_p;
                        } else {
                            next_cell->expect_dmg = (next_dmg * next_p + next_cell->expect_dmg * next_cell->p) / (next_p + next_cell->p);
                            next_cell->p += next_p;
                        }
                    }
                    // 三连
                    {
                        int next_ougi = ougi+ 40 > 100 ? 100 : ougi+ 40;
                        int next_stack = stack + 1 > habakiri_max_stackable ?
                                            habakiri_max_stackable :
                                            stack + 1;
                        double next_p = p * base_ta/100.0;
                        // 计算器火力乘以累计攻up,除以防御率
                        int actual_dmg = round(base_dmg_in_calculator * (1+ habakiri_stack_modifier * stack) / enemy_def_rate);
                        // 实际上限up
                        int cap_up = base_auto_dmg_cap_boost + habakiri_stack_dmg_cap_boost * stack;
                        // 累计伤害 = 上回合伤害+衰减后伤害 × 追伤倍率 × 3
                        double next_dmg = expect_dmg + AutoCap(actual_dmg, cap_up)* (1 + auto_echo/100.0) * 3;
                        cell* next_cell = &f[turn+1][next_ougi][next_stack];
                        if (next_cell->p == 0) {
                            next_cell->expect_dmg = next_dmg;
                            next_cell->p = next_p;
                        } else {
                            next_cell->expect_dmg = (next_dmg * next_p + next_cell->expect_dmg * next_cell->p) / (next_p + next_cell->p);
                            next_cell->p += next_p;
                        }
                    }
                }
        for (int turn = 0; turn<=total_turn; turn++) {
            // std::cout<< turn << ",";
            double total_p = 0;
            double total_expect_dmg = 0;
            for (int ougi = 0; ougi<=101; ougi++)
                for (int stack = 0; stack<=habakiri_max_stackable; stack++) {
                    cell print_cell = f[turn][ougi][stack];
                    if (print_cell.p!=0) {
                        total_p += print_cell.p;
                        total_expect_dmg += print_cell.expect_dmg * print_cell.p;
                    }
                }
            std::cout.precision(1000);
            std::cout<< round(total_expect_dmg) << std::endl;
        }
    }




    c



    有这个程序之后我们可以计算出各种状况下天羽的伤害期望。
    下面有3个场景,每个场景我们对比一下白版武器(相当于卡剑主手六道剑主手的剑圣),有叠攻技能的伤害,有叠攻并且有九头龙奥义的伤害。
    这样可以比较清楚的看到叠攻技能的价值,和九头龙奥义的收益。
    假设主角的计算器火力是250W,有BUFF的毕业盘不难达到,既然都在考虑天羽了,我相信盘子大概已经毕业了。
    技能之类的先无视掉,只考虑35%的剑神解放追伤。

    场景1,低防,高连击(50DA 50TA)
    1.jpg
    场景2,高防,高连击(50DA 50TA)
    2.jpg
    场景3,低防,低连击(20DA 20TA)
    3.jpg

    通过拆解叠攻和九头龙奥义的提升,我们可以看到:
    1,叠攻的收益比较依赖高防场景,低防环境收益只有12-15%,高防能有56%
    2, 九头龙斩的收益大概是16-20%,起到一个锦上添花的作用
    3,两者结合起来则能够在低防环境产生35%左右的收益,无论连击高低,可以看到九头龙斩作为一个连击辅助带来的稳定性
    类似石油枪,比较擅长的高防环境则是能有最大80%左右的收益

    上面所说的这些收益,是仅限主角个人的,假设主角和队友的基础伤害配比是1:1:1:1到1.5:1:1:1之间,我们可以大致估算一下天羽的收益
    低防环境团队收益大概9%-12%,高防环境团队收益大概20%-27%左右。
    实际的收益则会因为伤害配比的变化而发生变化,不过大致来说主角个人伤害越高(例如荣光开追击),团队收益越高
    当然,我们换了其他的主手武器,有可能会有更优秀的奥义效果,所以上面这个估算可以说估的是一个收益上限。
    但是总体来说,相比石油枪,天羽的表现算是一个相当不错的武器了,要发挥出比较高的价值还是需要高防本,但是低防本的效果并不差。

    至于石油琴,看团里有哪个土豪愿意兑换之后我再进行测试和推算好了。



    捐赠方式支持论坛,捐赠获得阳光请捐赠  一哥网ACG游戏精英家园!
    -----------------------------------------------------------------------------------------------------------
    你就认真回复也行啊!总之!不要白瞟!从我做起,请发帖!请点评!请回复!
    -----------------------------------------------------------------------------------------------------------
    【 认真点评 】 【 认真回复  】认真发帖 】!谢谢大家!
    您需要登录后才可以回帖 登录 | 注册

    本版积分规则

    客服:| 客服QQ: 2607818610 | 商务QQ:19878895 | 服务邮箱:ohyeah@vip.qq.com | 商务电话:13637860062

    公安机关备案号:50010602501574|网站地图|小黑屋|

    一哥ACG ( 渝ICP备13004552号-1)

    GMT+8, 2024-9-1 09:30 , Processed in 0.188506 second(s), 37 queries , Gzip On.

    Powered by 一哥网 X3.4

    © 2001-2013 www.1g31.com

    快速回复 返回顶部 返回列表