1. 程式人生 > >【學習拓展】C語言 隨機數應用:偽隨機機制

【學習拓展】C語言 隨機數應用:偽隨機機制

一、總論

1.偽隨機機制的意義

1.1 什麼是偽隨機機制

日常生活中大家都喜歡玩單機或者網路遊戲,而在這些遊戲中常常會存在隨機,比如暴擊率20%或者被動擊暈15%等等,而在這些隨機事件中,我們往往被告知這些隨機事件也能分成兩類:一類是固定的概率,常被稱為“真隨機”,另一類是根據遊戲行為有變化的概率,則叫做“偽隨機”。我們都知道計算機只能產生偽隨機數,那麼這裡的“真隨機”和“偽隨機”也不是我們通常對於計算機生成隨機數的隨機性質的定義,而是關於這個可見概率的具體實施方法。

1.2 為什麼要使用偽隨機機制

所謂的“真隨機”在足夠大的樣本下,其中某一段的連續樣本會距離整體期望產生較大的偏差,簡單地說,就是“臉黑,怎麼一直不暴擊”或者“怎麼臉那麼好,一直在爆擊”。而“偽隨機”則在具體的遊戲程序中對概率進行了及時的修正,以圖實現足夠穩定的樣本子序列。舉個簡單的例子的話,就是當你打不出爆擊時會增加下一次的概率,而你連續打出爆擊時則會降低概率,雖然這對於某些運氣好的玩家來說可能是一個噩耗,但是總體上來說,這挽救了某些運氣實在太糟糕的朋友。

2. 一個合理的偽隨機機制的資料

2.1 以一個被動擊暈技能為模版

假設這個技能來自某款知名ARPG遊戲,並且這個技能在某個前版本里被修正成了偽隨機機制
被動擊暈:概率25%
顯然這個資料的大小是和我們玩的各類遊戲中的被動都十分接近的,所以這個樣本有其代表性

2.2 偽隨機機制的實現資料

首先需要感謝前輩們為我們分析出了WAR3這款經典的RTS遊戲內的偽隨機實現過程,我們可直接套用這個關係來實現我們的偽隨機機制。
對照圖
P是遊戲中顯示的概率,c是實際操作概率,maxN是第N次連續不觸發後必定觸發的臨界,Pcount為大樣本測試下的實際概率
而具體實現流程則是
1.第一次攻擊,概率為C,如果暴擊返回1,未爆擊進入2
2.第二次攻擊,概率為2C,如果暴擊返回1,未爆擊進入3
……
N.第N次攻擊,必定爆擊,返回1
那麼我們的程式碼也會依照著這樣一個明確的流程來實現。

二、實現

//偽隨機實現過程
#include<iostream>
#include<cstdlib>
#include<cstring>
using namespace std;
#define P 200   //P和C均擴大若干倍以方便計算
#define C 84.75 //
#define maxN 11 //參照表格
#define Num 100 //實際測試組數
int main()
{
    bool a[1001];
    double cUsing=C;
    int p,count=0;
    int i,j;
    srand(time(NULL));//設定種子
for(i=1;i<=Num;i++){ memset(a,false,sizeof(a));//初始化判斷生效陣列 for(j=0;j<=(int)cUsing;j++){//根據當前的第N步C值將前C個值賦值為真 a[j]=true; } p=(int)1000*rand()/RAND_MAX;//生成隨機數0~1000 if(a[p]){//根據陣列的值判斷是否生效 cout<<cUsing<<" Y"<<endl; count++; cUsing=C; } else{ cout<<"N"<<endl; cUsing+=C; } } cout<<1.0*count/Num<<endl;//輸出實際概率 return 0; }

通過調整Num我們來測試多組資料
Num#######實際樣本概率(理論值0.25)###誤差[(理論-實際)/理論]
100 ####### 0.235 ################### -0.06
100 ####### 0.247 ################### -0.012
1000 ###### 0.255 #################### 0.02
1000 ###### 0.251 #################### 0.004
10000 ##### 0.2516 ################### 0.0064
10000 ##### 0.2518 ################### 0.0072
100000 #### 0.24989 ################## 0.00044
100000 #### 0.25048 ################## 0.00192

可以料想到隨著樣本的足夠大,我們的確可以實現較為穩定的輸出結果:25%的暴擊概率

三、總結

隨著網路遊戲的不斷髮展,概率觸發這個增進遊戲不確定度的機制在遊戲中愈發多的被使用,如爐石傳說中的食人魔一族、DOTA2中各類擊暈和爆擊,甚至是整個RPG遊戲族內的裝備爆率,都要利用到概率這一利器,而其中有一些是固定概率的“真隨機”,而另一部分則是不定概率“偽隨機”,這些各有特色的機制讓我們的遊戲過程更為隨機,讓我們的遊戲結果更為的出乎意料,也讓我們獲得了更多快樂。
而這個應用則讓我們實際操作了一次偽隨機機制的執行過程,讓我們對遊戲背後的執行原理加深了理解,希望能夠幫助到未來有志於從事遊戲開發的朋友。
如發現有程式碼上的錯誤或者有所疑問,請在博文後留言。