考虑奥义情况下的队伍连击收益
不考虑奥义的情况在不考虑奥义时其实就是一个数学问题,每回合的连击期望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:
const double ct = 168.0 / 44.0;
double da, ta, randda, randta;
int cb;
double totAtk, totCA, totCB;
bool caed;
public:
string name;
asCharacter* firstChara;
asCharacter* nextChara;
asCharacter(string n, double d, double t) {
name = n;
da = d;
ta = t;
cb = 0;
totAtk = 0;
totCA = 0;
totCB = 0;
nextChara = NULL;
firstChara = this;
}
void CBUp() {
if (caed) return;
cb += 10;
if (cb > 100) cb = 100;
}
bool isCAed() {
return caed;
}
void act(int time = 1) {
caed = false;
if (cb == 100) {
caed = true;
totCA++;
cb = 0;
for (auto ii = firstChara; ii != NULL; ii = ii->nextChara) {
if (ii == this) continue;
ii->CBUp();
}
}
else {
randda = rand() / (RAND_MAX + 1.0);
randta = rand() / (RAND_MAX + 1.0);
if (ta > randta) {
totAtk += 3;
cb += 37;
}
else if (da > randda) {
totAtk += 2;
cb += 22;
}
else {
totAtk++;
cb += 10;
}
if (cb > 100) cb = 100;
}
if (nextChara != NULL) nextChara->act();
else {
int canum = 0;
for (auto ii = firstChara; ii != NULL; ii = ii->nextChara)
if (ii->isCAed()) canum++;
if (canum >= 2)
if (canum >= 3) totCB += 1;
else totCB += 0.5;
}
if (time > 1) act(time - 1);
}
double out() {
return totAtk + ct*totCA;
}
double cbout() {
return ct*totCB;
}
};
//...
int main() {
//...
for (i = 1; i <= 100; i++)
for (j = 1; j <= 100; j++) {
da = i / 100.0;
ta = j / 100.0;
asCharacter a("1", da, ta);
asCharacter b("2", da, ta);
asCharacter c("3", da, ta);
asCharacter d("4", da, ta);
a.nextChara = &b;
b.nextChara = &c;
c.nextChara = &d;
b.firstChara = &a;
c.firstChara = &a;
d.firstChara = &a;
a.act(ACTTIMES);
map = a.out() / (double)ACTTIMES;
map = b.out() / (double)ACTTIMES;
map = c.out() / (double)ACTTIMES;
map = d.out() / (double)ACTTIMES;
map = d.cbout() / (double)ACTTIMES;
a.~a();
b.~b();
c.~c();
d.~d();
}
//...
return 0;
}
最后数据经处理和可视化得到下图
可能不太直观,这个模拟出的点云并不是像理论中双曲面一样的直纹面,用原始数据与用四角数据插值出的数据相减并归一化,得出下图
与预期基本符合
结论:没有结论,硬要说的话连击率提升在理论提升的80+4%,因为考虑因素过少所以这个结论其实没有任何意义,在伤害打不到上限或奥义有特殊buff的情况下还会有更大的偏差。
不过因为拟合的结果跟模拟误差在5%以内,所以可以认为靠理论计算出的收益是定性成立的。
要得出更有意义的结果只能考虑固定的队伍搭配下进行模拟。
附上模拟出的数据,txt格式[链接]
− 数据的一种用法 ...
可以将数据导入excal,通过函数功能进行不同连击率之间的伤害对比速查
假设将数据导入到命名为data的工作表中,再另一个工作表的B1到B4分别输入以两个连击率,通过公式
=INDIRECT("data!"&ADDRESS(B3,B4,4))/INDIRECT("data!"&ADDRESS(B1,B2,4))
就能快速得出新连击率的DPT提升
确实不错,眼前一亮的好文
页:
[1]