Archived

This topic is now archived and is closed to further replies.

Any good card shuffling functions out thar?

This topic is 5506 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hey all, I was wondering what other people write for a card shuffling function. I just use a simple array, which I then randomize, and it doesn’t quite seem to mimic what happens to a real-life deck when shuffled. Does anyone have a really good (sophisticated) card shuffling function? I don’t care what code it’s in. I’ll convert it to whatever code I decide to use. Thanks ___________________________ "It’s been a very long time since I’ve ceased to be preoccupied with reality." -Alfred Hitchcock

Share this post


Link to post
Share on other sites
Why not just have an array of type card with variables suit, value and taken in order?

Then use random to pick a number from 0-51, see if the card is taken, if it''s not set it to taken or if it is, proceed through the array until you find one that isn''t. If there aren''t any cards available, reset them all to taken=false and pick another random number.

You could use that same routine to take a sorted deck and randomize it into a second array of type card and go back and forth a few times. Then use the routine to pick a card from the randomized deck. Or go incrementally.

Ben


IcarusIndie.com [ The Rabbit Hole | The Labyrinth | DevZone | Gang Wars | The Wall | Hosting | Tiberian Merchandise!!!! | GameShot ]

Share this post


Link to post
Share on other sites
DIM CARDS(52)

RANDOMIZE TIMER

'Initialize the cards
FOR I=1 TO 52
CARDS(I)=I
NEXT I

' Shuffle the cards
FOR I = 1 TO 51
SWAP CARDS(I),CARDS(INT(RND*(52-I))+I+1)
NEXT I

That should work. The trick is calculating the random card to swap with.

[edited by - CodeJunkie on November 18, 2002 12:49:42 PM]

Share this post


Link to post
Share on other sites
I''ve never written a card shuffler before, so this might be a load of hot-air but:

When you shuffle a deck (depending on the shuffle you use), you''re not moving a card randomly from point a to point b. Instead, your moving a ''set'' of cards to some other position in the stack in some ''physical'' way.

When you shuffle, you''re always moving the cards in the same direction. That is- you dont move card 10 to position 1 and card 12 to position 33-- it would be more like card 10 to 1, and card 12 to 5..

Sometimes you move sets of sets. that is, 4 sets of 3 cards, from different parts of the deck.

You could try a shuffle like this:

///////

cardsInASet = rand() % 8; // move max of five cards at a time
numberOfSets = rand() % 10;
spaceBetweenSets = rand() % 10;
distanceSetMoved = rand() % 10;

startSet = rand() % 52;

for ( i = 0; i < numberOfSets; i++)
{
char cardsInThisSet;
char setOffset;
char distanceOffset;

// So every set does have exactly the same number //
cardsInThisSet = cardsInASet + ( 2 - (rand() % 4));
setOffset = 2 - rand() % 4;
distanceOffset = 2 - rand() % 4;

for ( j = 0; j < cardsInThisSet; j++)
{
char sourcePlace, destPlace;

sourcePlace = startSet + j + setOffset;
destPlace = startSet + j + setOffset + distanceMoved + distanceOffset;

destPlace = destPlace % 52;

MoveCard ( sourcePlace, destPlace);
}

startSet += spaceBetweenSets + ( 2 - (rand() % 4);
}

///////

This would simulate a well-known shuffle.

Will

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
hey CodeJunkie, that''s how i do mine too. works great.

i also use a seeding function to flip the time (can''t remember why, must have picked it up from one of the PhDs i used to work with):


  
unsigned GenerateSeed()
{
int d, s;
unsigned Seed = (unsigned)time(NULL);
char Temp, *SeedStr = _fcvt((double)Seed, 7, &d, &s);
int i = 0, l = strlen(SeedStr);
//

while ( i < l/2 )
{
Temp = SeedStr[i];
SeedStr[i] = SeedStr[l-i-1];
SeedStr[l-i-1] = Temp;
i++;
}
//

srand48((long)strtod(SeedStr, NULL));
//

return lrand48();
}

Share this post


Link to post
Share on other sites
thanks for the replies.

This is kinda what I'm doing now. It just seemed too simple, like it should be more complex. I guess I should explain my problem I'm having in more detail. When I step through my code it seems to place them in the same random order everytime. I'm using Visual Basic (but I don't have to, I just wanted to test it out quickly). Someone once told me that the random number generator in VB isn't that great, so I was wondering if there was a better way around this.

Thanks again.


Wow! I should have waited a bit before posting. Thanks everyone, I'll give these all a try.

___________________________
"It’s been a very long time since I’ve ceased to be preoccupied with reality."

-Alfred Hitchcock


[edited by - Sculder on November 18, 2002 1:21:03 PM]

Share this post


Link to post
Share on other sites
quote:
When I step through my code it seems to place them in the same random order everytime. I''m using Visual Basic


Well if that''s all you meant, just put the following line in there before you shuffle:

RANDOMIZE TIMER


Although I love the replies about modeling physical card shuffling That''s what I thought he meant too.

Share this post


Link to post
Share on other sites
That IS what I meant. Whta ouy wnat me 2b claer wit wha i right?

actually, it was the two fold problem. Yes the Randomize Timer was missing from my code (much thanks!) but the physical problem exisited too. That makes a lot of sense how cards shuffled are not randomized but groups of cards are. I tired it out (in C++ hehehe) and it works like I wanted it. The deck before always seemed too random. Thanks again for all the replies!

Share this post


Link to post
Share on other sites
While writing my own card game I had the same thought. A human shuffles the deck in subsets as mentioned. And I gave serious thought to trying to emulate that behavior. But in the end I decided that the way humans shuffle cards is born of necessity... we don''t have an hour to take each individual card and move it to another location after every hand played.

So after all was said and done, in the interest of fairness I thought it was more appropriate to let my code do the "simple" method. I swap two randomly selected cards in a loop for two seconds. Even on slower processors this results in thousands of swaps which I think results in a more truly randomized deck.

Larry Johnson - Head flunky in charge of diddly-squat.

www.sillisoft.com

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
I don''t know about you, but when you shuffle a deck IRL then you split the deck in two decks with equal lenght and then you simply make a new deck where you put first a card from deck 1 then one from deck 2 and so on. Why not do it that way? It is the real way, isnt it?

You know, if i hade been better at english, then this wouldn''t have sound as crappy.

/ Jolle

Share this post


Link to post
Share on other sites
quote:
Original post by l99057j
I swap two randomly selected cards in a loop for two seconds. Even on slower processors this results in thousands of swaps which I think results in a more truly randomized deck.


This sounds unnecessarily complicated ... why not just pick a random card (0-52) for the first position of the new deck, a random card remaining card (0-51) for the second, and so forth. (I''d probably look into Stoffel''s suggestion, unless I were really into reinventing the wheel, but I don''t know the intricacies of how the STL algorithm operates.)

Share this post


Link to post
Share on other sites
Knuth discusses this in the Art of Computer Programming. His algorithm is simple and effective... do a dejanews search. (or buy the book ) Another common approach is to just assign a random number to each card in the deck and then sort the cards based on this number. However, for this method you need a good random number generator, and good seeding. This is the method that ParadisePoker uses for deck shuffling.

Something you do *NOT* really want to do is simulate physical human shuffling, if the goal is to randomize the cards! That would be pointless.

Share this post


Link to post
Share on other sites
(Tangent. I remember hearing once that if you perfectly shuffle 7 times you''ll get the deck right back in the starting order.)

Stefu: remind me never to play poker with you.

Miserable:
quote:

The first template function evaluates swap(*(first + N), *(first + M)) once for each N in the range [1, last - first), where M is a value from some uniform random distribution over the range [0, N). Thus, the function randomly shuffles the order of elements in the sequence.


There''s also a functor overload that lets you substitute your own random number generator in place of whatever random_shuffle happens to be using internally (rand () would be a good guess).

Share this post


Link to post
Share on other sites
Seems like the physical shuffling model is being made a lot more complicated than it should be, and still not that accurate. If you really want to model a human shuffle, just think about exactly what happens when a human shuffles cards:

- start with a stack of cards in whatever order
- split it into two roughly equal portions, i.e. stack 1 contains whole deck, take half (+-5/10) of that array right off the "top" and put it in another array (stack)
- make a third, empty array to represent the freshly shuffled deck
- continue to alternately take 1-5 cards from the "bottom" of each of the first two stacks and add them to the third stack until you''re out of cards in the first two stacks.

Might not be blazingly fast or the best shuffle, but it will be a pretty accurate approximation of the standard two-handed human shuffle and it''ll run plenty fast for a card game. It''s also easier to write (IMHO) than something that shuffles cards in place (one array).

Share this post


Link to post
Share on other sites