如何實現概率性事件

2021-06-21 11:41:02 字數 2206 閱讀 3044

遊戲中經常會遇到概率性的問題,比如裝備公升級的成功率,合成寶石的成功率,洗裝備時出現隨機屬性條數的概率等,這些概率性事件具體是怎麼實現的呢?在網上看了一些相關的文章,總結一下。

首先需要了解兩個函式rand()和srand(),下面是百科裡面的解釋:

函式rand()是真正的隨機數生成器,而srand()會設定供rand()使用的隨機數種子。如果你在第一次呼叫rand()之前沒有呼叫srand(),那麼系統會為你自動呼叫srand()。而使用同種子相同的數呼叫 srand()會導致相同的隨機數序列被生成。

srand((unsigned)time(null))則使用系統定時/計數器的值做為

隨機種子

。每個種子對應一組根據演算法預先生成的隨機數,所以,在相同的平台環境下,不同時間產生的隨機數會是不同的,相應的,若將srand(unsigned)time(null)改為srand(tp)(tp為任一常量),則無論何時執行、執行多少次得到的「隨機數」都會是一組固定的序列,因此srand生成的隨機數是偽隨機數。

庫函式中系統提供了兩個函式用於產生隨機數:srand()和rand()。 原型為:

函式一:int rand(void);

返回乙個[0,

rand_max

]間的隨機整數。

函式二:void srand(unsigned seed);

引數seed是rand()的種子,用來初始化rand()的起始值。

但是,要注意的是所謂的「

偽隨機數

」指的並不是假的隨機數。其實絕對的隨機數只是一種理想狀態的隨機數,計算機只能生成相對的隨機數即

偽隨機數

。計算機生 成的

偽隨機數

既是隨機的又是有規律的 —— 一部份遵守一定的規律,一部份則不遵守任何規律。

比如 「世上沒有兩片形狀完全相同的樹葉」,這體現到了事物的特性 —— 差異性;但是每種樹的葉子都有近似的形狀,這正是事物的共性 —— 規律性。從這個角度講,我們就可以接受這樣的事實了:計算機只能產生

偽隨機數

而不是絕對的隨機數。

系統在呼叫rand()之前都會自動呼叫srand(),如果使用者在rand()之前曾呼叫過srand()給引數seed指定了乙個值,那麼 rand()就會將seed的值作為產生

偽隨機數

的初始值;而如果使用者在rand()前沒有呼叫過srand(),那麼系統預設將1作為偽隨機數的初始 值。如果給了乙個定值,那麼每次rand()產生的隨機數序列都是一樣的~~

所以為了避免上述情況的發生我們通常用srand((unsigned)time(0))或者srand((unsigned)time(null))來 產生種子。如果仍然覺得時間間隔太小,可以在(unsigned)time(0)或者(unsigned)time(null)後面乘上某個合適的整數。 例如,srand((unsigned)time(null)*10)

另外,關於time_t time(0):time_t被定義為

長整型 ,它返回從2023年1月1日零時零分零秒到目前為止所經過的時間,單位為秒。

隨機數字生成基本是兩步走,首先生成乙個種子,然後根據這個種子解算出乙個落在指定區間的數字。種子的隨機性和最終生成的隨機數質量直接相關,如果你用同乙個種子同乙個隨機數發生器去生成「隨機數」,那麼得到的結果是一致的[99.9999...%]。當然這種情況是必須要避免的,也就是說必須避免玩家可以通過精心挑選的種子來得到**的結果。

為此常用的種子是採用觸發函式的時間。對於網路遊戲來說,考慮到網路傳輸中的種種可能問題,可以認為資料到達伺服器,呼叫隨即函式的觸發時間是隨機的,所得到的數字也具備極高的隨機性。

至於在服務端的落實情況,因程式設計而異。不過基本上可以認為就是生成乙個合乎要求的隨機數(比如區間1-100),再找乙個預設的值或者一組值去比對,落在某區間,就算通過,否則就判定為失敗。

比如洗裝備時有60%的概率獲得3條附加屬性,30的概率獲取4條,10%的概率獲取5條:

#include #include #include /*用到了time函式,所以要有這個標頭檔案*/

extern void getthreeattr();

extern void getfourattr();

extern void getfiveattr();

int main( void)

else if (number <= 89)

else

return 0;

}



關於概率性事件的產品效能和客戶體驗討論

事件回放 近期關於簡訊驗證碼出現的概率性事件,為處理db2序列返回概率大概在萬份之一為null的解決方案。方案一,為杜絕null的產生和資料庫資料的完全性及使用者體驗的角度,允許設計萬份之一為null的組合主健出現,但為必須要處理插入資料庫後的過濾處理,確保資料的完整性。方案二,為杜絕概率性nul出...

關於概率性事件的產品效能和客戶體驗討論

事件回放 近期關於簡訊驗證碼出現的概率性事件,為處理db2序列返回概率大概在萬份之一為null的解決方案。方案一,為杜絕null的產生和資料庫資料的完全性及使用者體驗的角度,允許設計萬份之一為null的組合主健出現,但為必須要處理插入資料庫後的過濾處理,確保資料的完整性。方案二,為杜絕概率性nul出...

C 如何實現介面事件

在類中宣告事件,然後在相應區域中呼叫它。namespace implementinte ceevents public class myeventargs eventargs public class shape idrawingobject protected virtual void onsha...