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

[新人攻略] 考虑奥义情况下的队伍连击收益

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

    [LV.5]

    管理员

    Rank: 9Rank: 9Rank: 9

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

    卓越贡献元老勋章

    发表于 2018-10-30 11:41:14 | 显示全部楼层 |阅读模式
    不考虑奥义的情况在不考虑奥义时其实就是一个数学问题,每回合的连击期望HPT=(1-DA)*(1-TA)+2*DA*(1-TA)+3*TA,一个双曲抛物面的一部分。
    将这个式子化简到HPT=1+DA+2*TA-DA*TA,在DA和TA足够小的情况下,TA带来的收益接近DA的2倍。 一句废话
    在实际操作过程中因为奥义回合和奥义效果等因素印象,实际伤害提升期望应低于无奥义情况,且收益随连击提高而降低。

    考虑简单奥义的情况假定伤害均为上限的情况下,以不同连击率模拟四个白板队员队伍木桩战斗十万回合。
    模拟结果存在部分瑕疵,比如在满ta情况下没有错开奥义,不过不影响大部分情况
    也有可能是我哪里写错了
    − 部分代码 ...
    10w层的尾递归,编译器靠你了(
    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:

    #include <iostream>
    #include <cv.hpp>
    #include <stdlib.h>     
    #include <time.h>
    using namespace std;
    using namespace cv;
    #define ACTTIMES 100000
    class asCharacter {
    private:
    &#8195;&#8195;const double ct = 168.0 / 44.0;
    &#8195;&#8195;double da, ta, randda, randta;
    &#8195;&#8195;int cb;
    &#8195;&#8195;double totAtk, totCA, totCB;
    &#8195;&#8195;bool caed;
    public:
    &#8195;&#8195;string name;
    &#8195;&#8195;asCharacter* firstChara;
    &#8195;&#8195;asCharacter* nextChara;
    &#8195;&#8195;asCharacter(string n, double d, double t) {
    &#8195;&#8195;&#8195;&#8195;name = n;
    &#8195;&#8195;&#8195;&#8195;da = d;
    &#8195;&#8195;&#8195;&#8195;ta = t;
    &#8195;&#8195;&#8195;&#8195;cb = 0;
    &#8195;&#8195;&#8195;&#8195;totAtk = 0;
    &#8195;&#8195;&#8195;&#8195;totCA = 0;
    &#8195;&#8195;&#8195;&#8195;totCB = 0;
    &#8195;&#8195;&#8195;&#8195;nextChara = NULL;
    &#8195;&#8195;&#8195;&#8195;firstChara = this;
    &#8195;&#8195;}
    &#8195;&#8195;void CBUp() {
    &#8195;&#8195;&#8195;&#8195;if (caed) return;
    &#8195;&#8195;&#8195;&#8195;cb += 10;
    &#8195;&#8195;&#8195;&#8195;if (cb > 100) cb = 100;
    &#8195;&#8195;}
    &#8195;&#8195;bool isCAed() {
    &#8195;&#8195;&#8195;&#8195;return caed;
    &#8195;&#8195;}
    &#8195;&#8195;void act(int time = 1) {
    &#8195;&#8195;&#8195;&#8195;caed = false;
    &#8195;&#8195;&#8195;&#8195;if (cb == 100) {
    &#8195;&#8195;&#8195;&#8195;&#8195;&#8195;caed = true;
    &#8195;&#8195;&#8195;&#8195;&#8195;&#8195;totCA++;
    &#8195;&#8195;&#8195;&#8195;&#8195;&#8195;cb = 0;
    &#8195;&#8195;&#8195;&#8195;&#8195;&#8195;for (auto ii = firstChara; ii != NULL; ii = ii->nextChara) {
    &#8195;&#8195;&#8195;&#8195;&#8195;&#8195;&#8195;&#8195;if (ii == this) continue;
    &#8195;&#8195;&#8195;&#8195;&#8195;&#8195;&#8195;&#8195;ii->CBUp();
    &#8195;&#8195;&#8195;&#8195;&#8195;&#8195;}
    &#8195;&#8195;&#8195;&#8195;}
    &#8195;&#8195;&#8195;&#8195;else {
    &#8195;&#8195;&#8195;&#8195;&#8195;&#8195;randda = rand() / (RAND_MAX + 1.0);
    &#8195;&#8195;&#8195;&#8195;&#8195;&#8195;randta = rand() / (RAND_MAX + 1.0);
    &#8195;&#8195;&#8195;&#8195;&#8195;&#8195;if (ta > randta) {
    &#8195;&#8195;&#8195;&#8195;&#8195;&#8195;&#8195;&#8195;totAtk += 3;
    &#8195;&#8195;&#8195;&#8195;&#8195;&#8195;&#8195;&#8195;cb += 37;
    &#8195;&#8195;&#8195;&#8195;&#8195;&#8195;}
    &#8195;&#8195;&#8195;&#8195;&#8195;&#8195;else if (da > randda) {
    &#8195;&#8195;&#8195;&#8195;&#8195;&#8195;&#8195;&#8195;totAtk += 2;
    &#8195;&#8195;&#8195;&#8195;&#8195;&#8195;&#8195;&#8195;cb += 22;
    &#8195;&#8195;&#8195;&#8195;&#8195;&#8195;}
    &#8195;&#8195;&#8195;&#8195;&#8195;&#8195;else {
    &#8195;&#8195;&#8195;&#8195;&#8195;&#8195;&#8195;&#8195;totAtk++;
    &#8195;&#8195;&#8195;&#8195;&#8195;&#8195;&#8195;&#8195;cb += 10;
    &#8195;&#8195;&#8195;&#8195;&#8195;&#8195;}
    &#8195;&#8195;&#8195;&#8195;&#8195;&#8195;if (cb > 100) cb = 100;
    &#8195;&#8195;&#8195;&#8195;}
    &#8195;&#8195;&#8195;&#8195;if (nextChara != NULL) nextChara->act();
    &#8195;&#8195;&#8195;&#8195;else {
    &#8195;&#8195;&#8195;&#8195;&#8195;&#8195;int canum = 0;
    &#8195;&#8195;&#8195;&#8195;&#8195;&#8195;for (auto ii = firstChara; ii != NULL; ii = ii->nextChara)
    &#8195;&#8195;&#8195;&#8195;&#8195;&#8195;&#8195;&#8195;if (ii->isCAed()) canum++;
    &#8195;&#8195;&#8195;&#8195;&#8195;&#8195;if (canum >= 2)
    &#8195;&#8195;&#8195;&#8195;&#8195;&#8195;&#8195;&#8195;if (canum >= 3) totCB += 1;
    &#8195;&#8195;&#8195;&#8195;&#8195;&#8195;&#8195;&#8195;else totCB += 0.5;
    &#8195;&#8195;&#8195;&#8195;}
    &#8195;&#8195;&#8195;&#8195;if (time > 1) act(time - 1);
    &#8195;&#8195;}
    &#8195;&#8195;double out() {
    &#8195;&#8195;&#8195;&#8195;return totAtk + ct*totCA;
    &#8195;&#8195;}
    &#8195;&#8195;double cbout() {
    &#8195;&#8195;&#8195;&#8195;return ct*totCB;
    &#8195;&#8195;}
    };

    //...

    int main() {

    //...

    &#8195;&#8195;for (i = 1; i <= 100; i++)
    &#8195;&#8195;&#8195;&#8195;for (j = 1; j <= 100; j++) {
    &#8195;&#8195;&#8195;&#8195;&#8195;&#8195;da = i / 100.0;
    &#8195;&#8195;&#8195;&#8195;&#8195;&#8195;ta = j / 100.0;
    &#8195;&#8195;&#8195;&#8195;&#8195;&#8195;asCharacter a("1", da, ta);
    &#8195;&#8195;&#8195;&#8195;&#8195;&#8195;asCharacter b("2", da, ta);
    &#8195;&#8195;&#8195;&#8195;&#8195;&#8195;asCharacter c("3", da, ta);
    &#8195;&#8195;&#8195;&#8195;&#8195;&#8195;asCharacter d("4", da, ta);
    &#8195;&#8195;&#8195;&#8195;&#8195;&#8195;a.nextChara = &b;
    &#8195;&#8195;&#8195;&#8195;&#8195;&#8195;b.nextChara = &c;
    &#8195;&#8195;&#8195;&#8195;&#8195;&#8195;c.nextChara = &d;
    &#8195;&#8195;&#8195;&#8195;&#8195;&#8195;b.firstChara = &a;
    &#8195;&#8195;&#8195;&#8195;&#8195;&#8195;c.firstChara = &a;
    &#8195;&#8195;&#8195;&#8195;&#8195;&#8195;d.firstChara = &a;
    &#8195;&#8195;&#8195;&#8195;&#8195;&#8195;a.act(ACTTIMES);
    &#8195;&#8195;&#8195;&#8195;&#8195;&#8195;map[j][0] = a.out() / (double)ACTTIMES;
    &#8195;&#8195;&#8195;&#8195;&#8195;&#8195;map[j][1] = b.out() / (double)ACTTIMES;
    &#8195;&#8195;&#8195;&#8195;&#8195;&#8195;map[j][2] = c.out() / (double)ACTTIMES;
    &#8195;&#8195;&#8195;&#8195;&#8195;&#8195;map[j][3] = d.out() / (double)ACTTIMES;
    &#8195;&#8195;&#8195;&#8195;&#8195;&#8195;map[j][4] = d.cbout() / (double)ACTTIMES;
    &#8195;&#8195;&#8195;&#8195;&#8195;&#8195;a.~a();
    &#8195;&#8195;&#8195;&#8195;&#8195;&#8195;b.~b();
    &#8195;&#8195;&#8195;&#8195;&#8195;&#8195;c.~c();
    &#8195;&#8195;&#8195;&#8195;&#8195;&#8195;d.~d();
    &#8195;&#8195;&#8195;&#8195;}

    //...

    &#8195;&#8195;return 0;
    }






    最后数据经处理和可视化得到下图
    1.jpg
    可能不太直观,这个模拟出的点云并不是像理论中双曲面一样的直纹面,用原始数据与用四角数据插值出的数据相减并归一化,得出下图
    2.jpg
    与预期基本符合

    结论:没有结论,硬要说的话连击率提升在理论提升的80+4%,因为考虑因素过少所以这个结论其实没有任何意义,在伤害打不到上限或奥义有特殊buff的情况下还会有更大的偏差。
    不过因为拟合的结果跟模拟误差在5%以内,所以可以认为靠理论计算出的收益是定性成立的。
    要得出更有意义的结果只能考虑固定的队伍搭配下进行模拟。

    附上模拟出的数据,txt格式[链接]
    &#8722; 数据的一种用法 ...
    可以将数据导入excal,通过函数功能进行不同连击率之间的伤害对比速查
    假设将数据导入到命名为data的工作表中,再另一个工作表的B1到B4分别输入以两个连击率,通过公式
    =INDIRECT("data!"&ADDRESS(B3,B4,4))/INDIRECT("data!"&ADDRESS(B1,B2,4))
    就能快速得出新连击率的DPT提升
    3.jpg




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

    该用户从未签到

    [ Lv.1 新 伙 伴 ]

    Rank: 1

    阳光
    315
    人气
    7
    G点
    0
    任务金卷
    0
    发表于 2018-12-19 01:28:27 | 显示全部楼层
    确实不错,眼前一亮的好文
    回复 支持 反对

    使用道具 举报

    您需要登录后才可以回帖 登录 | 注册

    本版积分规则

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

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

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

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

    Powered by 一哥网 X3.4

    © 2001-2013 www.1g31.com

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