1. Deck Shuffle

What I want to do is shuffle the cards like a person does. Split the deck roughly in half, then shuffle the two halves together from the bottom up by alternating between the havles and placing 1-4 cards from the halves in the orginal deck until all 52 cards are back in the original deck. Then repeat a good number of times to get the deck shuffled as if it has been used for years. I thought I had this all set. But if I try to shuffle it more than five times this way I get a segmentatin fault, and when I do it five times it isnt shuffled enough. So, with out further waiting here is the code.

card struct
Code:
```enum suit {hearts,diamonds,spades,clubs};

struct card{

suit s;     //takes values of the enum
int value;  //1-13, where 1=A,11-13=J,Q,K
bool dis_or_played; //has the card been discarded/played from a hand?

};```
deck class
Code:
```class Deck{

friend class Player;

public:
Deck();             //create deck
void shuffle();     //shuffle deck
void deal();        //deal to players and the kitty

private:
card d[52];        //the deck
int next_card;   //next card to be dealt

};```
shuffle function(maybe be a little hard to understand with the way I have it set up)
Code:
```void Deck::shuffle(){

time_t seconds;
time(&seconds);
srand((unsigned int)seconds);

random_shuffle(d[0],d[51]);

int b = rand() % (32 - 20 + 1) + 20;
int t = (52 - b);
card *temp1[b];
card *temp2[t];
int j=0;
int c = rand() % (4 - 1 + 1) +1;
int temp1_index = b-1;
int temp2_index = t-1;
int deck_index = 51;

for(int h=0; h<5; h++){
for(int i=0; i<b; i++){
temp1[i] = &d[i];
}

for(int i=b; i<52; i++){
temp2[j] = &d[i];
j++;
}

while(deck_index>=0){
if(temp1_index>=0 && (temp1_index + 1)>=c){
for(int i=0; i<c; i++){
d[deck_index] = *temp1[temp1_index];
temp1_index--;
deck_index--;
}
}
else{
int rest = temp1_index + 1;
for(int i=0; i<rest; i++){
d[deck_index] = *temp1[temp1_index];
temp1_index--;
deck_index--;
}
}

if(temp2_index>=0 && (temp2_index + 1)>=c){
for(int i=0; i<c; i++){
d[deck_index] = *temp2[temp2_index];
temp2_index--;
deck_index--;
}
}
else{
int rest = temp2_index +1;
for(int i=0; i<rest; i++){
d[deck_index] = *temp2[temp2_index];
temp2_index--;
deck_index--;
}
}
}
}
}```

2. First, I would only call srand() once at the beginning of the program, not every time you shuffle. Second, random_shuffle takes the first and one past the last element, so you should be using random_shuffle(d[0],d[52]); instead of d[51]. Third, you might already know this, but random_shuffle completely shuffles the deck by itself without any need to do your own shuffling.

For the actual problem of getting your human-esque shuffling code to work, I did notice that you never reset j to 0 inside your shuffle loop. The first time through it runs from 0 to t, but the second time through it is still at t so you are accessing the temp2 array out of bounds. Unluckily for you this doesn't cause a problem until the 5th time through.

I didn't look any further so there may be other problems.

One last note, card *temp1[b]; uses a non-constant value as the size of the array. This isn't legal in C++ but works on gcc because the C language allows it. You might consider changing that to a dynamic array (or even better a vector) if you plan on using your code on other compilers.

3. The random_shuffle was an attempt to do the shuffling a different way. But that didn't work because the array I pass isnt of type RandomAccessIterator or something. So just disregard that.

The setting of the j to 0 was the problem with getting the fault. But, after having it loop 1000 times the shuffle still doesn't seem to shuffle anything. Any idea?

The top half of the deck is all the red suits and the bottom the black. But when I deal only like two of the players have a black card in their hand and by a I mean ONE!

4. Rather than cutting the deck, which you seem to be trying to do, why not just swap random pairs of cards several times?

Code:
```i = rand() % 52;
j = rand() % 52;
temp = deck[i]; deck[i] = deck[j]; deck[j] = temp;```

5. Originally Posted by Salem
Rather than cutting the deck, which you seem to be trying to do, why not just swap random pairs of cards several times?

Code:
```i = rand() % 52;
j = rand() % 52;
temp = deck[i]; deck[i] = deck[j]; deck[j] = temp;```
I dont want to have to deal with getting duplicate cards in the deck. And I am trying to get a more realistic type of shuffle, seeing as I have seen some programs deal really weird when it comes to the way the game I am writing deals the cards.

I was thinking about doing that, but I figured I would come here for help with the way I was thinking of doing it.

Thanks for the suggestion though.

6. >> But that didn't work because the array I pass isnt of type RandomAccessIterator or something.

Sorry, it should be random_shuffle(d, d+52). If you just want to get a real shuffle, calling that once is all you have to do.

Now that you set j = 0 inside the loop, what about deck_index, temp1_index and temp2_index? This is why it is better style to declare your variables inside the smallest scope that you can. I would move all your local variables inside your first for loop, and remember to reset any variables that are re-used inside the while loop.

One other potential problem with your code... you are storing pointers in your temp arrays. The pointers point at positions in the deck, not values. So when you update the value during the shuffle, the temp array gets modified indirectly. I think the temp arrays should hold cards, not card pointers.

7. > I dont want to have to deal with getting duplicate cards in the deck
What duplicates?
You initialise 52 cards with say 52 unique cards, and you swap pairs a number of times. The uniqueness property does NOT change, but the order property does.
How is this not a shuffle?

8. Originally Posted by Salem
> I dont want to have to deal with getting duplicate cards in the deck
What duplicates?
You initialise 52 cards with say 52 unique cards, and you swap pairs a number of times. The uniqueness property does NOT change, but the order property does.
How is this not a shuffle?
Simmer down there buddy. I was wrong. It does shuffle. I just didn't see it because of the way it was written with everything on three lines.

9. Thank you Daved, my shuffle works now. It was all about the indices to my arrays and resetting j in the loop. Your help is much appreciated.

10. And I am trying to get a more realistic type of shuffle, seeing as I have seen some programs deal really weird
Yep, if the deal ever seems strange, it can't be random because with random deals there are always cards from every suit and no pairs. Oops, gotta run...I think I see a goblin lurking in the shadows of my bedroom.

11. Originally Posted by pjharris
And I am trying to get a more realistic type of shuffle, seeing as I have seen some programs deal really weird when it comes to the way the game I am writing deals the cards.
Just to really nail down a point that 7stud was making (and for fun), let's test your ability to judge randomness. If you want to.

Write down a random sequence of 1's and 0's, one hundred digits long, where each digit represents the outcome of a coin flip. But don't actually flip coins, try to make it look like you did flip coins, with a typical sort of outcome, and write the digits manually. Here's one example that's five digits long. It represents a heads-tails-heads-tails-heads coin toss sequence.

Code:
`10101`
Can you make your sequence of digits indistinguishable from real coin tosses, or will you be exposed as a faker? :-)

12. > Yep, if the deal ever seems strange, it can't be random because with random deals there are always cards from every suit
Being dealt SA,SK,SQ,SJ,S10 is just as likely as being dealt C2,H4,D6,S8,C10
The fact that one is far more desirable than the other is not a property of randomness.

Deal yourself many 1000's of hands, and count how many times each card comes up. If you're getting roughly equal numbers of each card, then you might be onto something.

13. Originally Posted by Rashakil Fol
Can you make your sequence of digits indistinguishable from real coin tosses, or will you be exposed as a faker? :-)
I get it. But like I said with the shuffle that I saw, and for the type of game that I am making it for(not poker or blackjack or any other casino card game game) the shuffle seemed a little off. I didn't say it wasn't shuffling, I said it was off. And I know about probability and all that stuff. It's just a preference with the way I want to shuffle the deck.

14. Originally Posted by Daved
One last note, card *temp1[b]; uses a non-constant value as the size of the array. This isn't legal in C++ but works on gcc because the C language allows it. You might consider changing that to a dynamic array (or even better a vector) if you plan on using your code on other compilers.
How would a dynamic array or vector be better for what I am doing? I guess because it isn't legal in C++ and I am using g++ as my compiler. So, I guess I don't understand the reason given. So, please elaborate on that too.

And why is a vector better than dynamic array(haven't used either)?

15. Many people change compilers, or re-use code on different projects that use different compilers. When you try to use that code on another compiler that doesn't support non-constant array sizes, it won't work. Also, when you post it on a website like this, only people with g++ will be able to run and test your code without making changes.

The gcc compiler allows it for a reason, so if you know you are only going to use g++ and you don't plan on using this code much elsewhere, then it is perfectly acceptable to take advantage of the feature. Besides, it might even be added to the C++ standard in the future.

A vector is better than a C style dynamic array because it encapsulates the memory management and provides a safer interface than plain arrays.