遊戲中經常會遇到概率性的問題,比如裝備公升級的成功率,合成寶石的成功率,洗裝備時出現隨機屬性條數的概率等,這些概率性事件具體是怎麼實現的呢?在網上看了一些相關的文章,總結一下。
首先需要了解兩個函式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...