閱讀597 返回首頁    go 阿裏雲 go 技術社區[雲棲]


Cocos2dx 3.0 過渡篇(五) 隨機數的獲取

本來上午是要轉載一篇看起來還不錯的博客,被cocos2dx官方微博推薦過。誰知道早上打開鏈接時那篇博客已經轉為私密了。早知道昨晚就應該複製一下內容,今天厚臉皮的來篇原創豈不妙哉。哈哈。

1、簡單的隨機數用法:CCRANDOM_0_1 示例如下:

  1. int HelloWorld::getRand(int start,int end)  
  2. {  
  3.  float i = CCRANDOM_0_1()*(end-start+1)+start;  //產生一個從start到end間的隨機數  
  4.  return (int)i;  
  5. }  

2、上述的方法雖然簡便,但是運行多次後,發現產生的隨機數都一樣的,這是為什麼呢?這就涉及到“隨機數種子”這東西了

什麼叫隨機數種子?這裏我們不妨.......百度一下。

    在計算機中並沒有一個真正的隨機數發生器,但是可以做到使產生的數字重複率很低,這樣看起來好象是真正的隨機數,實現這一功能的程序叫偽隨機數發生器。
    有關如何產生隨機數的理論有許多,如果要詳細地討論,需要厚厚的一本書的篇幅。不管用什麼方法實現隨機數發生器,都必須給它提供一個名為種子的初始值。而且這個值最好是隨機的,或者至少這個值是偽隨機的。種子的值通常是用快速計數寄存器移位寄存器來生成的。

    好了,看完上述介紹,多少對隨機數種子有了一定的概念,接下來就講下該如何在調用隨機數時初始化隨機數種子。代碼如下:

  1. cc_timeval psv;    
  2. CCTime::gettimeofdayCocos2d(&psv, NULL);    
  3. unsigned long int rand_seed = psv.tv_sec*1000 + psv.tv_usec/1000;    
  4. srand(rand_seed);   

別問我為什麼是這樣寫,就跟“不要問我從哪裏來”一樣的道理。使用起來如下:

  1. cc_timeval psv;    
  2. CCTime::gettimeofdayCocos2d(&psv, NULL);    
  3. unsigned long int rand_seed = psv.tv_sec*1000 + psv.tv_usec/1000;    
  4. srand(rand_seed);   
  5.   
  6. For(int i=0;i<100;i++)  
  7. {  
  8.   int _rand = getRand(1,100);  
  9.   CCLOG(“the _rand is : %d”,_rand);  
  10. }  

恩,看完後不知道你會不會有種疑問,為什麼不再每一次for循環都初始化下隨機數種子,這樣子不就更隨機了嗎?如:

  1. for(int i=0;i<100;i++)  
  2. {  
  3. cc_timeval psv;    
  4. CCTime::gettimeofdayCocos2d(&psv, NULL);    
  5. unsigned long int rand_seed = psv.tv_sec*1000 + psv.tv_usec/1000;    
  6. srand(rand_seed);   
  7.    
  8. int _rand = getRand(1,100);  
  9. CCLOG(“the _rand is : %d”,_rand);  
  10. }  

運行後會發現產生的數又不隨機了。原來初始化隨機數種子一定要在循環外,在循環內就沒什麼效果了。如果你要問我為什麼是這樣的,我隻能說“不要問我從....”。

嗬嗬,開玩笑的,我姑且給個自己瞎猜想的結論吧:

隨機數種子就相當於 隨機數的重置開關,你如果想獲得隨機數,肯定要先把開關打開吧,初始化了隨機數種子,也就是相當於打開開關,這時候“種子”就開始起來了,你每隔一段時間獲取隨機數,它都會反饋給你一個不同的位置數據,而如果你每獲取數據就要初始化隨機數種子(也就是重啟開關),這就相當於“種子”又從起點重新出發,這不是要累死“種子”的節奏麼?

哈哈,都是瞎掰的,大家看看就好啦。

3、接下來講下如何在一定範圍內,產生K數量不同的隨機數。

在網上能找到幾種實現方法,我這裏隻記錄下認為比較高效的做法

用數組 A[] 存放xy的數值,然後在(x,y)產生第一個隨機數H做為下標,從數組A中取出A[H],然後將數組最後個元素賦值給A[H],再重新在(x,y-1)產生,如些循環

具體代碼實現

  1. int quantity = 12;  
  2.     int start = 0;  
  3.     int end = 36;  
  4.     int total = abs(end - start);  
  5.     if (quantity >total) {  
  6.         CCLog("隨機數錯誤");  
  7.     }  
  8.     int sequence[total];  //存放隨機數的數組  
  9.     int output[quantity]; //最終生成的不重複一係列隨機數  
  10.       
  11.     //將sequence 初始化  
  12.     for (int i = 0; i < total; i++) {  
  13.         sequence[i] = start+i;  
  14.     }  
  15.       
  16.     //隨機數種子  
  17.     cc_timeval psv;  
  18.     CCTime::gettimeofdayCocos2d(&psv, NULL);  
  19.     unsigned long int seed = psv.tv_sec*1000 + psv.tv_usec/1000;  
  20.     srand(seed);  
  21.       
  22.     for (int i = 0; i < quantity; i++) {  
  23.         int num = this->random(0, end - 1);//在指定範圍下產生隨機數  
  24.         output[i] = sequence[num];//將產生的隨機數存儲  
  25.         sequence[num] = sequence[end-1];//將最後個下標的值填充到隨機產生的下標中  
  26.         end--;//在指定範圍 向前移  
  27.     }  

恩,就寫這些咯。哈


轉發請務必注明出處:https://blog.csdn.net/start530/article/details/18713217

最後更新:2017-04-03 12:56:08

  上一篇:go python中json格式數據輸出實現方式
  下一篇:go JRainbow 0.3版本發布