资讯中心
您当前的位置: 首页> 资讯中心
【数据篇】理论向眩晕流
发布时间:2018-03-16 14:00:00

原帖发布者/x3144875

原帖地址:https://tieba.baidu.com/p/5432584620?

 

先说些题外话,本人是从事机器学习,数据分析,图像处理方向,坐标东京某IT公司。眩晕流是我妻子在玩这个游戏抽到太多的布利和菲尔德时,我给她出的建议。她的账号是vip5,我的是vip8,ios国际服s66服务器。但本人不玩眩晕流只有她玩。

我为了在和她辩论这个阵容的可行性时可以说服她,于是从理论层面进行了一些分析和模拟。理论上来说,给定两个阵容,每个阵容的所有参数都确定时,那么这两个阵容打架的胜率也是确定的。

最多15回合,每回合有12个英雄发动攻击或反击,魔兽一般最多出手5次。如果把一个状态(双方阵容的所有当前状态)当成一个节点,每个节点由于放技能的随机性,会生成若干个子节点。父节点到子节点通过可计算的概率进行转移。那么整个战斗流程的随机过程是一个深度大约为200层的多叉树。所以说战斗的所有随机情况都可以进行模拟,进而计算概率。

然而这个树的深度过深,并且要遍历整个树才可以计算准确的胜率,所以是np难问题,(当然可以做一些trade-off进行剪枝)每秒进行10亿次计算的计算机要计算10的40次方年才可能计算完这个概率。所以计算胜率基本上是不可行的。

如果从机器学习角度,收集大量对战数据才能训练模型,现阶段同样也不现实。所以我们选择阵容时,很难严密的评价阵容的优劣,于是可以用一些贪心策略去进行大概的衡量。题外话到此结束,我们来讨论一下眩晕流。

首先,现在所有的眩晕都是2回合(包括龙,普攻,技能,被动),可以带来额外额外伤害的debuff目前只有冰冻(冰闪),流血(血刃),燃烧(西格蒙德,毁灭者),中毒(马拉萨),眩晕(菲尔德)。能制造眩晕的英雄是最多的,而且多数较好获得。

本帖想讨论一下眩晕流的pvp可行性,虽然对pve有用的部分只有爬塔。本帖会有不严谨的地方,和理想化的地方,希望吧友自行判断或理性讨论。


先列出眩晕的英雄和魔兽,以10星和满级为基准:
菲尔德(速度:1140,普攻眩晕概率:对1号位75%,技能:随机4人159%伤害,刺客100%眩晕,被动:对眩晕单位额外造成125%伤害);
布利(速度:1123,普攻眩晕概率:对1号位65%,技能:对所有人25%,被动:死亡对后排45%概率眩晕);
米迦勒(速度:1188,技能:随机4人40%概率眩晕);
沃尔特(速度:1169,技能:后排随机2人50%概率眩晕);
荣耀守卫(速度:1152,技能:后排30%概率眩晕);
古斯塔(速度:1155,技能:后排32%概率眩晕);


下面是一些对特殊职业眩晕的英雄:
OD-01(速度:1126,技能:全体,对牧师100%概率眩晕);
鲁特兹(速度:1166,技能:随机4人,对法师100%概率眩晕);
星光(速度:1123,技能:后排,对游侠35%概率眩晕,备注:几乎不会用在眩晕流里)


其中菲尔德,布利,荣耀守卫,古斯塔,od-01,鲁特兹非常容易获取,米迦勒,沃尔特有一定难度,星光暂且不予考虑。


魔兽龙:满级随机4人,36%概率眩晕


眩晕流的核心思想是持续控制和利用菲尔德的对眩晕额外125%伤害的被动打出足够输出。

先来探讨持续控制,四个关键点,一是速度,二是控制概率,三是能量,四是命中。


一、我们先说速度和能量。

由于输出依赖了菲尔德的被动,所以其他5个英雄主要是提供辅助,提供充足眩晕为菲尔德制造输出环境。
魔兽和科技:为所有英雄提供相同的速度,上限120点(科技80,魔兽40),所以假设魔兽科技速度全满,大家收益相同,所以不讨论魔兽带来的速度收益。
宝石:带有速度,假设橙色三星:80点
神器:带有速度,红42,橙66
不同英雄有不同的宝石和神器配置,所以是讨论重点。
目前最快英雄是美树:10星基础1200,最快控制类:米迦勒和黑暗阿辛多1188,最快刺客:血刃1172
持续控制畏惧的是出手前被控和出手前被秒。

高速也分为两类,一类控制型英雄,一类爆发型刺客英雄。

一般来讲,对面的控制型英雄会堆速度(宝石),神器带能量+50,爆发型刺客英雄基本不会带速度宝石或神器。
所以我们的思路是,在第二轮抢在所有爆发型刺客之前放出控制。如果对面没有这类英雄,我们也显然可以在回血类辅助和持续伤害型战士出手之前放出控制。
然而带最多眩晕的布利,基础速度只有1123,但好在布利的普通攻击也带眩晕,所以神器也可佩戴速度,这样1123+神器66=1189点速度,大于米迦勒和阿辛多。
另一个提供速度的途径就是艾米丽(技能使友军速度提升30点),艾米丽一定是眩晕流的终极辅助,并需要速度宝石和能量神器,在速度宝石的支持下,艾米丽可以使队伍在第二轮出手速度大于多数英雄。


关于速度和能量的结论是:
1.眩晕流最好配置艾米丽(速度宝石,能量神器)
2.眩晕流英雄的神器宝石选择:
米迦勒(速度宝石,可不带速度神器)
布利(速度宝石,必带速度神器)
荣耀守卫(速度宝石,最好速度神器)
古斯塔(速度宝石,最好速度神器)
沃尔特(宝石和神器最好有一个速度)
OD-01(速度宝石,必带速度神器)
鲁特兹(宝石和神器最好有一个速度)
3.很难应对的对手:恶魔猎手,黑暗阿辛多,米迦勒,(注:1号位的能量神器冰闪很好应对,因为冰闪带了能量神器速度不够造成威胁)


二、我们来讨论眩晕概率,这涉及到了英雄选择,带有眩晕的10星英雄除去星光有8个。为了讨论眩晕概率,简单起见,我做一些理想假设:
1.假设战斗前x回合内,我方没有人阵亡,没有人被控制
2.假设对面是木桩,不会攻击我方(不会带来我方能量变化)
3.不考虑对特殊职业的眩晕
4.魔兽在3k+1的回合开始放技能
那么在x回合内每个回合我方所有人施放技能前的时刻,和我方所有人施放技能后的时刻,对方每个单位被眩晕的概率都是可以模拟计算的。

下面是我用于模拟概率的代码,花1个小时简单写了一下(语言是python):
```
def updateStunRate(originRate, newRate):
return 1-(1-originRate)*(1-newRate)
def calculateStunRate(n,m,hitRate,stunRate):
return min(m,n)/n*hitRate*stunRate
def calStunRateWithDragon(heroesWithStun, roundNum):
heroes = heroesWithStun
res = []
beforeHeroesRes = []
tmpResThisRound = {'first_place':0,
'second_place':0,
'back_line':0}
dragonEnergy = 0
for i in range(roundNum):
tmpResNextRound = {'first_place':0,
'second_place':0,
'back_line':0}
if i%3 ==2:
r = calculateStunRate(6,4,1,0.36)
tmpResThisRound['first_place'] = updateStunRate(tmpResThisRound['first_place'],r)
tmpResNextRound['first_place'] = updateStunRate(tmpResNextRound['first_place'],r)
tmpResThisRound['second_place'] = updateStunRate(tmpResThisRound['second_place'],r)
tmpResNextRound['second_place'] = updateStunRate(tmpResNextRound['second_place'],r)
tmpResThisRound['back_line'] = updateStunRate(tmpResThisRound['back_line'],r)
tmpResNextRound['back_line'] = updateStunRate(tmpResNextRound['back_line'],r)
b = tmpResThisRound.copy()
b['stunned_count_expectation'] = b['first_place']+b['second_place']+b['back_line']*4
beforeHeroesRes.append(b)
for hero in heroes:
r1,r2,rb = [0,0,0]
if hero[1] < 100 :
r1 = hero[0]['attack_stun_rate']
hero[1] += 50
else :
if hero[0]['spell_type'] == 'all':
r1 = hero[0]['spell_stun_rate']
r2,rb = r1,r1
if hero[0]['spell_type'] == 'backline':
rb = calculateStunRate(4,hero[0]['spell_object_number'],1,hero[0]['spell_stun_rate'])
if hero[0]['spell_type'] == 'random':
r1 = calculateStunRate(6,hero[0]['spell_object_number'],1,hero[0]['spell_stun_rate'])
r2,rb = r1,r1
hero[1]=0
tmpResThisRound['first_place'] = updateStunRate(tmpResThisRound['first_place'],r1)
tmpResNextRound['first_place'] = updateStunRate(tmpResNextRound['first_place'],r1)
tmpResThisRound['second_place'] = updateStunRate(tmpResThisRound['second_place'],r2)
tmpResNextRound['second_place'] = updateStunRate(tmpResNextRound['second_place'],r2)
tmpResThisRound['back_line'] = updateStunRate(tmpResThisRound['back_line'],rb)
tmpResNextRound['back_line'] = updateStunRate(tmpResNextRound['back_line'],rb)
tmpResThisRound['stunned_count_expectation'] = tmpResThisRound['first_place']+tmpResThisRound['second_place']+tmpResThisRound['back_line']*4
res.append(tmpResThisRound)
tmpResThisRound = tmpResNextRound
return res,beforeHeroesRes
```
英雄的定义:

```
Field = {'spell_stun_rate':0,
'attack_stun_rate':0.75,
'spell_type':'random',
'spell_object_number':4,
'hitRate':1}
Bleeker ={'spell_stun_rate':0.25,
'attack_stun_rate':0.65,
'spell_type':'all',
'spell_object_number':6,
'hitRate':1}
Michelle = {'spell_stun_rate':0.4,
'attack_stun_rate':0,
'spell_type':'random',
'spell_object_number':4,
'hitRate':1}
Walter = {'spell_stun_rate':0.5,
'attack_stun_rate':0,
'spell_type':'backline',
'spell_object_number':2,
'hitRate':1}
HonorGuard = {'spell_stun_rate':0.3,
'attack_stun_rate':0,
'spell_type':'backline',
'spell_object_number':4,
'hitRate':1}
Gusta = {'spell_stun_rate':0.32,
'attack_stun_rate':0,
'spell_type':'backline',
'spell_object_number':4,
'hitRate':1}
```

用于测试的阵容(第二个变量是初始能量,带能量神器就是100,不带就是50):
```
#[Hero, Initial Energy]
test1 = [[Field,50], [Bleeker,50]]
test2 = [[Field,50], [Bleeker,50], [Walter,50], [HonorGuard,50]]
test3 = [[Field,50], [Bleeker,50], [Walter,50], [HonorGuard,50], [Gusta,50]]
test4 = [[Field,50], [Bleeker,50], [Walter,50], [HonorGuard,50], [Gusta,50],[Michelle,50]]
test5 = [[Field,50], [Bleeker,50], [Walter,50], [Gusta,50]]
test6 = [[Field,50], [Bleeker,50], [HonorGuard,50]]
test7 = [[Field,50], [Bleeker,50], [Gusta,50]]
test8 = [[Field,50], [Bleeker,50]]
test9 = [[Field,50], [Bleeker,50],[Walter,100],[HonorGuard,50],[Michelle,50]]

```

现在取x为9,我们来看一下前9回合对方被眩晕的概率:
res, beforeHeroesRes = calStunRateWithDragon(test9,9)
我方带的眩晕英雄是 菲尔德,布利,沃尔特,荣耀守卫,米迦勒,米迦勒和沃尔特带能量神器。
对方被眩晕的概率,back_line是后排任一英雄,first_place是一号位,second_place是二号位,stunned_count_expectation是对应行被眩晕的人数的数学期望(可以理解为对面大概能有几个人被晕)
每回合我方英雄出手前(魔兽出手后):

每回合我方英雄出手后:


可以看到,平均每回合大概会有4个左右的对手会被控制,但是二号位很难被控制。对于其他阵容的测试图片太多,暂时不贴,会用python的可以拿走代码。结论是,布利提供的眩晕是最充足的,在对面没有特定职业时(刺客,法师,牧师),提供眩晕的能力方面,布利>米迦勒>古斯塔>荣耀守卫>沃尔特>菲尔德。在第一节讨论速度时,得出速度的高收益,
那么做一下考虑速度和眩晕的排序,不考虑对面职业时,眩晕流里菲尔德>布利(可多个)>艾米丽(一个就够)>米迦勒>沃尔特>古斯塔>荣耀守卫
如果对面有特定职业,如果法师,建议上鲁特兹,如果牧师建议上OD-01,
惧怕的敌人:米迦勒(免控),带免控神器的暗系(好像只有暗系专属神器有免控),全光系(光环免控)


三、稍微说一下命中,由于游侠和法师科技里包含命中,目前闪避较高的是人类的某些英雄,游侠和法师的15%命中以及阵容克制的15%命中,或许对于高闪避英雄可能有一定限制(不知道有没有命中+速度的宝石)。


四、其他
关于伤害,在视频里可以看到,不算很高,但也不低,由于带有控制,打出被动之后伤害还算可观。

如果菲尔德每次大招对命中单位平均伤害40w的话,理想情况7个回合一般可以解决战斗。

由于这个游戏暂时还没有控制递减,可以造成持续控制,提高生存,这种生存不依赖护甲和血量,所以成本较低。低成本就意味着高风险,因为如果一旦运气不好晕不到,就会团灭。

如果你喜欢稳扎稳打的阵容,那么眩晕流一定不合适。如果你喜欢夸战力取胜来获得成就感,或者喜欢看着对手无还手之力的窃喜,那我建议你可以尝试这样的阵容。
总的来说,在拥有菲尔德和布利之后,这个眩晕流的英雄搭配也不算很难,而且可选择性也大,成长空间也有,不需要全部十星也可发挥一定威力。
最后,眩晕流的好处是可以用低成本的阵容去抗衡一些比较难应对的阵容,但是也有明显的缺陷:
1.阵容虽然成本低,但对速度要求高
2.对手免控高闪避高速是很大的威胁
3.对2号位限制普遍较小
4.对boss无力(地牢,试炼和爬塔不算很好,但也不差,地牢可以用特定英雄打特定职业,爬塔可以堵运气,试炼可以得到眩晕带来的生存保证)


好了,先写这么多,以后有机会也可以多做些别的测试。对于错误的地方,希望大家理性指正。(能看到结尾的人应该不多吧)

 

【小编有话说】

其实看完整篇的时候,小编的脑袋也是晕的,特别的那串代码。这篇技术帖虽说是理论向的,但是确实有可取之处。在原帖中,还有一些具体的讨论可做考虑。如原帖作者所说,有兴趣的完全可以去尝试一下,这是一个需要冒险精神的尝试。

 

wechat