Cocos2dx 3.0 過渡篇(五) 隨機數的獲取
本來上午是要轉載一篇看起來還不錯的博客,被cocos2dx官方微博推薦過。誰知道早上打開鏈接時那篇博客已經轉為私密了。早知道昨晚就應該複製一下內容,今天厚臉皮的來篇原創豈不妙哉。哈哈。
1、簡單的隨機數用法:CCRANDOM_0_1 示例如下:
- int HelloWorld::getRand(int start,int end)
- {
- float i = CCRANDOM_0_1()*(end-start+1)+start; //產生一個從start到end間的隨機數
- return (int)i;
- }
2、上述的方法雖然簡便,但是運行多次後,發現產生的隨機數都一樣的,這是為什麼呢?這就涉及到“隨機數種子”這東西了。
什麼叫隨機數種子?這裏我們不妨.......百度一下。
在計算機中並沒有一個真正的隨機數發生器,但是可以做到使產生的數字重複率很低,這樣看起來好象是真正的隨機數,實現這一功能的程序叫偽隨機數發生器。
有關如何產生隨機數的理論有許多,如果要詳細地討論,需要厚厚的一本書的篇幅。不管用什麼方法實現隨機數發生器,都必須給它提供一個名為“種子”的初始值。而且這個值最好是隨機的,或者至少這個值是偽隨機的。“種子”的值通常是用快速計數寄存器或移位寄存器來生成的。
好了,看完上述介紹,多少對隨機數種子有了一定的概念,接下來就講下該如何在調用隨機數時初始化隨機數種子。代碼如下:
- cc_timeval psv;
- CCTime::gettimeofdayCocos2d(&psv, NULL);
- unsigned long int rand_seed = psv.tv_sec*1000 + psv.tv_usec/1000;
- srand(rand_seed);
別問我為什麼是這樣寫,就跟“不要問我從哪裏來”一樣的道理。使用起來如下:
- cc_timeval psv;
- CCTime::gettimeofdayCocos2d(&psv, NULL);
- unsigned long int rand_seed = psv.tv_sec*1000 + psv.tv_usec/1000;
- srand(rand_seed);
- For(int i=0;i<100;i++)
- {
- int _rand = getRand(1,100);
- CCLOG(“the _rand is : %d”,_rand);
- }
恩,看完後不知道你會不會有種疑問,為什麼不再每一次for循環都初始化下隨機數種子,這樣子不就更隨機了嗎?如:
- for(int i=0;i<100;i++)
- {
- cc_timeval psv;
- CCTime::gettimeofdayCocos2d(&psv, NULL);
- unsigned long int rand_seed = psv.tv_sec*1000 + psv.tv_usec/1000;
- srand(rand_seed);
- int _rand = getRand(1,100);
- CCLOG(“the _rand is : %d”,_rand);
- }
運行後會發現產生的數又不隨機了。原來初始化隨機數種子一定要在循環外,在循環內就沒什麼效果了。如果你要問我為什麼是這樣的,我隻能說“不要問我從....”。
嗬嗬,開玩笑的,我姑且給個自己瞎猜想的結論吧:
隨機數種子就相當於 隨機數的重置開關,你如果想獲得隨機數,肯定要先把開關打開吧,初始化了隨機數種子,也就是相當於打開開關,這時候“種子”就開始起來了,你每隔一段時間獲取隨機數,它都會反饋給你一個不同的位置數據,而如果你每獲取數據就要初始化隨機數種子(也就是重啟開關),這就相當於“種子”又從起點重新出發,這不是要累死“種子”的節奏麼?
哈哈,都是瞎掰的,大家看看就好啦。
3、接下來講下如何在一定範圍內,產生K數量不同的隨機數。
在網上能找到幾種實現方法,我這裏隻記錄下認為比較高效的做法
用數組 A[] 存放x到y的數值,然後在(x,y)產生第一個隨機數H做為下標,從數組A中取出A[H],然後將數組最後個元素賦值給A[H],再重新在(x,y-1)產生,如些循環
具體代碼實現
- int quantity = 12;
- int start = 0;
- int end = 36;
- int total = abs(end - start);
- if (quantity >total) {
- CCLog("隨機數錯誤");
- }
- int sequence[total]; //存放隨機數的數組
- int output[quantity]; //最終生成的不重複一係列隨機數
- //將sequence 初始化
- for (int i = 0; i < total; i++) {
- sequence[i] = start+i;
- }
- //隨機數種子
- cc_timeval psv;
- CCTime::gettimeofdayCocos2d(&psv, NULL);
- unsigned long int seed = psv.tv_sec*1000 + psv.tv_usec/1000;
- srand(seed);
- for (int i = 0; i < quantity; i++) {
- int num = this->random(0, end - 1);//在指定範圍下產生隨機數
- output[i] = sequence[num];//將產生的隨機數存儲
- sequence[num] = sequence[end-1];//將最後個下標的值填充到隨機產生的下標中
- end--;//在指定範圍 向前移
- }
恩,就寫這些咯。哈
轉發請務必注明出處:https://blog.csdn.net/start530/article/details/18713217
最後更新:2017-04-03 12:56:08