易竞技前言:“朝神”是被《炉石传说》玩家们所熟知的明星选手,作为清华大学数学系的博士,他对《炉石传说》有另一种解读:炉石就是一个随机看脸的运气游戏?其实未必,基于概率计算采取尽量有利于自己的行动才是致胜之本。
什么是伪随机?《炉石传说》的随机是怎样的随机?朝神在这篇文章中给出了自己的解读和猜测。值得一看!
以下是朝神的文章《数学系炉石专业毕业论文》:
玩炉石以来一直觉得自己水平还不是那么太烂,但也没写过啥攻略之类。以前爱打竞技场,每个月基本上了传说也不怎么打天梯,冲个排名却月月打个100多名没法在榜单上露脸好装逼。最近就爱瞎组一堆逗逼卡组 去天梯各种找虐,偶尔直播但总感觉对炉石也没啥贡献,没弄个中外炉石第一人(cai)的美名对不起自己,所以想想就写点东西吧,写完这个估计也不写别的了,总不能写自传吧,所以尽量写的好点,不留遗憾。
这文章主要是一个菜鸡对《炉石传说》这个游戏一些乱七八糟的想法,希望可以对大家理解游戏有所帮助。
![](http://n.sinaimg.cn/games/transform/20160131/aUnX-fxnzanm3877931.jpg)
概率与随机
《炉石传说》是一款运气游戏这好像是大家的共识。这游戏到底是不是运气游戏我们以后再探讨。所谓运气游戏就是说这游戏充满了各种随机性:起手摸牌,飞刀、25仔、奥术飞弹、门、砰砰博士的两个蛋蛋……各种随机性。
经常有人问我说炉石里啥啥概率怎么算,这类问题最经典的就是奥术飞弹打死精灵龙的概率,这个问题起源于炉石刚内测时法爷的强大,大家纷纷带精灵龙针对,当时贴吧漫山遍野的问这个问题,以及求削弱精灵龙。
(编者注:计算概率的方式有多种,朝神此次使用“对称性”解决问题)
我稍微回答一下这个问题好了,当然我们假设对面英雄血量超过3,对方场上只有精灵龙,己方场上没有法伤火妖之类的牌。最简单的求法是你假设精灵龙有3血或者更多,但是只要受2点伤害就会死,由于精灵龙吃到2发奥弹后无法再吃,这个假设是不影响求解的,于是奥弹打脸0或1精灵龙死,打精灵龙0或1则不死,由对称性这答案是二分之一,不需要1秒就能算出来。
对于经常得到的三分之一、七分之三之类。我只想说,用乘法原理这种答案在0.00001秒内就可以排除。
下面这段写给高中生、学概率论第一章的大学生,以及所有感兴趣的玩家,我尽量说的详细,保证人人都能看懂。
我们稍微复杂一下问题,万一场上有血法(没有用狗头代替)、蓝龙、火妖,或者什么丛林枭兽,加个恩泽,对面万一是欢笑姐妹姐夫,黑暗教徒圣殿加过血,或进行过随从交换。你丢的万一是机关枪或者10费的那张不知道啥玩意。总之就是对面场上有且只有一个n血的随从,你打了一发随机m点的伤害,对面英雄血量足够多(就是大于等于m,小于m的有兴趣自己算),打死那个随从概率是多少?当然m到大于等于n,不然就是0。
我们分析一下这个问题,一发随机伤害打出去,打脸打随从各是二分之一,如果随从死亡了 那只能以概率一打脸,因此不需要计算分母肯定是2的幂,然后我们考虑随从在第几发后刚好死亡,设为k,这个k大于等于n,也就是说k发之前各0.5打脸打怪,之后只能打脸,发生这事概率为2的k次幂分之一,然后这样的事件有多少呢?就是前面的k-1发有哪n-1发打怪了,所以是组合数(k-1 n-1)这个乘以2的k次幂分之一,再从n到m进行sigma求和就是答案。
如果我算错了欢迎大家指正,毕竟我数学不太好,关键不能误人子弟。
但是上面的答案是对的吗?其实严格上来说不对,哪里错了,关键在于奥弹打脸打怪是不是真的是二分之一。
所谓的随机只是数学上的第一定义而已,一般对于古典概率空间,认为这些事发生的概率相等。然而,到目前为止,现实中并没有纯随机的例子,你就算抛硬币也是由硬币的造型、你的力度、空气的阻力、抛下的高度等等决定的。随之而来的问题是,电脑也没法产生随机事件。
游戏中怎么决定你开的卡是金橙还是白卡、你起手摸的是肉酱还是伊瑟拉、奥术飞弹干的是脸还是怪呢?所谓伪随机数,就是一列0到1之间的数,伪随机数有很多的产生办法,我也只是略知一二,大家初中高中数学书后面会有的什么随机数表就是最简单的伪随机数。
伪随机数就是大家说的发牌员。
比如程序员可以写这随机数在0到0.5之间打脸,0.5到1之间打怪,或者是什么区间摸知识古树,什么区间摸咆哮等。
这样就有一个几乎可以忽略不计的问题,一般而言其实你摸树人和摸咆哮的概率是不一样的(这个例子可能不对,取决于摸牌的程序是如何实现的,至少奥弹打两个精灵龙就会有这个问题),因为计算机精度有限无法保存无限小数,所以对于因子不止2和5时就会出现不等可能的情景,但这个差距小到可以忽略。
最大的问题和最大的机遇在于:
伪随机数有很多产生办法,但是有个长度,这个长度之后就出现了循环,不过据说现在的数学已经可以做到这个伪随机数列足够长到一个人在有生之年几乎无法用完这个数列,但《炉石传说》用的是啥我就不知道了。
如果《炉石传说》用的是个固定的伪随机数列,那么当两个会玩的人对战时,发牌员决定好了所有的牌序(如果牌序是游戏开始之前就决定的话)。然后之后所有的随机事件都由伪随机数列确定,某种程度上可以说胜负几乎是决定好的,我们只是一步步去实现开始就设定好的事情,但是你可以改变随机事件发生的时间来影响胜负,同时随从的站位和出场的先后顺序将至关重要!如果奥弹或飞刀的目标是根据随从位置来标记时,站位将是关键,如果是根据随从出场顺序来标记的,先摇报告再下收割机还是先下收割机再摇报告又是关键,考虑到有个亡语结算的问题,我更相信是后者,所以不要随便怀疑别人的出牌顺序,说不定人家是看穿了发牌员!
关键就是《炉石传说》使用了怎样的随机数,比如我知道C语言里有个由当前时间决定种子的伪随机数时。假设有一个天大的机遇知道《炉石传说》随机数是怎么个顺序,以及伪随机数是怎么转化成伪随机事件的(比如暴雪的某程序员),那么他可以在恰好的时间开包,包包出金橙,可以奥弹想打脸打脸想打怪打怪,元气弹发发打20,这游戏真不知道怎么输,细思极恐。所以烧绳是有道理的,捏着连环爆裂祷告也是有道理的,因为这样可以改变伪随机数种子而致胜。
说了这么多其实都是废话,我们都不知道炉石的源代码,在我们不知道的这个条件下就是原来的古典概率空间,问题还是这么简单,上面算的概率都没有任何问题。
既然如此,像文章开头快速计算至少是估算简单的概率是非常重要的,因为在这种充满随机性的游戏里,你必须选择使自己获胜概率最大的方式进行游戏,例如大家几乎每局都可能面对的如何处理砰砰博士的两个蛋蛋,这也就是暴雪爸爸经常说的虽然随机但是却可以体现技术的所在,然而我觉得这句话非常片面。
概率和随机就写到这吧,剩下的以后再写。