2015-12-27 3 views
-2

Я пытаюсь получить 2 разных типа чисел/цветов, когда я вызываю свою функцию дважды, но это не работает. Я засеял число/функцию, но она все еще не работает.Сгенерировать случайное число не работает при вызове функции дважды

Вот как мой код выглядит:

#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 случайным образом карты и цвета в первый раз, но второй раз я называю, это не так. Как исправить эту проблему и как ее правильно настроить?

+0

@ l3x Вы уверены, что это хороший обман? –

+0

@ l3x Я снова открываю этот вопрос, поскольку отмеченный обман может быть связан, но не является точным ответом на этот вопрос. Дайте мне знать, если вы думаете иначе. :) –

+0

По-прежнему нет ответа, который работает. Пробовал методы ниже, но не работал. – Philly

ответ

0

TL; DR Вам необходимо выровнять PRNG (генератор псевдослучайных чисел) только один раз в начале вашей программы. Удалите srand(time(NULL)); из функций и поместите их в свой main().

Чтобы уточнить, time(NULL) имеет временную гранулярность 1 секунда. что означает, что если он вызван несколько раз в течение 1 секунды, он вернет то же значение. Таким образом, вы в конечном итоге высеваете PRNG с одинаковым значением снова и снова, и, таким образом, псевдослучайные числа, генерируемые rand(), будут одинаковыми.

Вот почему вам нужно удалить часть посева из вызываемой функции, чтобы избежать повторного посева PNRG.

2

Вы вызываете srand пару раз в начале нескольких функций. srand сгенерирует генератор случайных чисел и должен вызываться только тогда, когда вы хотите сбросить генератор случайных чисел. Когда вы вызываете srand, используя time(NULL) как семя несколько раз за ту же секунду (что вполне возможно с учетом текущего оборудования), вы будете использовать одно и то же семя с чистым генератором случайных чисел. Это будет генерировать одно и то же число несколько раз.

Способ решения проблемы переводит ваш вызов на srand в начало main, а затем удаляет его во всех других функциях. Таким образом, ваш генератор случайных чисел будет установлен ровно один и не будет сброшен, создавая более случайные числа.

EDIT:

Еще одна проблема, которую я не заметил в первый раз, то, что вы проходите тот же самый аргумент функции printOneCards, а именно аргумент deck. Этот аргумент не отличается между карточками игрока и картами дилера, что означает, что функция будет печатать одну и ту же колоду дважды.

Поскольку у игрока всегда есть две карты, вы можете использовать арифметику указателя, чтобы изменить это. После этого ваши вызовы будут следующими:

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

Таким образом, вы получите разные результаты как для игрока, так и для дилера, как вы и предполагали.

+0

Ive пробовал, как вы написали в своем ответе. но он все еще не работает. Я удалил srand из всех других функций, кроме main, но он по-прежнему дает мне такую ​​же последовательность чисел. – Philly

+0

Вы переместили srand в начало main? Попробуйте написать это как первое действие, которое вы предпримите в основном. – Shadowwolf

+0

Да, я сделал это. Это не имеет значения, хотя, если я все еще вызываю функцию дважды, это дает мне ничего, кроме тех же двух напечатанных чисел. – Philly

0

Вы можете использовать srand()все время, необходимое для посева нового случайного числа. Если вы положите srand(time(NULL)) на для цикла или while loop, возможно, вы получите то, что хотите.