-1

I am having trouble with shuffling a deck of cards in C++. I have a deck of cards class. Within the class I have a vector of objects, which are the cards within the deck, and I am trying to shuffle the elements within the vector to shuffle the cards. However, the function I wrote to do it appears to be just shifting everything over every iteration instead of swapping it with another random element within the vector. I'm sure its something really simple and stupid that I am missing, but I just haven't been able to figure it out yet. Any help would be greatly appreciated. Thanks.

void shuffle(int seed = 0)
{
    for (int i = 0; i < 100; i += 1)
    {
        for (unsigned int i = 0; i < deck.size(); i++)
        {
            card *swap = deck[i];

            srand(time(NULL) + seed);
            int temp = rand() % 52;

            deck[i] = deck[temp];
            deck[temp] = swap;
        }
        cout << "shuffled deck: ";
        for (unsigned int i = 0; i < deck.size(); i++)
            cout << deck[i]->compare() << " ";
        cout << endl;
    }
}

This is being called within a probability function I made, inside a loop. The seed for the shuffle function is the iteration of the loop.

This is a sample of part of the output in one iteration

Chris
  • 95
  • 9
  • 2
    http://en.cppreference.com/w/cpp/algorithm/random_shuffle and call srand() once, at the start of your program. –  Apr 16 '18 at 17:49
  • 1
    `srand(time(NULL) + seed);` why are you seeding inside your loop? – drescherjm Apr 16 '18 at 17:50
  • @drescherjm Masochism. [Or they don't know how `srand` works.](http://en.cppreference.com/w/cpp/numeric/random/srand) One of the two. – user4581301 Apr 16 '18 at 17:53
  • because every time I have used srand within a loop, rand always gives me the same seed over and over again. I have been told its because srand only reseeds once per second, and the loop runs several times per second – Chris Apr 16 '18 at 18:01
  • I guess, with your questioning my use of it, maybe I dont understand it correctly, as I thought I did... – Chris Apr 16 '18 at 18:02
  • but regardless of whether using srand repeatedly is over kill, I still dont see the rest of the issue. It should be swapping each consecutive array element with another, random, element in the vector.... what am I missing? – Chris Apr 16 '18 at 18:06
  • ***because every time I have used srand within a loop, rand always gives me the same seed over and over again.*** Then why are you doing this knowing the bad result? – drescherjm Apr 16 '18 at 18:06
  • ***It should be swapping each consecutive array element with another, random, element in the vector*** No since you are reseeding each time it's not swapping with a random element. It's swapping with the same element each time. `temp` is likely the same value on every iteration because of the improper seeding. – drescherjm Apr 16 '18 at 18:09
  • 1
    Take a look at the examples here: http://en.cppreference.com/w/cpp/algorithm/random_shuffle – Jesper Juhl Apr 16 '18 at 18:12
  • I assume the assignment prohibits using `std::shuffle` or `std::random_shuffle` – drescherjm Apr 16 '18 at 18:15
  • I mispoke, but regardless, I moved srand outside the for loop and it worked, so thank you. Could you please help me to understand why it did not work though? Why would repeatedly reseeding cause it to generate the same number over and over again? – Chris Apr 16 '18 at 18:15
  • 1
    reseeding resets the numbers generated. If you use the same seed over and over you will always get the same random numbers (very useful for testing, by the way. You may want random numbers, but to test effectively you may need the same random numbers for all runs of the test). One `rand` per `srand` and you always get the same number. In this case you'll get a different number every second because the seed will change. – user4581301 Apr 16 '18 at 18:17
  • If you use the same seed rand() will return the same number. – drescherjm Apr 16 '18 at 18:17

1 Answers1

0

Initialize your RNG just once, for example in your main() function

    srand(time(NULL));

Then one of simplest methods of shuffling is just swap each item from the end to the beginning with a random element from those preceding it. Note the item to swap can be the same to be swapped – this way the item can also stay where it already is.

void shuffle()
{
    for (int i = 0; i < 100; i ++)
    {
        for (unsigned int n = deck.size(); n > 1; --n)
        {
            unsigned swapPosition = rand() % n;

            card *swap = deck[n-1];
            deck[n-1] = deck[swapPosition];
            deck[swapPosition] = swap;
        }
        cout << "shuffled deck: ";
        for (unsigned int n = 0; n < deck.size(); n++)
            cout << deck[n]->compare() << " ";
        cout << endl;
    }
}
CiaPan
  • 9,381
  • 2
  • 21
  • 35