為什麼有人說《暗黑破壞神 3》中的隨機是「偽隨機」?

什麼叫「偽隨機」?和 random() 這種函數有關係嗎?如果是偽隨機,那麼實現「真隨機」有哪些障礙?


很多遊戲愛好者應該已經知道了,目前的很多涉及到概率問題的遊戲中,遊戲系統所採用的隨機判定方法與實際是不相符的。

大菠蘿很久沒碰過,dota 相對比較了解,既然偽隨機的原理具有一定程度的一致性,這裡我們就先拿 dota 來舉例,和大家一起談笑風生。


(原貼:從非洲邁向歐洲——了解Dota2中的偽隨機機制 - 集智專欄)

幻影刺客的恩賜解脫

混沌騎士的混亂之箭

「明明可以逃的,怎麼就觸發最大傷害了呢」,大家一定遇到過這種玄學災難。用專業一點的話來講,其實是遊戲中一些隨機事件的概率分布與其原本應當遵循的概率分布(大部分情況下是幾何分布)完全不同——我們把這種概率分布叫做偽隨機分布(The Pseudo-random distribution,簡稱PRD)。不是你不歐,是偽隨機機制讓你顯得很非。

(緣分的事兒有時候沒辦法解釋)

雖然同樣含有「偽隨機」(Pseudo-random)這個名字,但是偽隨機分布這個概念與信息技術領域所用的「偽隨機數生成器」是有區別的——後者試圖使用某些技術手段給出符合需要的隨機數列,而前者只是在應用隨機事件的時候額外加入的一個演算法。但隨機這種東西,其實是件讓大部分人類都容易沉迷其中的妙事。你想想,哪一個半藏玩家不是被叮叮叮的爆頭聲吸引入坑的呢?

(理直氣壯的准心補償機制,島田家的事兒你上哪說理去)

「偽隨機分布」簡單來說,就是把人們在賭博遊戲中常有的「事不過三」這種心態變成了現實——也就是說,在這種概率分布下,如果一個事件多次未發生,則它下一次發生的概率會變大。DOTA2 Wiki 給出了一個專頁說明了這個系統的內容(同樣,DOTA2 Wiki 也對護甲計算方法、各類特性疊加等涉及到演算法的遊戲系統均給出了詳盡的說明),下面讓我們來簡單地學習一個。用數學語言來講,DOTA2 所使用的 PRD 遵循這樣一個函數:

P(N)=C×N

其中,P(N)表示僅當第N次嘗試時事件發生的概率(意味著前N-1次嘗試均未成功),C表示一個小於1的常數。

這個函數表達的意義就是,從某個時刻開始,如果某次事件未發生,則它在下一次嘗試中發生的概率會增加一個固定值;而當某次事件發生後,下一次嘗試中發生的概率又會降到最低值。

舉個例子,斧王的反擊螺旋在第一次攻擊時效果發生的概率是5.6%(C=0.05570),如果這次攻擊未發生,則它下一次發生的概率會變為11.2%,一直如此增加下去,需要注意的是,如果螺旋效果連續17次未發生,那末下一次發生的概率將會大於100%(事實上僅僅是計算數值大於1,概率的數值不可能大於1),也就是說螺旋一定會發生。

上述函數中的C值(也就是例子中的0.056)不是隨便取的,是根據需要符合的期望值來獲得的。我們可以使用程序計算一下此時發生螺旋的期望:

(知乎編輯器說他不茲瓷運行,請點擊這裡去往原文運行代碼)

根據遊戲里的數據,斧王反擊螺旋的概率是20%。而眾所周知,對於一個單次發生概率為20%的事件,其期望是5(幾何分布的期望是單次檢驗概率P的倒數),這與 PRD 的期望是一致的。也就是說,PRD 並未改變原有隨機過程的概率,而僅僅改變了該隨機過程的分布狀況。

大家很明顯地可以看出,對於 PRD 而言,C 值是非常關鍵的一個數據,而且很顯然的,這個 C 值與原有的單次事件發生概率 P 有一一對應的關係。通過傳統的方法來獲取 C 值並不容易,對於常用的一些概率 P,我們可以通過查表來獲得它們所對應的 C 值。

而利用計算機程序,我們便可以通過中值逼近方法來計算出任意一個 P 值所對應的 C,具體做法是將上面的程序包裝成一個函數,然後不斷拿猜測的 C 值去嘗試得到一個新值,如果新值非常接近於 P,則認為我們找到了所需的 C 值。

點擊這裡閱讀原文,去往主站運行代碼)

大家可以自己改變程序第一行的P的賦值,來看看得到的C值與上表中是否接近。

大家也許會問,為什麼要在視頻遊戲里使用PRD系統呢?我們不妨先繪製出PRD隨機分布與正常隨機分布(幾何分布)的圖像,來觀察二者有哪些差異:

(不用說了吧?)

從代碼運行的結果圖不難看出,藍柱表示正常隨機過程(幾何分布)的分布情況,而紅柱表示 PRD 的分布情況。從圖中可以看出,相對於幾何分布,PRD 的分布曲線更為均勻,而且分布狀況接近於正態分布,這種分布狀況正好反映了在視頻遊戲中採用 PRD 這一系統的兩個理由:

其一,防止某些小概率事件連續發生。在遊戲中,比如某些抽獎、暴擊、閃避等效果頻繁連續發生會一定程度上影響遊戲平衡性,而作為競技遊戲而言,某次小概率事件的集中發生很可能影響比賽形勢。歷史上的一次 DotA 比賽中,當時折射技能還是按固定概率全部反彈的幽鬼實現了一次殘血反殺三人的壯舉,靠得就是連續幾次的折射觸發。這一次戰鬥的獲勝很大程度上影響了比賽走勢——而這對於競技項目是不合理的,因為比賽結果不應當由運氣所決定(事實上,之後幽鬼的技能很快就被修改)。而 PRD 就能很好地減少這種情況出現的可能性。比如說,大魚人斯拉達連續打出兩次重擊的概率在一般概率分布下為6%左右,而在 PRD 下這一概率僅為0.6%;

其二,防止某些事件長時間不發生。某些事件的嘗試次數超過期望值很多倍仍不發生的這種現象在真實世界中很常見(比如說全球男女比例差不多,可是有些人就是沒有女朋友),但是在遊戲世界中不免讓人惱火。在 PRD 中,任何事件都能保證在有限次嘗試中發生,這對於遊戲是有積極意義的(這也是為什麼遊戲世界看上去,比現實更加幸福的原因之一)。

DOTA2 所採用的 PRD 這一系統是來源於 Warcraft III 的。事實上,在 DOTA2 的早期,開發人員摒棄了 War3 的諸多系統和演算法,但是玩家反映這樣的遊戲很難適應並會出現一些令人不快的問題,於是後來 DOTA2 的絕大部分遊戲系統均與 War3 DotA 一致——甚至包含一些War3固有的問題。比如 PRD 中某些大概率事件的實際期望值相較於一般概率分布的期望值是不同的(貌似是暴雪的程序猿算錯了),它們更低一點(比如先鋒盾實際的抵擋概率是66.7%而並不是標稱的80%)。

在 DOTA2 中,大部分的暴擊、擊暈和格擋都遵循 PRD,但是也有少部分例外——比如碎顱錘的重擊(擁有一個內置 CD 以防止連續觸發),以及舊版虛空假面的回到過去(這一神級閃避技能不僅可以閃避任何傷害,同時遵循幾何分布,也就是說連續幾次觸發技能從而完成死血逃生的可能性並不低)。對了,最靠人品的英雄——食人魔法師的技能並不遵守 PRD,也就是說連續多次打出4倍技能的可能性是很大的,當然,也有可能整場比賽沒有一次4倍暴擊。

(暴多暴少是個緣)

了解這一系統有什麼意義么?其實並沒有什麼特別的作用,只是我們據此可以了解到我們並不會不幸到一場遊戲打不出一次紅字,而有經驗的玩家則可以根據之前的攻擊情況判斷下一次攻擊是暴擊的可能性(這對於幻影刺客這種英雄很有意義)。

在視頻遊戲中偽隨機分布很常見,他們的分布狀況並不一樣,生成演算法也根據遊戲的需求有所區別。研究這些東西很有意義的——它不僅可以使我們知道虛擬世界是如何通過數學方法搭建起來的,同時也可以讓我們在遊戲世界中暢玩的時候更加理智一些。要知道某些氪金遊戲即使公布了遊戲概率,其概率分布也不一定就和大家想的一樣。玩的過程中你可以很清晰的感覺到——你正在被刁難。

謝謝閱讀。也歡迎大家來集智(http://jizhi.im)發現更多有趣內容。

官方微博:@景略集智

微信公眾號:景略集智

集智QQ群:557373801

商務合作:chenyang@jizhi.im

投稿轉載:kexiyang@jizhi.im


不只暗黑三,許多遊戲中的「隨機」要素都是「偽隨機」。而很諷刺的,採用「偽隨機」的理由往往是為了製造更「隨機」的感覺給玩家。

試想,如果一個珍貴道具,掉寶率只有千分之一,那麼玩家會期待我打一千個怪物應該要掉一個吧,再不然我打兩千個怪物應該也總該掉給我一個珍寶了吧?

上面是一般玩家的直覺。然而我們考慮真實情況:

  1. 連續掉兩件珍寶的機率是百萬分之一(0.001^2)。但如果這遊戲的玩家夠多(例如暗黑三第一天就賣了三百五十萬套),出現連拿兩件珍寶的玩家並非不可能,但是看在其他人的眼裡,可能就會覺得有作弊不公之嫌。
  2. 打了一千個怪物仍沒有掉任何一件珍寶的機率是多少?答案是 0.3677 (0.999^1000);而打兩千個怪物仍沒有珍寶的機率是 0.1352 (0.999^2000)。換個方式說,有三分之一的人打了一千個怪仍沒拿到珍寶,就算各打了兩千個怪,仍有超過十分之一的玩家是毫無所獲的。雖然這是真實存在的機率情況,但對玩家而言,卻會覺得是開發商作弊,而不會認為這是正常的隨機。

所以遊戲設計中,許多時候的隨機都不是真的亂數隨機,而是用各種方式做出看起來隨機的樣子。比較常用的一個方式就是洗牌 (Shuffle),把所有可能發生的情況放在一個陣列中,對陣列的內容作亂數排序。

以前面千分之一掉寶率的假設為例,可以設想有個陣列有 1~1000 的數字,亂數排序後,每次玩家打怪我就從數列中抽出一個數字,若數字等於 1 時我就給玩家珍寶,當 1000 個數字都取完後,就對這個陣列重新洗牌,重新抽牌。這樣的作法可以確保玩家平均每 1000 次打怪中可以得到一次珍寶,從而避免機率的極端狀況,對玩家而言,看起來比較像是直覺意義上的隨機,雖然事實並不是。


因為那的確是偽隨機,我記憶里到現在還沒有「真隨機」的演算法,當然還有人認為沒有真隨機的存在,不過那個太學術了:

有限狀態機不能產生真正的隨機數的,所以在現在的計算機中並沒有一個真正的隨機數生成演算法,現有的隨機數生成演算法生產的隨機數只不過因為重複的周期比較大,可以做到使產生的數字重複率很低,這樣看起來好象是真正的隨機數,一般稱作叫偽隨機數發生器。

真正的隨機數是使用物理現象產生的:比如擲錢幣、骰子、轉輪、使用電子元件的噪音、核裂變等等。這樣的隨機數發生器叫做物理性隨機數發生器,它們 的缺點是技術要求比較高。真隨機數生產效率沒有偽隨機數高,還有就是"信息熵的信息量如果很有限的話,就不是一定是真的隨機數了。"

來源:關於真隨機數生成器,http://cryolite.iteye.com/blog/199943很多語言的random函數演算法都有區別,我記得用的比較多的是線性同餘法還有平方取中法,其實就是在調用random的時候他就用事先寫好的演算法套公式算出數字。
擴展閱讀:
史上最快的隨機數生成器:從真空中的亞原子噪音獲取隨機數,http://article.yeeyan.org/view/219269/266017
從Linux內核中獲取真隨機數,http://www.cnblogs.com/bigship/archive/2010/04/04/1704228.html


真隨機現在不太能低成本做到,基本上計算機都是偽隨機,尤其民用。

唯一獲得真隨機字元串的方法是

讓用戶退出VI


首先,根據我的了解,計算機是不能產生所謂的「真。隨機數」的,基本都是利用時間種子產生偽隨機數
真正的隨機數得在物理微觀層面產生

其次,為了保證遊戲的公平性,這種偽隨機往往還經過周密的計算與安排
我沒有玩過暗黑三,但是,可以根據我對魔獸三的了解來說一下,畢竟都是暴雪出品

魔獸三中使用的隨機機制很有趣,前一次的事件是否發生會影響到下一次事件發生的概率
比方說暴擊,如果頭一次攻擊沒有觸發,那麼下一次攻擊中出現暴擊的概率就會提高

就拿劍聖的暴擊來說事
劍聖的暴擊概率寫出來是20%,但第一次攻擊不是20%,而是5.57%的概率,而下次的攻擊就會是11.14%,直到第17次攻擊就會是100.26%的保證性暴擊。暴擊之後回到之前的5.57%形成個平均20%機率的暴擊。這種設定是減少連續性暴擊,減少連續性沒暴擊的想法。這當然也可以拿來利用,如果你在玩幻影刺客的時候,打幾下小兵(最多31下)再去攻打英雄會增加你下一次攻擊的暴擊率,而4倍的加成不是開玩笑的。


引用:http://games.sina.com.cn/e/n/2012-01-17/2132574852.shtml


因為真隨機感覺並不真實,我第一次發覺這點是在《魔獸爭霸3》的3C地圖裡,很多版本的劍聖都有閃避這個技能,3級是60%的幾率閃避攻擊,基本來說就是無敵,10次攻擊能有2次擊中就算運氣好的了,10攻擊1次都打不中也經常發生。


BLZ自己都說了是智能掉落,已經不是真隨機了。
掉落有補償,有低保,臉黑黨,臉白黨,互助團這些概念和應對方式的出現,不從技術上去討論,從宏觀遊行性的角度去解釋,客觀上加強了玩家組隊收益,大大提高了氏族/社區的存在價值。
也許這才是BLZ希望看到的。


只有上帝才能扔色子呀少年。所有所謂程序模擬的隨機都是偽隨機


演算法我不管,我就想知道寒冰洞的豹女什麼時候掉那個鬼石頭!
一個圖刷了整整100級巔峰!


所有隨機演算法都是偽隨機。


先不說是不是有真假隨機數的問題,前提是一個遊戲對於物品掉率和隨機事件觸發是需要可控的,不可控的物品掉率和隨機事件會嚴重影響玩家的遊戲體驗,就算有真隨機數生成器,遊戲公司也不可能會使用真隨機數,因為這會導致不可控的情況發生。

舉個例子就是DOTA剛更新的版本修改了斧王的反擊螺旋/PA的恩賜解脫和閃避/JB臉的閃避的隨機數生成規則(changelog是說明了使用更好的偽隨機數生成器)來確保玩家玩的時候不會出現太過臉黑和人品過高的情況導致遊戲體驗變差。

其實對於遊戲來說,隨機數的使用是為了提升遊戲體驗的,就算有真隨機數生成的硬體和演算法,遊戲公司也不會很簡單地就使用它,因為實際上不可控的行為會嚴重影響玩家的遊戲體驗,所以偽隨機數這種更為可控的行為(例如你可以控制種子產生有一定規律的隨機數序列)也就更符合遊戲公司的需求了。(當然其實對於D3這種刷刷刷的遊戲來說,其實比起隨機數來說數學上的正態分布規律更適用)


補充下,D3的PRD不是簡單的洗牌,而是設定了以玩家某些行為為觸發點,生成新種子的洗牌,舊牌組與當前種子生成新牌組(所以叫偽隨機),然後玩家在新牌組裡面繼續抽取數,基本不可能有效預測打多少次怪就一定出什麼裝備,跟war3的PRD是完全不一樣的~


講道理,使用計算機硬體和程序生成的隨機數都是偽隨機數,區別只在於狀態空間大小而已。

曾經做過一個神經網路晶元,裡面需要做到盡量逼真的隨機數產生器,我最後是用線性移位寄存器實現的。

另外,對於產生的偽隨機數質量,有很多方法進行評價。比如熵等(這不是常用方法,我當時用的方法太久遠我也記不清了)。

補充一下,我記得有一個網站,通過分析空氣中分子的噪音擾動,生成隨機數。這可以說是真隨機數了。。。


鄙人還沒有聽說什麼計算機演算法能實現真隨機。


真隨機只產生於物理世界,特別是微觀物理世界。計算機演算法只能無限逼近和模擬一個隨機過程。我覺得某些遊戲世界中,掉寶率也不能簡單稱為「偽」隨機,而更像是一種改良的隨機演算法,能夠在大中小樣本中輸出盡量恆定的概率結果。當然,如何去定義它不是最重要的,重要的是,通過如此,我們學到一種平衡數值還有人心的方式。


先有的計算機硬體嚴格意義上只能產生偽隨機,更何況是一部遊戲。


只要是計算機計算出來的,就不是真隨機


一般來說,除了有專門硬體利用一些物理特性,比如說熱雜訊什麼的來產生隨機數,呢是真隨機。純軟體產生的是偽隨機,只要隨機種子不變輸出結果是一樣的。我覺得沒有真隨機估計是沒有必要,比如用時間日期做隨機數,撞車的概率挺小的。用高能射線照你的ram估計有不錯的隨機效果,不過工程師們會抓狂的,嘿嘿嘿


現在暗黑3暴率太高了 當然是爆的都是垃圾暗金裝備,畢業的幾個裝備掉率還是很低,暴雪就是讓你花時間刷,太累了 ,AFK了。當然賭博也是獲取需要裝備的方法


只有實際的物理過程能產生真隨機數。
實用中通常是採用一些數學演算法產生的偽隨機數,能通過一些檢驗,具有隨機數的性質。
遊戲中所謂的「偽隨機數」實際上採用了一些抽樣方法來提高抽樣效率。


推薦閱讀:

當正在閱讀的書籍、正在討論的內容或者正在解決的問題涉及到許多因素時,如何有效在大腦中組織這些因素?
Alienware 用來開發辦公,穩定可靠嗎?
27歲的男人學什麼技術比較有用?
我用個假簡歷去面試android的結果為什麼會這樣?
為什麼我的編程一直沒法入門?

TAG:編程 | 計算機 | 暗黑破壞神3DiabloⅢ | 隨機演算法 |