伪随机触发-增强OR削弱?PA大招不如剑圣被动?

发本文前本来就是想看看斧王是否削弱,PA大和jugg被动哪个屌,途中发现这个伪随机很有意思,就弄来看看了。

名词解释:

DOTA内伪随机触发:

对一个总体触发概率为的技能(注:高于0.4后伪随机效果不明显,如先锋盾等,此时按真随机应用就好)。在尝试触发时,若连续N-1次没有触发,则第N次触发时的真实触发概率为

详情见:PlayDota

例如

PA的暴击总体触发概率为0.15,那么它对应的C=0.03222。
第一次攻击时,真实触发概率为0.03222,若没有触发,第二次攻击的真实触发概率为0.03222*2……。若连续31次攻击都没有触发暴击,那么第32次的真实触发概率为1.0310,第32次攻击必暴。

结论先睹为快

首先请明确以下几点:
(1)我们分析的是技能在一场战斗中收益的期望,而非特定的某场战斗,更不是对整局游戏。
同时,由于每次技能触发都会重置触发器,消除之前所有战斗的影响。所以我们仅从战斗前最近一次触发开始,来统计技能对单次战斗的效果。
(2)此图仅展示了几个较典型的曲线,其余都做过计算,大部分都在0.9左右到达平台,估计0。05也是。
设技能触发器全部重置,看看同样攻击次数下伪随机的触发次数期望和真随机的触发次数期望对比。

图解 :以0.15概率对应的曲线为例,也就是PA大招的概率。

打5下的时候,暴击效果只有真随机的60%左右,总共可以有50,150,6的触发次数
打10下的时候,暴击效果已经恢复到80%,总共能暴击100.150,8次
打15下的时候,暴击效果已经恢复到85%的水平,一共可能暴击150.150,85次

 

从图中很显然可以看出:

1.虽然从理论上可以推测所有曲线的极限必然趋近1的,但在按照图示的恢复速度,在可以接受的范围内(50次普攻左右),可以认为伪随机相对真随机是削弱的。
2.伪随机下的技能,按攻击次数计时,战斗前期进被削弱,然后慢慢恢复 ,战斗后期稳定工作。
3.触发率越高的技能前期削弱越小,恢复至较好状态的速度也越快

我们来继续看另一组对比,这组对比与战斗效果无关,只是来看看伪随机是否可以如预期那样减少看脸的因素,也就是输出方差相对真随机是否变小。

这个图像展示了随攻击次数增加伪随机攻击稳定性相对真随机的变化。

可以看到

  1. 输出稳定性相对真随机得到了提升,至少2倍左右
  2. 触发几率越低的技能,在前10次攻击的稳定性提升越明显
  3. 触发稳定性都是先降低后升高,最后稳定在3倍于真随机附近。

综合来看

1.使用伪随机对游戏输出整体是削弱的
2.游戏显得不那么看脸了,随机因素少了,欢乐的因素也少了。
就是说伪随机下可以更稳定的打出整体比较低的伤害,而非不稳定的打出整体较高的伤害,减少随机性,这和冰蛙的思路是符合的,好比徐涅沙,1秒晕1点伤害的悲惨故事注定成为过去。

应用:

来分析斧王。
显然可以知道,反击螺旋从真->伪整体削弱了,电风扇和一下都不转都成为过去,但是你现在脸再怎么好也没有以前输出高了。再来看看PA大招和jugg被动

来看看换算后PA和jugg的15次平A内输出差距有多大?

Jugg微弱领先了一次普攻,在这种有暴击的英雄面前,1次普攻的领先其实就是55开。闲人君不防做测试,同样的神装战撸绝对五五开。

满级互撸也就五五开,而jugg的被动是小技能,16级前必然已经点满,显然jugg的被动更厉害。

作为一个游戏机制,竟然不能平等的对待每个技能, 对于我这种喜欢PA的玩家,看到这样的数据真是对伪随机一脸泪。

PA大招不加强到2,4,6倍根本不能算大招好么。

最后,我玩jugg的话就直接A杖斩死你了,谁还跟你撸。

数学部分

高中概率大致就能做,计算部分需要编程计算而已,这一部分仅仅作为补充,我尽量精简的带过。

期望与方差

水平有限,纯理论推导出N次攻击期望公式比较复杂,只利用计算机计算有限次的期望值.

对于真随机,显然n次攻击中的触发次数X遵循二项分布,只计算伪随机了。
首先计算连续N-1次攻击不暴击,恰好第N次攻击暴击的概率。比较繁琐,具体方法就是coding,得到的结果就是该死的playdota官网上给的图,误导了我很久。这张图什么也看不出,因为他不是分布函数的图像(我不得不吐槽老外,常常没图也要强行画图上去,没错但是也没用)

再利用刚才的计算进一步穷举来计算分布函数,不赘述,我们直接看对比结果。

显然可以看出:

  • 伪随机的输出变得高瘦了许多,这意味着方差变小,也就是说输出更加稳定.
  • 伪随机的对称轴略微左移,意味着均值变小,也就是说输出降低了.
  • 让期望和方差与二项分布的做一下比值,就可以得到最开始展示的曲线图了。

Read more

Coroutine

从一般概念上说, 协程是特殊的函数调用: 被调用的函数可以在可控的位置被中断,然后在下一次调用时,继续从上次中断的位置继续执行。 本文主要通过Python的协程来介绍协程, 这是我唯一熟悉的一种协程实现. Classic Coroutine 下面的python代码很好的说明了协程的核心功能 def co_routine(): recv0 = yield 996 # hangs here after first coro.send assert recv0 == "Second" yield 711 # hangs here after second coro.send return def main(): coro = co_routine() # Create a new coroutine object value = coro.send(None)

By Edimetia3D

GDB with Python

这篇文章的主要应用场景是调试Python的C/C++ Extension 1. 同时使用pdb / gdb 进行调试. 通俗点说, 既可以break在 .py 文件中,也可以break在 .cc 文件中 2. 在gdb中不但可以获得常规的调试信息, 还可以获得python VM 的调试信息, 例如获得python的调用栈, 访问Python局部变量等. 这将会在调试exception时(如Segmentfalut)非常有用, 这种场景下, 定位 Python VM 正运行到哪一行代码往往可以提供一些直观的重要信息. 第一步: 编译源码以获得一些辅助数据. 我们并不真的需要使用从源码编译的Python, 但是一些调试相关的辅助文件需要从源码中获得, 包括 python-gdb.py及debug symbol等. 在 https://www.python.org/ftp/python/ 或 https://github.com/python/cpython

By Edimetia3D

Bazel Notes

这是一篇2019年左右的记录, 内容可能过时, 也不太全面 杂谈 Bazel是Google为Monorepo服务而开发的构建工具. 首先是巨大,当问题的规模变大,事情总是会变得更复杂. 而Google面对的"巨大Monorepo",应该是世间罕有的. 然后是Monorepo,这极大的影响了代码的组织风格.例如,你要写一个操作系统内核ProjectOS,还要写一个游戏ProjectGame.在传统的开发习惯中,这两个项目会组织到两个不同的Repo里,PorjectOS和ProjectGame之间无法直接相互引用,例如,你在ProjectOS里写了一个高级的数据结构,想要在Game里也使用,要么直接复制粘贴,要么是创建一个新的CommonRepo,把可公用的代码都放在Common里,然后两个项目各自引入Common作为依赖. 使用MonoRepo则不存在这个问题,Game可以直接依赖OS内的组件,按照Bazel的语法描述,就是在Game中可以直接使用@ProjectOS//path/to/package:AdvancedStruct.当然,你仍然可以选择重构一

By Edimetia3D

Unix related things

这是一篇2017年左右的记录, 仅用作分享 杂 * 在shell内能干的事,我们都可以比较简单地通过系统调用实现. * `称为反引号,^称为脱字符,常用来表示CTRL * windows的系统调用是不开放的,windows下只能直接使用windows.h里的windows API. * /dev目录下的设备是供用于程序直接使用的,主要由block,char,pipe,socket类型 * 并不是所有设备都能映射为这种形式 * /sys/device/目录称为sysfs,他下面存放了所有设备的信息.(不能直接从/dev获得任何设备信息) * udevadm info --query=all --name="/dev/sda1"可以用于查询/dev下某个设备对应的sysfs路径 权限系统 * 权限系统由两部分组成 * 文件属性:用于标注文件owner,所属组,以及权限的设定(默认只有owner和root可以修改权限设置) *

By Edimetia3D