调用函数两次时生成随机数不起作用

时间:2015-12-27 12:54:29

标签: c function random srand

当我两次调用我的函数时,我试图获得两种不同类型的数字/颜色,但它不起作用。我已经播种了数字/功能,但它仍无效。

以下是我的代码的外观:

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

#define DIAMONDS 0
#define CLUBS 1
#define HEARTS 2
#define SPADES 3
#define JACK 11
#define QUEEN 12
#define KING 13
#define ACE 1
#define COLOR_SIZE 13
#define NR_OF_SUITS 4
#define DECK_SIZE 52


struct Card
{
    int suit;
    int value;
};

void printCards(struct Card *cardDeck);
void swapCards(struct Card *cardA, struct Card *cardB);
void shuffleCards(struct Card *cardDeck);
void printOneCards(struct Card *cardDeck);

int main()
{
    //struct Card deck[DECK_SIZE];      //Statiskt allokerad array
    struct Card * deck; //Dynamiskt allokerad array
    int index;
    int suit_index;

    deck = (struct Card *)malloc(sizeof(struct Card) * DECK_SIZE);
    for (suit_index = 0; suit_index < NR_OF_SUITS; suit_index++)    /* Initiera kortleken */
        for (index = 0; index < COLOR_SIZE; index++)
        {
            deck[suit_index*COLOR_SIZE + index].suit = suit_index;
            deck[suit_index*COLOR_SIZE + index].value = index;
        }
    printCards(deck);
    shuffleCards(deck);
    printCards(deck);
    printf("\n");
    printOneCards(deck);
    printf("Dealers cards\n");
    srand(time(NULL));
    printOneCards(deck);

    system("pause");
    return 0;
}

void printCards(struct Card *cardDeck)
{
    for (int i = 0; i < DECK_SIZE; i++)
    {
        switch (cardDeck[i].value + 1)
        {
        case ACE: printf("Ace ");
            break;
        case JACK: printf("Jack ");
            break;
        case QUEEN: printf("Queen");
            break;
        case KING: printf("King ");
            break;
        default: printf("%d ", cardDeck[i].value + 1);
            break;
        }
        printf("of ");
        switch (cardDeck[i].suit)
        {
        case DIAMONDS: printf("Diamonds ");
            break;
        case HEARTS: printf("Hearts ");
            break;
        case CLUBS: printf("Clubs ");
            break;
        case SPADES: printf("Spades ");
            break;
        default: printf("Something went wrong!! ");
            break;
        }
        printf("\n");
    }
}

void swapCards(struct Card * cardA, struct Card *cardB)
{
    struct Card temp;
    temp = *cardA;
    *cardA = *cardB;
    *cardB = temp;
}

void shuffleCards(struct Card *cardDeck)
{
    srand(time(NULL));

    for (int i = 0; i < DECK_SIZE; i++)
        swapCards(&cardDeck[i], &cardDeck[rand() % 52]);
}
void printOneCards(struct Card *cardDeck)
{
    srand(time(NULL));
    for (int i = 0; i < 2; i++)
    {
        switch (cardDeck[i].value + 1)
        {
        case ACE: printf("Ace ");
            break;
        case JACK: printf("Jack ");
            break;
        case QUEEN: printf("Queen");
            break;
        case KING: printf("King ");
            break;
        default: printf("%d ", cardDeck[i].value + 1);
            break;
        }
        printf("of ");
        switch (cardDeck[i].suit)
        {
        case DIAMONDS: printf("Diamonds ");
            break;
        case HEARTS: printf("Hearts ");
            break;
        case CLUBS: printf("Clubs ");
            break;
        case SPADES: printf("Spades ");
            break;
        default: printf("Something went wrong!! ");
            break;
        }
        printf("\n");
    }
}

因此,当我调用函数printonecards()时,它会在第一次打印2张随机卡片和颜色,但第二次调用它时,它不会。 如何解决此问题以及如何使其正常工作?

3 个答案:

答案 0 :(得分:2)

您在多个功能开始时多次致电srandsrand为随机数生成器播种,只有在您希望重置随机数生成器时才应调用它。当您在同一秒内多次使用srand作为种子调用time(NULL)时(这很可能考虑当前硬件),您将使用具有干净随机数生成器的相同种子。这将多次生成相同的数字。

解决此问题的方法是将您的号召srand移至main的开头,然后将其移至所有其他功能中。这样,您的随机数生成器将被设置为一个,并且不会被重置,从而产生更多的随机数。

编辑:

我第一次没注意到的另一个问题是你将相同的参数传递给函数printOneCards,即参数deck。这个论点在玩家的牌和经销商的牌之间没有区别,这意味着该功能将两次打印相同的牌组。

由于玩家似乎总是有2张牌,你可以使用指针算法来改变它。您的函数调用将变为:

printOneCards(deck); //Print the first and second card
printf("Dealers cards\n");
printOneCards(deck+2); //Print the third and fourth card

通过这种方式,您可以按照预期为玩家和经销商获得不同的结果。

答案 1 :(得分:0)

TL; DR 您需要在程序开始时仅为PRNG(伪随机数生成器)播种一次。从功能中删除srand(time(NULL));并将其放入main()

详细说明,time(NULL)时间粒度为1秒。这意味着,如果在1秒内多次调用,它将返回相同的值。这样,您最终会一次又一次地为PRNG播放相同的值,因此rand()生成的伪随机数将是相同的。

这就是为什么,您需要从被调用函数中移除播种部分以避免重新播种PNRG。

答案 2 :(得分:0)

您可以在所有需要播种新随机数时使用srand() 。如果您将srand(time(NULL))置于 for循环 while循环,那么您可能会得到您想要的内容。