學而無術者比不學無術者更加愚蠢 ----富蘭克林
玩遊戲的,總歸會有很多心得,網上略微搜一下,就會發現很多墊裝備的言論,很多人相信墊裝備有用.這是問題!!
OK,讓我們來把問題簡化一下,因為裝備打造合成機率實在是繁複,所以存在必要的簡化.問:
連續的拋一枚硬幣,失敗N次之後,第N+1次失敗的機率是多少?會不會比50%高(!!!這是我們真正要搞定出的問題).
拋硬幣,是隨機事件.理論上講,成功失敗的機率各50%(頭像朝上與否),而且任何兩次隨即之間完全無關.否則他就不叫隨機事件了.當年機率論學的不好,但是頭腦裡面還有一點意識,我不相信連續的失敗可以明顯提高成功的機率!
但是理論學的太差,我不能證明第N+1次的機率還是那麼高.....好吧,我只能寫代碼,看看類比的真實情況是什麼樣子,來代碼:
#include <stdlib.h>#include <time.h>#include <iostream>#include <Windows.h>#include <assert.h>#pragma comment(lib, "advapi32.lib")#define RANDOM_TIMES1000000#define FAIL_TIMES5#define FAIL_PERCENT50#define PERCENT_MAX100//#define C_RANDOM#ifdef C_RANDOM//nop#else#define RAND_MAX65535static HCRYPTPROVhProvider = 0;static const DWORDdwLength = 2;static BYTEpbBuffer[dwLength] = {};#endifstatic void random_init(){#ifdef C_RANDOMsrand((int)time(0));#elseDWORD result =::CryptAcquireContextW(&hProvider, 0, 0, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT | CRYPT_SILENT);assert(result);#endif}static void random_close(){#ifdef C_RANDOM//nop#else::CryptReleaseContext(hProvider, 0);#endif}static int _random(){unsigned short _rand_value = 0;#ifdef C_RANDOM_rand_value = (unsigned short)rand();#else DWORD result = ::CryptGenRandom(hProvider, dwLength, pbBuffer);assert(result);_rand_value = *(unsigned short*)pbBuffer;#endifreturn _rand_value;}static long random_count = 0;static int random_result(){int times = 0;while(times < FAIL_TIMES){int _num = _random();random_count++;if((1.0f*_num/RAND_MAX) > (1.0f*FAIL_PERCENT/PERCENT_MAX)){times++;}else{times = 0;}}random_count++;return _random();}int main(int argc, char* argv[]){random_init();long times_total = 0;long times_fail = 0;for(int times = 0; times < RANDOM_TIMES;++times){int x = random_result();if((1.0f*x/RAND_MAX) > (1.0f*FAIL_PERCENT/PERCENT_MAX))times_fail++;times_total++;}std::cout<<"total: "<<times_total<<std::endl;std::cout<<"fail: "<<times_fail<<std::endl;std::cout<<"random_count: "<<random_count<<std::endl;system("pause");random_close();return 0;}
這裡用了兩種隨機數的實現,一種是標準C隨機數,另外是CryptGenRandom.Windows下面沒/dev/random和/dev/urandom,所以用哪個API代替.
代碼我不想做過多的解釋,比較重要的就那幾個宏,沒事幹自己改變一下宏,運行一下,看看結果:-)我這邊CryptGenRandom的兩次結果:
total: 1000000fail: 499497random_count: 62905788請按任意鍵繼續. . .total: 1000000fail: 499914random_count: 62979706請按任意鍵繼續. . .
另外再上一次標準C隨機數的運行結果:
total: 1000000fail: 500330random_count: 63103246請按任意鍵繼續. . .
可以看到,幾次隨即類比的結果,差不多是相似的:連續失敗N次之後,第N+1次的機率是不變的. 這才叫隨機事件.:-)
但是問題還沒完,這裡需要架設隨機數的品質非常的好,兩次隨機之間沒有關聯.事實上,標準C的隨機數很難做到這一點(偽隨機數產生器).偽隨機數,有可能被破解,預測;真隨機數不會:-D.
所以,網遊在進行跟RMB相關的隨機時,可以考慮一下真隨機數,或者是品質稍微好一點的RNG;跟RMB無關的,libc的rand/rand_r足矣~~~~
PS:
記得我們一個策劃,給怪物掉落的機率設定的太低(20%還是25%),然後打了據說有四十幾個怪,一個東西都沒掉....後來換成rand_r,效果好了很多.
參考:
http://msdn.microsoft.com/en-us/library/aa379942(v=vs.85).aspx