?很久以前流傳著這樣壹則笑話:壹個身患重病的人決定去動手術。在手術之前,他問醫生:“這起手術的成功率是多少?”醫生回答他:“只有1%。”他很驚慌,但是醫生說:“沒事的,在妳之前我已經治死過99個人了。”
這是壹則嘲笑那些不懂“概率”的人的笑話,卻講出了“真隨機”和“偽隨機”之間的區別。
在四月末的時候,我曾寫過壹篇 《妳打 遊戲 靠的是技術,還是運氣?》 ,其中就提及了“偽隨機”這個概念。當時受限於篇幅,沒有詳細展開解釋“偽隨機”的概念。前不久,在因國際邀請賽而備受關註的Dota2在最近壹次的更新中,有這麽壹條更新內容: “落空的負面效果和下坡攻擊的落空效果現在都采用偽隨機觸發” 。
那麽到底什麽是 “偽隨機” 呢?以及和“偽隨機”對應的 “真隨機” 又是什麽概念?
贗隨機數算法(Pseudo-Random Number Generator,簡稱PRNG) 是計算機的壹個術語——當然,它也可以被叫做“偽隨機數算法”,只是為了方便與 遊戲 中的“偽隨機數”進行區分,本文中統壹稱作“贗隨機數算法”。
眾所周知,計算機程序是由無數“0”和“1”兩種狀態構成的,如果壹個狀態不是“0”,那就必定是“1”,頗有種非黑即白的味道。
因此,在計算機程序中,不存在“不確定”的數字,只有確定的“1”和“0”。基於這種特性,計算機無法生成“真正的(不確定的)隨機數”。
那麽在計算機中,需要生成或是使用到隨機數的時候怎麽辦呢? 通常是利用計算機抓取壹些數值,然後將這些數值輸入至壹個復雜算法 (常用的算法是同余法和梅森旋轉算法,有興趣的讀者可以自行查詢,這裏就不展開講了) 當中,通過壹系列運算得出壹個數字,這就是平常說的贗隨機數了。
只要最初輸入的數值(初值)不變,那麽輸出的值都會是同壹個值,這就證明了這個數並不隨機,只是看起來隨機而已。
換句話說,只要這個隨機數是由確定算法生成的,那就是贗隨機數。
所以下壹次在和朋友聊天時提到真隨機數、偽隨機數時,如果有人插嘴:“計算機只能生成偽隨機數,所以根本沒有什麽真隨機”,那妳就可以霸氣側漏地說他是 “雲玩家” 了。
我們通常說的 真隨機 又名 “純隨機”(True Random Distribution) ,就是我們平常壹直說的那種、壹般意義上的“隨機”。
在真隨機中, 每壹個事件都是相互獨立、服從真隨機分布的,不受其他事件的發生而改變 。比方說某款 遊戲 為了吸引用戶,擁有這麽壹個隨機抽卡系統:每次抽卡時,都有1%的幾率抽出SSR卡片,這個概率服從真隨機分布。
回到我們最開始說的那個“治死99個”的笑話:我們壹眼就能看出這個笑話的不合理性。但在抽卡 遊戲 中,我們的大腦瞬間失去理智。有相當壹部分玩家認為: 我連抽100次,總能抽到這張卡吧!
實際上,連抽100次卻抽不出1%的SSR卡的幾率是為(1-0.01)^100=36.6%,甚至還稍稍超過了1/3。將連抽數字上升至300,也仍有4.9%的幾率。
換句話說,假設有10000個玩家連抽100次,就有約3660個玩家抽不出這張SSR;10000個玩家連抽300次,也仍有約490個玩家抽不出這張SSR ——這對玩家的 遊戲 體驗來說可以說是毀滅性的打擊。
盡管純隨機在數學上是無罪的,在代碼中更是明明白白、清清楚楚,但玩家抽不出卡可不會回想到初高中的數學課本, 而是首先懷疑幾率是否被策劃運營篡改、這背後又是否有骯臟的PY交易……
當然不僅僅是在抽卡系統當中如此。在壹些競技性比較強的 遊戲 中(比如War3、Dota2之中——英雄聯盟幾乎完全摘除了隨機系統,不在此列),連續數次的“走運”極大影響 遊戲 的競技性和觀賞性。
比方說Dota中最著名的概率英雄虛空假面的技能“回到過去”: 使虛空假面有25%幾率完全躲避壹次傷害。 受限於War3引擎,這個技能采用的是真隨機概率,在某個極端情況下(通常見於精彩集錦中),虛空假面能夠保持很低的血量承受多次傷害卻不死、最終反殺對手。這種帶給敵方極差 遊戲 體驗的系統,因此也進入了計師們“整治範圍”之中。
為了避免極差的 遊戲 體驗帶來的玩家數量流失,設計者們提出了“偽隨機”的概念: 在不確定性的隨機事件當中,通過壹系列算法使隨機事件均勻分布在多次事件當中,盡可能減少或消除極端情況的發生,以提高玩家的 遊戲 體驗。
在設計師們的努力下,“偽隨機”應運而生,這裏的偽隨機就和上文的贗隨機數算法(PRNG)意義不同了。
制造“偽隨機”的方法有很多,在War3、Dota2這類 遊戲 當中普遍使用的是 “偽隨機分布”(Pseudo Random Distribution,簡稱PRD) 處理概率。
就拿Dota2中最強大的暴擊技能“恩賜解脫”來舉例: 幻影刺客有15%的幾率造成200%/325%/450%致命壹擊傷害 。在PRD機制下,幻影刺客的攻擊實際上 並不是 每壹刀都有15%的暴擊率。
根據PRD機制的公式P(N)=N*C可得出15%幾率的C值為3.22%,即幻影刺客的第壹次攻擊暴擊概率為3.22%;如果第壹刀沒有暴擊,則第二刀的暴擊率提升至2倍,即6.44%;如果仍舊沒有暴擊,則提升至3倍的9.66%,以此類推。
如果繼續推算,可得在第32刀時暴擊幾率會達到100%,最可能觸發暴擊的次數是第6刀,平均觸發刀數是6.67刀等等……
同樣,在連續觸發暴擊時,下壹刀的暴擊幾率會減少。RPD機制使競技 遊戲 中連續觸發或不觸發技能的幾率降低,避免了運氣成分過度幹擾戰鬥結果,大幅提升了玩家的 遊戲 體驗,但不影響這些隨機事件的正反饋:TI6決賽的“打我五下暈三下”,可是令全球人民集體沸騰了呢!
除了偽隨機分布RPD之外,還有兩種常見的偽隨機: 洗牌算法 和 組合隨機 。
洗牌算法 最常見的用法,是在各大音樂播放器中的“隨機播放”之中。在隨機播放時,如果采用真隨機,會導致壹首歌無論如何都播放不出,或是同壹首歌連續播放數次(有興趣的讀者可以計算壹下這些概率)。為了解決這個問題,播放器采用的解決方案即是洗牌算法:將壹個包含所有歌曲的數組像洗牌壹樣打亂,然後依次播放這個亂序數組。
至於 組合隨機 ,這是壹種廣泛應用於各個 遊戲 的做法:在抽獎的時候進行兩次、或是更多次的判斷,壹次不隨機,而剩下的判斷則是真隨機。比如說,妳會在第X次抽卡時抽到SSR是確定的,但抽中的SSR具體是哪張卡,則是隨機的——這就是廣大手遊中的“低保”系統了。
在壹堆數據之中想要分清“真隨機”和“偽隨機”似乎並不是那麽容易。那麽接下來為大家介紹兩個例子,有助於更好理解什麽是“真隨機”和“偽隨機”:
真隨機 :有壹天,小明在的班級上舉辦了壹次抽獎活動。這個班級有40個學生,所以為了公平起見,保證每個學生都有1/40的幾率中獎,老師準備了40個相同的紙盒,每個紙盒中都有40張紙條,有1張紙條是中獎紙條。這樣壹來,每個學生都有1/40的幾率中獎,但每個學生是否中獎並不受其他學生的影響。在極端情況下,這個班上可能40個學生都能中獎。這就是真隨機。
偽隨機 :小明班上舉辦了抽獎活動。為了公平起見,老師準備了1個紙盒,紙盒中有40張紙條,只有1張紙條是中獎紙條。這樣壹來,每個學生都有1/40的幾率中獎——但是顯而易見,這個班上有且僅有壹名學生能夠中獎。壹名學生在中獎後,余下的所有學生中獎幾率都會減少至0。這就是偽隨機。