论war3中的随机数系统

转帖来源:http://war3.replays.net/bbs/htm_data/2/0609/866031.html 

war3 中的随机数系统 ( 重新编写版 ) 英文版在 MYM 主页放出 感谢 ryanz9 翻译 | 感谢 rn_tl 纠错 已用红字修正
 
写在前面 : 最初的我,来 RN 只是为了下录像,当有一天 ShortRound 突然出现在 RN bbs 的时候,为了回帖,我拥有了自己在 RN 的第一个 id 。最初的时候,只回帖不发贴,灌了几百帖之后,我觉着应该写些什么有意义的东西了。于是大约两个月前,我在 Hum 区发了这篇文章,当时激起了激烈的讨论。前两天有人在综合区发过原文了,相信不少人也看过了,经过这段时间,我对原文有了一些改进,依照承诺发上来,主要是 做了一些内容上的补充更新和重新排版,更利于理解。 当然,还是那句话,其实这里面的部分结论只是我的猜测,而且验证起来也比较困难,所以算是抛砖引玉吧,欢迎大家一起讨论。
 
原贴地址 :http://war3.replays.net/bbs//htm_data/102/0607/727518.html 
­  
English Version
Translater & Rewriter ryanz9 ): http://www.meetyourmakers.com/article/127.html ­  
 
cga 转贴时的评论 : 国内某神秘达人对于 WAR3 游戏中的随机系统的解释,非常专业;建议各位读者看看,会得益不少  
神秘达人 ?呵呵,偷笑。  
 
_________________________ 
Part 1: 关于攻击力的随机值问题  
 
大家都知道, war3 里面攻击力是有范围的, DH 的闪避、 BM 的暴击等都是有概率的。所以在 war3 里,随时随地都是有随机事件发生的。但大家可能没注意过,攻击力的随机值是怎样产生的呢?是全范围内的等概率事件,还是如二项式曲线一样中间数值概率高、两边数值概率低?  
 
正确的答案是这样的
1
、对于所有的法师、建筑、召唤生物等不可以升级攻击力的单位来说,分布是平均的,范围内所有数据产生的概率是一样的;  
2
、对于 英雄 和所有可以升级攻击力的常规攻击单位来说,是中间的数值概率高,两边的概率低。  
至于具体的原因和分布概率,请看下面详解。 ­  
 
大家应该都看过魔兽的中文帮助,细心的朋友可能发现了,有些版本的帮助中,对攻击力的数值的表述不是一个由下限到上限的具体数字范围,而是用的类似这样一个式子 A+BdC (其中 ABC 均为自然数)。比如 0 rm 吧,用前一种表述方法就是 18-24 ,而用后一种表述方法则为 :16+2d4 。有人可能会问了,这种表述方法是什么意思呢?  
 
这其实表示, war3 中攻击力的概率分布使用的是 d&d 骰子系统。通俗一点的理解就是 : 任何兵种都是有一个基础攻击力数值 A (比如 rm 就是 16 ), B 则代表骰子数量(比如 rm 就是 2 ), C 则代表骰子的面数(比如 rm 就是 4 ,这里不一定是 6 啊, war3 不是搓麻)。 rm 每攻击一次,系统就扔出两个 4 面的骰子(骰子扔出 1-4 的概率是相同的),假如扔出来的数值是 2 4 ,那么这一次攻击的数值就是 16+2+4=22 。当然啦,当扔出的都是 1 时,就是最小值 18 ,当都是 4 时,就是最大值 24  
 
现在来研究一下攻击力分布概率的问题。继续拿 0 攻的 rm 举例,其他的兵种道理是一样的。 ­  
18
24 :1+1 4+4                             一种可能性 概率 1/16  
19
23 :1+2 2+1 3+4 4+3               两种可能性 概率 2/16 
20
22 :1+3 2+2 3+1 2+4 3+3 4+2 )三种可能性 概率 3/16 
21             :1+4
2+3 3+2 4+1                 四种可能性 概率 4/16 
可以看出来,越居中的数值随机出来的可能性越高,而两边的数值概率是对称的,距中心数值越远概率越低。  
­  
也许可能有人要问了,那 rm18-24 的攻击力为什么不能表示为 17+1d7 或者 15+3d3 呢?这两个式子也代表了 18-24 这个攻击范围啊?这是一个好问题,如果各位 war3er 看到这里能提出这个问题的话,说明你是个善于动脑、善于思考的人。  
 
答案是这样的,大家想一下, war3 对攻击力的升级是怎么实现的呢?很简单,就是加一个骰子。再拿 rm 举例, 0 攻的 rm 攻击力是 16+2d4 1 攻的 rm 攻击力是 19-28 ,用先前的表示法就是 16+3d4 ,正好是 B 值增加了一点。而如果是 17+1d7 或者 15+3d3 这两个式子的话,升一攻加一个骰子后变成 17+2d7 或者 15+4d3 ,这分别对应于 19-31 19-27 ,这与事实是不符的。同理, 2 3 攻的 rm 的攻击力分别为 16+4d4 20-32 )、 16+5d4 21-36 )。  
­  
现在大家再看一下这个式子 :A+BdC ,升 1 2 3 级攻后 B 分别为 B+1 B+2 B+3  
可以看出, A 越大、 B 越小、 C 越大,那么升级攻后对攻击力的提升更加显著。下面列表看一下各族各个兵种的攻击力数值(召唤生物、法师没有列出,因为他们不能升级攻防,于本文没有讨论意义)
 
Hero: 
PAL   22+2d5 BM 24+2d12 DH   22+2d12 DK     23+2d6 
AM   19+2d4 FS 19+2d4   KOG 18+2d4   LICH   20+2d4 
MK   24+2d6 TC 25+2d5   POM 19+2d5   DL     20+2d6
­  
BMG 19+2d4 SH 20+2d4   WD   20+2d11 CL     26+2d4 
DR   21+2d6 PD 22+2d6   FL   20+2d4   NAGA 22+2d6
­  
BM   22+2d6 PL 26+2d6   GA   25+3d10 Tinker 22+2d4
 
 
HUM:             ORC:               NE:                 UD: 
民兵 :11+1d2     G:   17+1d4   ac:     15+1d3   g:   10+2d2 
fm: 11+1d2    
猎头 :   22+1d5   ht:     15+1d3   zz:     25+1d6  
rm: 16+2d4    
粉碎者 :71+1d18 投刃车 : 35+1d18 g:   17+1d4 
74:   25+2d5  
狼骑 :   22+1d5   小鹿 :   16+1d3           60+1d10 
破法 :12+1d3   飞龙 :   34+2d5   doc:   18+1d4     绞肉车 : 70+1d18 
飞机 :6+1d2     蝙蝠 :   12+1d3   熊形态 : 26+3d6   abo:   32+1d7 
      13+1d2    
牛头 :   29+1d7   角鹰 :   49+1d8   des:   18+1d3 ­  
小炮 :51+1d13                         角鹰骑 : 15+1d3   冰龙 :   91+2d12 
坦克 :44+1d11                         精灵龙 : 13+1d3   骷髅 :   13+1d2 
      12+1d2                          
奇美拉 : 66+1d17 
49: 44+1d11                                   44+1d11 
61: 17+1d3                          
山岭 :   26+2d7 
                                                    32+2d8 
                                          dot
: 34+1d7  
 
关于此表的相关讨论 : ­  
0 、关于英雄的攻击力 :A 即为初始的主要属性值,升级后 A 随主要属性值的增加而增加,而 B C 不会改变;绝大部分 B=2 ,其分布概率如 0 攻的 rm C 值一般都在 4-6 之间,除了 BM DH WD ,由于拥有较高的敏捷值,他们三个也是 DPS 最高的英雄。还有一个不得不提醒大家注意的英雄 :GA (地精炼金术士),唯一的 B=3 C 更是高得离谱,虽然攻速低了些,但配合化学狂暴和酸性炸弹,也可以提供非常高的攻击输出。下表列出了 BM DH 和主升狂暴的 GA DPS ,可见成长性还是相当好的, Blizzcon Zacard TM 上打 Grubby 就是使用的 GA ,不过最后输了,不知道能不能发展出围绕它的相应战术。只可惜敏捷值太可怜了, 10 级也只有 4 点甲 -_-! 
  BM   DH  
狂暴 GA 
Lv1 30.94 29.65 24.90 
Lv3 33.90 30.92 41.23 
Lv5 41.69 37.62 62.78
 
1
、可以看出,初级兵里 zz A C 值最高,所以也是初级兵力最贵的。  
2
49 、奇美拉、小炮、三种 CAT 都符合 A 大、 B 小、 C 大的原则,也就是说,对于他们升攻对攻击力的提高是显著的。(这里要注明一下,如果从纯数学的角度计算,应该是 :A 越小、 B 越小、 C 越大则升攻后对攻击力的提升更加显著,有些朋友在回复中提到了这一点。这并不是笔误,我当是在写此文的时候考虑到这一点了,但我认为衡量一个单位的攻击力的高低是要综合考虑 A C 的大小的,而 A C 同时都很大的单位,其攻击力输出通常是可怖的,而且看我上面列的表格会发现, A C 大的单位几乎没有,所以我的结论也是依据这一点。)  
3
、有一个不得不提的就是熊德,它是所有法师里(如果它算法师的话)唯一升级还会加攻击力的。而变形后的熊也比较特殊,它是唯一 B 值为 3 的,而 C 值也只有 6 ,升攻对它的效果并不显著,只是因为 B 值较大,攻击力范围很大而已。  
4
、对于争论较多的角鹰和天鬼,他们对空攻击力之比约为 4:5 ,考虑到攻击间隔分别为 1.05 1.4 dps 之比约为 14:13 ,再考虑到血量(按照 1 点护甲 =6% 血量,角鹰 525 ,天鬼约 484 )和速度(角鹰 400 、天鬼 350 ),纯对 PK 的话,角鹰强。  
5
、对于 C 值小于 4 的(比如 des 61 ),升攻对它们是没什么太大作用的。  
6
UD 的绞肉车数据上并不逊于 ORC 的粉碎者,而且攻频还稍快( 4s 4.5s ),不过粉碎者有小范围的溅射;三本升级则各有所长。  
 
对于这部分更多讨论可以参看 0imm 的帖子: 同样质疑下下攻击 关于 war3 中的随机数系统 ­  
http://war3.replays.net/bbs//htm_data/102/0607/729351.html 
­  
还有要强调的一点就是 : 对于 B=1 的兵种来说,升攻前因为只有一颗骰子,所以它们的攻击力概率分布是均匀的,当 B>1 后就符合前文所说的中间概率高,两边概率低的规律了。 ­  
 
_____________________________ 
Part 2: Replay 重现随机事件的方法  
 
这方面的内容,是有关 war3 本身程序原理的,我只是提出自己的一种假说而已,真正的答案可能要去问 war3 的设计者,写在这里是希望大家一起来参与讨论。  
 
除了攻击力的随机值, war3 中还存在大量的其他的随机事件,比如英雄的被动技能、 Miss 的产生,甚至包括出生点的确定、英雄的姓名、宝物的掉落也都是随机事件。在比赛中这些随机事件发生的时候,和攻击力的随机值的产生一样,只需要系统产生一个或多个随机数就可以了,但在播放 Replay 的时候,会怎样呢?  
 
大家应该都用过 W3G Master 来查看 Replay ,从操作列表里我们可以看出 Replay 的工作原理: rep 记录的是时间序列,即什么时间什么坐标的单位,以什么样的命令,指向目标坐标;而对于这个动作所造成的结果,是在播放 rep 时进行实时演算的。比如,坐标( 1 1 )的 fm ,以动作指令 “A” ,指向坐标( 3 3 )的 DH ;而对于这次攻击实际造成的伤害, rep 里是不会、也没有必要、甚至是不能记录的。于是问题就产生了,由于随机系统的存在,每一次动作指令造成的结果是不确定的, fm 可能给 dh 造成 8 点伤害,也可能被 dh 闪避掉,怎么才能保证播放 rep 时真实的重现当时的情况呢? ­  
 
一种解释是 : 对于每一个动作, rep 都记录下对应于它的随机数。  
 
这种解释看似最方便直接,但仔细想想,又有不合理的地方,因为其数据量过于庞大了,要知道一次攻击通常都会产生不止一个随机数。我使用过 W3G Master w3chart 这两款 Replay 分析软件,在操作列表里一共只有四项数据:玩家、时间、动作、坐标(我们常用的 W3G Master 动作 坐标 整合为 操作 ),并没有 随机值 这项数据。如果 rep 真的记录了每次动作所对应的随机值的话,分析软件里为什么不列出来呢?是分析软件读不出 rep 中记录的随机数么?技术手段足以达到了;是分析软件读到了但没有列出此项数据么?完全没有必要。所以,真正的情况很可能是 :Replay 里并没有记录随机数。  
 
依此,对于 Replay 的工作原理,我认为须遵循如下要素:  
1
、必须能够真实的再现当时的情况,这一点毋庸置疑。  
2
、数据量要尽量地少,能够用一个数干到的事情,绝不用三个数。这就像学 C 的时候老师说过:代码越精干越好,能够用少量代码完成的事情,绝不用大量的代码。  
 
于是有人又提出这样一种解决办法 : 既然不记录每次动作对应的随机数,可以记录每次动作实际造成的结果。  
 
这种解释也是有着明显缺陷的。首先,数据量并没有明显减少;其次,也是最重要的,这种方法并不能真实重现当时的情况。举个例子吧:升了一级跳劈的 BM 砍小 g ,一次攻击造成了 50 点伤害,于是系统记录下 50 这个数值。但在播放 rep 时,面对 50 这个数值,系统会产生混乱,因为它无法确定到底是 BM 随机到了 50 点的攻击力,还是随机到了 25 点攻击 + 跳劈,虽然结果相同,但在显示效果上跳劈和不跳劈还是有着明显区别的。  
 
学过 basic 语言的可能都知道,调用随机函数 rand() 的时候,如果不指定随机种子的话,其产生的随机数列是不会改变的,也就是说不同的随机种子对应于不同的随机数列。  
 
这里引用 祝蜚 在回帖中的一段话有助于理解 :“ 计算机只能产生伪随机数, C 语言中的随机数函数 rand() ,一个种子,只会产生一个固定的随机数数列,打个比方来说明这个问题 : 设种子为 1 ,第一次调用 rand() 会得到 7 (这个 7 是我乱写的一个数字,并不是真的 rand 产生的,后同),第二次调用 rand() 会得到 9 ,然后得到 225 159 6724...................... 这样得到一个随机数列 7 9 225 159 6724....... 再第二次把种子设为 1 ,运行 rand() 还是会得到 7 9 225 159 6724....... 这一个数列。 (抱歉我不是学计算机的,发贴前对于伪随机数这个概念并不是很明白,所以在之前的回复贴中有一些武断的言论,在此收回,各位见谅。)  
 
这就好比等差数列,在通项公式已知的情况下,如果确定了首项,那么整个数列也就确定了,而且首项与整个数列之间是一一对应的。  
­  
依据这个原理,我认为是这样的,一次游戏开始前, war3 先随机产生一个随机种子(相当于首项),而依据事先制订好的数据生成规则(就好比通项公式),可以利用这个种子生成一个随机数序列,而且这个种子和随机数列之间是唯一对应的。当一个随机事件产生的时候,系统就按照先后顺序分配事前已产生好的随机数。 rep 也只须记录这个随机种子,当播放 rep 的时候,系统根据记录的随机种子重新产生出这个随机数列,由于时间顺序是确定的,所以一个随机事件对应的随机数也是确定的,这样就可以真实的重现当时的情况,而且也可以大大的缩小数据量。 ­  
 
关于这部分,可以参考 biaika 的帖子 :“ 质疑随机数系数一文 ” 
http://war3.replays.net/bbs//htm_data/102/0607/728790.html 
biaika
对于我的理论理解有误,我和各位回复者作了比较详尽而形象的解释。  
 
________________________________________________ 
 
最后,还想感谢一下之前对我这个帖子给予关注的各位 RNer ,人太多了恕我不能一一列举,你们的有见解的回复对我现在发这个帖有不小的帮助,所以还希望各位继续踊跃参与讨论。  
 
综合区的帖总有一天要沉的,欢迎访问 魔兽图书馆 区镜像:  
http://war3.replays.net/bbs/read.php?tid=867158
­  
 
版权所有,转载请注明出处  
shohit@Replays.Net


[ 此贴被 shohit 2006-10-17 23:46 重新编辑 ]
 
 
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值