简体   繁体   English

播种该号码时,兰德仍然无法正常工作

[英]Rand is still not working when im seeding the number

Note, the code below is not completely written out, I've already made a deck and shuffled the cards 请注意,下面的代码尚未完全写出,我已经制作好了纸牌并洗牌了

I don't understand why i don't get two random numbers, I've tried to seed the numbers but it doesn't seem to work properly. 我不明白为什么我没有两个随机数,我试图播种这些数字,但它似乎无法正常工作。 What i would like is for everytime i print out face/suit it should be two different numbers/colors. 我想要的是每次我打印出脸/西服时应该是两个不同的数字/颜色。 Where are my mistake? 我的错误在哪里?

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

struct card{
    const int *face; 
    const char *suit; 
};
typedef struct card Card;

void dealing(const Card * const wDeck);
void shuffle(Card * const wDeck);

int main(){
    srand(time(NULL));
    shuffle(deck);
    dealing(deck);
    return(0);
}

void dealing(Card * const wDeck)
{
    int j;
    j = rand() % 52;
    srand(time(NULL));

    printf("%d of %s\n", wDeck[j].face, wDeck[j].suit);
    printf("%d of %s\n", wDeck[j].face, wDeck[j].suit);
} 
void shuffle(Card * const wDeck)
{
    int i;     
    int j;    
    Card temp; 

    for (i = 0; i <= 51; i++) {
        j = rand() % 52;
        temp = wDeck[i];
        wDeck[i] = wDeck[j];
        wDeck[j] = temp;
    } 
} 

Remove the call to srand() from within dealing() . 删除调用srand()从内部dealing() Calling srand() once per program invocation (in main() ) is enough. 每个程序调用一次(在main() )调用srand()就足够了。

    void dealing(Card * const wDeck)
    {
        int j;
        j = rand() % 52;
        // srand(time(NULL)); /* no, no, no.
                              /* The PRNG has already been
                              /* seeded inside main() */

        printf("%d of %s\n", wDeck[j].face, wDeck[j].suit);
        printf("%d of %s\n", wDeck[j].face, wDeck[j].suit);
    } 
void dealing(Card * const wDeck)
{
    int j;
    j = rand() % 52;
    srand(time(NULL));

    printf("%d of %s\n", wDeck[j].face, wDeck[j].suit);
    //                        ^^^            ^^^
    printf("%d of %s\n", wDeck[j].face, wDeck[j].suit);
    //                        ^^^            ^^^
}

You're printing values of the j th element twice. 您将第j个元素的值打印两次。

dealing is problematic in several ways. dealing在几个方面都有问题。

Firstly, you are calling srand() every time you want a random number. 首先,您每次需要随机数时都调用srand() The way rand works is that it starts off with a seed number and performs a complicated piece of arithmetic on it each time it has to produce a new "random" number. rand运行的方式是,它以种子编号开始,并在每次必须产生新的“随机”编号时对其执行复杂的算术运算。 For this reason, the sequence isn't really random (that's why they are called pseudo random number generators (PRNGs). 因此,序列并不是真正随机的(这就是为什么它们被称为伪随机数生成器(PRNG)的原因。

You are reseeding the sequence with the current time in seconds every time you ask for a random number. 每次您请求一个随机数时,您都将使用当前时间(以秒为单位)重新播种该序列。 Now assuming your function deals the cards in a tight function with no artificial delays, is it not likely that you will always be reseeding the PRNG with the same time ? 现在,假设你的函数交易的卡在没有人为延迟紧的功能,是不是可能,你将始终与同一时间补种的PRNG? As pmg says, call srand() only once per run of your program. 如pmg所说,每次运行程序仅调用srand()一次。

Secondly, and I am assuming this is a typo, you forgot to generate a new random number before selecting the second card. 其次,我假设这是一个错字,您忘记了在选择第二张纸牌之前生成一个新的随机数。 (This is pmg's other answer.) Actually, as you have already shuffled the pack, why not just select the first two cards from the deck? (这是pmg的另一个答案。)实际上,由于您已经洗牌了,为什么不从牌组中选择前两张牌呢?

You don't say what platform you are using, but on some (like OS X), srand/rand is a very poor random number generator. 您没有说使用什么平台,但是在某些平台(例如OS X)上,srand / rand是非常差的随机数生成器。 You should use srandom/random if you have got it. 如果有,应该使用随机/随机。 Even better, you should be using arc4random_uniform() if your platform has got it. 更好的是,如果您的平台已安装,则应使用arc4random_uniform() This is because rand() % 52 introduces a bias because 52 is not a power of 2. Some numbers are more likely to come up than others. 这是因为rand() % 52引入了偏差,因为52不是2的幂。某些数字比其他数字更有可能出现。

Finally, your shuffle looks fine to me, but it might be biased. 最后,您的随机播放在我看来还不错,但可能会有偏见。 I would use the Fisher Yates shuffle which is known to be unbiased. 我将使用费希尔耶茨(Fisher Yates)随机播放,该播放器无偏见。

void fisherYatesShuffle(Card* const deck, size_t cardCount)
{
    for (size_t i = 0 ; i < cardCount ; ++i)
    {
        size_t upperCardIndex = cardCount - i - 1;
        size_t pickIndex = arc4random_uniform(upperCardIndex + 1);
        Card tmp = deck[upperCardIndex];
        deck[upperCardIndex] = deck[pickIndex];
        deck[pickIndex] = tmp;
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM