#数学系炉石专业毕业论文# 第一章 概率与随机

作为一款处处体现着随机性的游戏,关于《炉石传说》中概率与随机的讨论从未停止过,曾经在赛中大放异彩的清华大学数学系博士“朝神”@张昭君该昵称已经被占用 日前为我们带来了关于如何从数学角度看待《炉石传说》的文章,一起来看看吧!




第一章 概率与随机

炉石是一款运气游戏,这好像是大家的共识,这游戏到底是不是运气游戏我们以后再探讨,所谓运气游戏就是说这游戏充满了各种随机性,起手、摸牌、飞刀、25仔、奥弹、传送门、砰砰博士的两个炸弹……各种随机性。

经常有人问我说炉石里啥啥概率怎么算,这类问题最经典的就是奥弹打死精灵龙的概率。这个问题起源于炉石刚内测时法爷的强大,大家纷纷带精灵龙针对,当时贴吧漫山遍野的问这个问题,以及求削弱精灵龙。


OK ,我稍微回答一下这个问题好了。我们假设对面英雄血量超过3 ,对方场上只有精灵龙,己方场上没有法伤火妖之类的牌,最简单的求法是你假设精灵龙有3血或者更多,但是只要受2点伤害就会死,由于精灵龙吃到2发奥弹后无法再吃,这个假设是不影响求解的。于是奥弹打脸0或1精灵龙死,打精灵龙0或1则不死,由对称性,这答案是二分之一 ,不需要1秒就能算出来。


对于经常得到的三分之一、七分之三 ,我只想说,用乘法原理这种答案在0.00001秒内就可以排除。

下面这段写给高中生、学概率论第一章的大学生、以及所有感兴趣的玩家,我尽量说得详细,保证人人都能看懂。


我们稍微复杂一下问题,万一场上有血法(没有用狗头代替)、蓝龙 、火妖、丛林枭兽、加个恩泽、易建联buff过的;对面万一是欢笑姐妹、姐夫、黑暗教徒圣殿加过血或进行过随从交换;你丢的万一是机关枪或者10费的那张不知道啥玩意……OK 总之就是对面场上有且只有一个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,这游戏真不知道怎么输。所以烧绳是有道理的,捏着连环爆裂祷告也是有道理的,因为这样可以改变伪随机数种子而致胜。


说了这么多其实都是废话,我们都不知道炉石的源代码,在我们不知道的这个条件下就是原来的古典概率空间,问题还是这么简单。上面算的概率都没有任何问题。


既然如此,像文章开头快速计算,至少是估算简单的概率是非常重要的。因为在这种充满随机性的游戏里,你必须选择使自己获胜概率最大的方式进行游戏。例如大家几乎每局都可能面对的如何处理砰砰博士的两个炸弹,这也就是暴雪爸爸经常说的,“虽然随机但是却可以体现技术的所在”然而我觉得这句话非常片面。


前头写的概率与随机很多人说看不懂,看不懂也是正常的,其实只是想给大家普及一下伪随机数的知识,大概有下面这些性质:


  1. 电脑程序里涉及随机性的东西都是通过伪随机数实现的,游戏也不例外;

  2. 伪随机数可以很长但终归是个有限的数列,超过一定的长度会出现循环;

  3. 好的伪随机数在一些随机性检验中表现良好,所以看上去就像是随机的;

  4. 产生伪随机数的方法很多,我也只知道一些不是太复杂的构造方法;

  5. 我好像也扯不下去了;

  6. 可以证明,在我们对伪随机性一无所知的条件下,可以用理想的概率空间来认识问题,对于炉石来说,就是古典概率空间;

  7. 我的确扯不下去了。


因此,在炉石这个游戏里,你可以通过计算概率来提高你获胜的概率,希望上面的那些犊子能帮助大家理解我上一篇写的东西。