1程序里面的隨機(jī)數(shù)
1.1 偽隨機(jī)
首先,程序的一大特征就是销钝,在輸入和代碼邏輯不變的情況下有咨,輸出也不會(huì)發(fā)生變化。所以任何依賴于特定算法加上種子生成的隨機(jī)數(shù)蒸健,都是可預(yù)測(cè)和可復(fù)現(xiàn)的座享。這些隨機(jī)數(shù)只是在分布上接近隨機(jī)婉商,但實(shí)際上在哪個(gè)位置出現(xiàn)哪個(gè)數(shù)在程序運(yùn)行起來(lái)的一刻就確定了。
比如以下代碼編譯后重復(fù)運(yùn)行總是會(huì)產(chǎn)生相同的結(jié)果(不同的實(shí)現(xiàn)隨機(jī)值會(huì)不一樣渣叛,但重復(fù)運(yùn)行的結(jié)果一定是一樣的):
1215069295
1311962008
1086128678
#include <iostream>
#include <cstdlib>
int main() {
using namespace std;
srand(0);
cout << rand() << endl;
cout << rand() << endl;
cout << rand() << endl;
}
為了避免總是產(chǎn)生相同的結(jié)果丈秩,一般做法是把時(shí)間戳作為種子值:
//把上面的srand(0)替換成下面這樣
srand(time(nullptr));
但這種解決不了根本問(wèn)題,因?yàn)槠鋵?shí)是可以通過(guò)大量的實(shí)驗(yàn)來(lái)推測(cè)出種子淳衙,進(jìn)而控制隨機(jī)性的蘑秽。比如就有人破解了minecraft的隨機(jī)附魔,來(lái)實(shí)現(xiàn)定向附魔
1.2 真隨機(jī)
真隨機(jī)就是指無(wú)法人為控制和預(yù)測(cè)的隨機(jī)值箫攀。所以隨機(jī)的來(lái)源一般是大自然肠牲,比如 https://www.random.org/ 提供的隨機(jī)數(shù)就來(lái)自于大氣噪音。 https://qrng.anu.edu.au/ 這里提供的隨機(jī)數(shù)來(lái)自于量子波動(dòng)匠童。
如果一個(gè)抽獎(jiǎng)(比如彩票)要證明沒(méi)有幕后黑手埂材,那就只能使用真隨機(jī)數(shù)塑顺。
1.3 改進(jìn)的偽隨機(jī)
一般操作系統(tǒng)也會(huì)提供生成隨機(jī)數(shù)的功能汤求,比如linux提供了通過(guò)搜集硬件數(shù)據(jù)(鼠標(biāo)/鍵盤事件、溫度傳感器等)來(lái)生成隨機(jī)數(shù)的方式(/dev/random) https://wiki.archlinux.org/index.php/Random_number_generation
由于這些硬件設(shè)備較多严拒,并且一般無(wú)法預(yù)測(cè)扬绪,所以安全性相對(duì)較高。
在運(yùn)行一些對(duì)隨機(jī)性要求較高的程序時(shí)(比如openssl genrsa)裤唠,有時(shí)候會(huì)看到一些讓你動(dòng)動(dòng)鼠標(biāo)挤牛、亂敲一下鍵盤的提示,目的就是為了提高隨機(jī)性种蘸。
2 游戲里的隨機(jī)
游戲里有很多地方設(shè)計(jì)到隨機(jī)墓赴,比如
- 觸發(fā)某個(gè)技能可能有特定的概率(dota之類)
- 游戲里可能會(huì)定期產(chǎn)生一些隨機(jī)事件
- 抽卡有一定概率獲得高級(jí)別的英雄、皮膚(爐石之類)
- 官方搞得一些充值活動(dòng)航瞭,抽獎(jiǎng)概率獲得xxx
這些隨機(jī)大部分都是看起來(lái)隨機(jī)诫硕,實(shí)際上都是經(jīng)過(guò)精心策劃的,在隨機(jī)性上做了手腳刊侯,抽獎(jiǎng)概率并沒(méi)有發(fā)生變化章办,但已經(jīng)不再是完全隨機(jī)。
從而讓一些看起來(lái)很玄學(xué)的抽獎(jiǎng)技巧其實(shí)是有科學(xué)依據(jù)的滨彻,比如 http://www.eeyy.com/shouyou/yys/2017012057318.html 這里邊提到的:
- 凌晨抽卡
- 不要連續(xù)抽卡
- 跟抽
甚至還能夠在游戲時(shí)利用這些技巧藕届,提高技能觸發(fā)概率。
2.1 獨(dú)立隨機(jī)
獨(dú)立隨機(jī)就是利用上面說(shuō)的偽隨機(jī)亭饵,每次都是用偽隨機(jī)來(lái)判斷執(zhí)行什么樣的動(dòng)作休偶。
魔獸爭(zhēng)霸的錄像文件就利用了這個(gè)機(jī)制:
《魔獸爭(zhēng)霸》的錄像,為什么長(zhǎng)達(dá)半小時(shí)的錄像大小只有幾百 KB辜羊?
錄像文件有三個(gè)主要內(nèi)容:
隨機(jī)種子數(shù)
基本信息(玩家踏兜、地圖)
操作序列
在我們玩war3的時(shí)候懂算,地圖初始化會(huì)產(chǎn)生一個(gè)隨機(jī)種子,這個(gè)種子的作用是用來(lái)計(jì)算游戲中的隨機(jī)數(shù)(例如AI行動(dòng)庇麦,單位攻擊造成的傷害)计技。
接著,我們每一次的點(diǎn)擊山橄、按鍵操作都會(huì)被序列化記錄下來(lái)垮媒。這里記錄有分成三種:
時(shí)間X,玩家X對(duì)單位X執(zhí)行命令(無(wú)目標(biāo)航棱,無(wú)點(diǎn))
時(shí)間X睡雇,玩家X對(duì)單位X對(duì)單位Y執(zhí)行命令
時(shí)間X,玩家X對(duì)單位X對(duì)點(diǎn)X執(zhí)行命令
作者:知乎用戶
鏈接:https://www.zhihu.com/question/25431134/answer/30861068
從用戶角度來(lái)看饮醇,其實(shí)這種隨機(jī)就是他們眼中的真隨機(jī)它抱,沒(méi)有任何暗箱操作。
但是這種形式有一個(gè)嚴(yán)重的問(wèn)題朴艰,就是部分運(yùn)氣比較差的玩家观蓄,體驗(yàn)感會(huì)非常差。
假如某個(gè)抽獎(jiǎng)活動(dòng)的中獎(jiǎng)概率為50%祠墅,理論上連接5次不觸發(fā)的概率只有1/32=0.03125侮穿,是一個(gè)非常小的值。但是如果有100w人參加了這個(gè)活動(dòng)毁嗦,連抽5次啥也沒(méi)有的人會(huì)非常多(100*0.03=3w)亲茅,他們會(huì)覺(jué)得這個(gè)抽獎(jiǎng)是在騙他們,就會(huì)產(chǎn)生這個(gè)局面:
- 運(yùn)氣較差的這3w人瘋狂發(fā)帖吐槽
- 運(yùn)氣一般的人會(huì)給吐槽的人點(diǎn)贊
- 運(yùn)氣較好的人幸災(zāi)樂(lè)禍狗准,什么也不說(shuō)
- 本來(lái)要抽獎(jiǎng)的人看到這些吐槽克锣,不去抽獎(jiǎng)了
假如某個(gè)暴擊技能的觸發(fā)概率是50%,2個(gè)有同樣技能的玩家互A3次腔长,其中一個(gè)玩家連接暴擊3次袭祟,另一個(gè)玩家一個(gè)暴擊也沒(méi)有的概率是1/64=0.015,平均沒(méi)100次就有1.5次會(huì)出現(xiàn)饼酿。這回影響競(jìng)技類游戲(dota)的公平性榕酒。
所以就誕生了保底機(jī)制,保底機(jī)制就是如果用戶n次沒(méi)有觸發(fā)故俐,下一次必定觸發(fā)想鹰。但粗暴的加一個(gè)保底會(huì)導(dǎo)致概率發(fā)生變化,因此就有了PRD機(jī)制药版。
2.2 PRD機(jī)制
PRD是一種隨著為中獎(jiǎng)次數(shù)的增加辑舷,中獎(jiǎng)概率會(huì)不斷上漲的機(jī)制。
比如第1次中獎(jiǎng)概率為25%槽片,如果沒(méi)有中獎(jiǎng)何缓,第二次中獎(jiǎng)概率變成50%肢础,如果還沒(méi)有中獎(jiǎng),第3次概率變成75%碌廓,如果這一次也沒(méi)中传轰,第4次概率變成100%,也就是必中谷婆。一旦用戶中獎(jiǎng)慨蛙,概率恢復(fù)到25%。
如果某個(gè)技能的概率是50%纪挎,那么在dota里第1次觸發(fā)的概率其實(shí)不是50%期贫,而是30%,第2次是30%2异袄,第3次是30%3通砍,第4次是30%*4>1,所以第4次必中烤蜕。
這樣用戶在第n次觸發(fā)的概率分別是:
第1次: 0.3
第2次:(1-0.3)*0.6 = 0.42
第3次:(1-0.3)(1-0.6)0.9 = 0.25
第4次:1-0.3-0.42-0.25 = 0.03
平均中獎(jiǎng)次數(shù):0.31+0.422+0.253+0.034 = 2.01封孙, 中獎(jiǎng)概率 1/2.01 = 50%
所以可以看到通過(guò)使用PRD,整體的中獎(jiǎng)概率仍然是50%玖绿,但是保證了用戶連續(xù)4次敛瓷,至少會(huì)有一次會(huì)中,避免了極端情況出現(xiàn)斑匪。
dota(英雄聯(lián)盟)里使用的就是這種機(jī)制: https://liquipedia.net/dota2/Pseudo_Random_Distribution
王者榮耀不確定: https://bbs.nga.cn/read.php?tid=18479920
在游戲時(shí)其實(shí)可以利用PRD機(jī)制:
1、先打小兵锋勺,如果發(fā)現(xiàn)2次沒(méi)有觸發(fā)暴擊蚀瘸,停手
2、去打?qū)Ψ接⑿凼鳎@是暴擊的概率已經(jīng)不是技能表里的50%了贮勃,而是90%,幾乎必中
一些游戲里強(qiáng)化/合成裝備苏章、抽卡也會(huì)使用這種機(jī)制寂嘉,這樣就可以:先強(qiáng)化/合成垃圾裝備,如果2次失敗枫绅,停手
換成想要強(qiáng)化/合成的裝備泉孩,幾乎必定成功
現(xiàn)在有政策要求所有的游戲內(nèi)抽獎(jiǎng)都必須公布概率,拿到概率后舊可以對(duì)照上表來(lái)搞了并淋。
2.3 老虎機(jī)
b站有一個(gè)視頻:
【游戲燈塔】UP主用氪金500萬(wàn)的經(jīng)驗(yàn)來(lái)告訴大家游戲抽獎(jiǎng)背后的秘密與邏輯寓搬! https://www.bilibili.com/video/BV1HJ411q7Ye?from=search&seid=15473182918558298670 (10:40開(kāi)始)
里面提到街廳里面的老虎機(jī)其實(shí)概率是可以調(diào)整的,并且是先吞掉一定的錢县耽,才會(huì)吐出來(lái)其中一部分句喷,保證老板永遠(yuǎn)不虧镣典。所以有經(jīng)驗(yàn)的人發(fā)現(xiàn)某臺(tái)機(jī)器中獎(jiǎng)后就會(huì)換臺(tái)機(jī)器。
一些游戲抽獎(jiǎng)也是同樣的套路唾琼,比如每抽100次就吐出一個(gè)1個(gè)獎(jiǎng)品兄春,第100、200锡溯、300個(gè)抽獎(jiǎng)的用戶鎖定中獎(jiǎng)(第1-99個(gè)用戶神郊,跟上面的小兵和垃圾裝備,有個(gè)專業(yè)代稱:墊子)趾唱,其他都不中獎(jiǎng)涌乳。由于用戶不知道自己是第幾個(gè),所以每個(gè)用戶中獎(jiǎng)的概率是一樣的甜癞。
但這種其實(shí)是存在漏洞的夕晓。
一般某個(gè)用戶中獎(jiǎng)后會(huì)全服廣播,可以通過(guò)觀察2次中獎(jiǎng)的平均間隔悠咱,在間隔接近時(shí)參與抽獎(jiǎng)蒸辆,這時(shí)中獎(jiǎng)的概率就會(huì)大幅提升,成為墊子的概率就大大減小析既。
2.4 定時(shí)放號(hào)
假如游戲廠商決定要通過(guò)活動(dòng)在某1天放100件高級(jí)裝備躬贡, 一件不多放,一件不少放眼坏。
由于活動(dòng)參與人數(shù)是未知的拂玻,所以事先無(wú)法確定概率,概率調(diào)大了宰译,幾分鐘就抽光了檐蚜,概率調(diào)小了,獎(jiǎng)品抽不完沿侈。
一般會(huì)把100件裝備分到24小時(shí)內(nèi)闯第,每小時(shí)在某個(gè)固定的時(shí)間(一般是整點(diǎn))以較高的概率放幾件。搶完后這個(gè)時(shí)段內(nèi)其他人的中獎(jiǎng)概率就成了0缀拭。
所以凌晨抽獎(jiǎng)咳短、整點(diǎn)抽獎(jiǎng)也是很科學(xué)的。