我的随机数生成器的问题

时间:2012-03-05 13:21:32

标签: c random

我自己学习基本的C并尝试创建一个扑克客户端。我有一个带有牌的阵列(称为kortArray)和一个牌手(称为kortHand)。我的实现并没有改变牌组,而是按顺序添加所有52张牌,然后从牌组中随机选择5张牌。我添加了一个标记(称为draget),用于说明是否已经拾取了卡片。

现在,当我运行下面的算法时,它通常会生成五个随机数,这些数字会影响玩家或计算机。但有时它会生成少于五个数字,即使我已经明确声明要生成五个可接受的值。

我有两个循环,一个循环运行五次,另一个循环运行,直到找到尚未被挑选的卡。中间的printf告诉我,这个算法并不总是生成五个被接受的数字,当发生这种情况时,玩家的手中包含带有无意义值的卡片。

srand((unsigned)(time(0)));
for(i = 0; i < 5; i++) {                        
    int x = rand()%52 + 1;
    while (kortArray[x].draget!=1) {                
        x = rand()%52 + 1;
        if (kortArray[x].draget != 1) {
            printf("%i\n", x);
            kortArray[x].draget = 1;
            kortHand[i] = kortArray[x];
        }
    }
}

5 个答案:

答案 0 :(得分:4)

问题仍然在于随机数的+1。

此外,如果已经选择了卡,则首先检查x的第一个分配,然后将其分配给另一张卡。

为什么不使用类似的东西:

int nr_cards_picked = 0             /* Number of uniquely picked cards in hand */
/* Continue picking cards until 5 unique cards are picked. */
while (nr_cards_picked < 5) {
    x = rand() % 52;                         /* Take a random card */
    if (kortArray[x].draget == 0) {
        /* Pick this card. */
        kortArray[x].draget = 1;             /* Card is picked */
        kortHand[i]         = kortArray[x];  /* Add picked card to hand */
        nr_cards_picked++;
    }
}

原谅编译错误;我附近没有编译器。

这种情况下你只有一次随机号码呼叫。

理论上它可能永远不会结束,但这不太可能。

答案 1 :(得分:2)

你有:

   int x = rand()%52+1; 
      while (kortArray[x].draget!=1){                 
        x = rand()%52; 

C中的数组从0开始编制索引。第一次调用rand()将生成一个从1开始的值。假设您声明kortArray []保存52个值,那么大约有2%的可能会超出数组。

您对rand()的第一次调用会生成1..52范围内的值。你的第二个电话会产生0..51。其中一个错了。

答案 2 :(得分:2)

有几点需要注意。

首先,如果对它们进行mod操作,则无法保证随机数生成器是随机的。更好的是将它分成52个部分,并选择那样。

其次,你最好不要移动你的调用来在while循环中生成一个随机数到结尾,或者只是在for循环的开头不生成一个。

你的问题发生的地方是你有时会离开while循环而不是实际输入它,因为你在进入循环之前随机生成一个数字。

鉴于所有这些,我会做一些代码如下:

srand((unsigned)(time(0)));
for(i=0;i<5;i++){         
     x=-1;               
     while (kortArray[x].draget!=1){                
          x = floor(rand()*52);
      }
      printf("%i\n", x);
      kortArray[x].draget=1;
      kortHand[i]=kortArray[x];
}

答案 3 :(得分:2)

仅当kortArray [x] .draget不为1时才输入嵌套循环。因此,每次为1时,不执行任何操作且未分配卡。首先确保你有一个独特的x然后在所有情况下更新kortHand [i]

答案 4 :(得分:2)

我建议使用不同的算法:

  1. 在牌组中创建一个介于0和牌数之间的随机数
  2. 将卡从该位置分配到适当的手
  3. 将最后一张卡换成该位置
  4. 将牌组中的牌数减少1。
  5. 继续1,直到发出必要数量的牌。
  6. 这样,你摆脱了旗帜,你可以保证线性表现。无需检查卡是否已经处理过。