Shuffling

… in algorithm?

ping could be used as a random number, especially if you have many clients connected to the server (as online poker games probably do). Just collect the ping from all the players a few times every game, hash it to produce a standard string/byte array. The ping is “random” because it is influenced by a third party (the network, other users, other routers) which cannot be predicted.

Is a hand-shuffled and cut deck of actual playing cards really randomly sorted?

In my opinion, this is because physical methods can only approximate truly random shuffling. Computers, with clever random functions, can get much closer to true randomness than a human ever could.

Kind of ironic, really, since computers are about as deterministic as you can get, yet when properly programmed they can do much better than a human.

I’m not sure I buy the argument that we should duplicate inferior physical shuffling, because shuffling is somehow intended to be non-random. At least not in a typical Casino gameplay environment.

I definitely find that modeling real shuffling is more fun than actually randomizing the deck. My model for a bridge shuffle is:

  1. Simulate imperfect cut
    [set partition of array +/- X of center]

  2. Two stacks. A force is applied on the bottom card of each stack proportional to the number of cards left in that stack (since the cards are bent, and can be treated roughly as springs). Probability comes from the proportion of these forces.

There are so many fun parameters here. Cut error, card flexibility (per-card?!), perhaps the shuffler’s dominant hand influences next-card force?

Impractical, but a lot of fun :smiley: Any other ideas for parameters?

Is that algorithm reliable? It depends on the sorting algorithm to call the key function once for each element and cache the key. I don’t see anything in the OrderBy docs that state that it does this. It could potentially call the key function multiple times resulting in the same element receiving different GUIDs and thus a non-deterministic end point.

So far the only language I’ve seen with shuffling as a built-in array method is SystemVerilog (hardware programming/verification language).

I use my own random numbers code for my C/C++ programs, to have the same behavior from the same seed everywhere. And also to have some guaranties :smiley:

A pseudo-random number generator with a long period (2^219937 #8722; 1), fast (bits manipulation only), and good statistical properties is the Mersenne Twister. There is a special SIMD version of it, and it has some proof behind it. It simply rocks for simulations.

But the Mersenne Twister is also pretty easy to predict, just 634 outputs are neaded to predict it. The Blum Blum Shub generator is very hard to predict (I mean, you need a computer that not exists) while having good statistical properties. It uses product of big prime numbers so it also slow, that is not very important for a card game without AI. Blum Blum Shub, beside having a cool name, should be perfect for a poker game.

josh and others: Trefethen, L N Trefethen, L M, “How Many Shuffles to Randomise a Deck of Cards?”, Proceedings of the Royal Society London, A 456, 2561 - 2568 (2000). The paper describes their model of “real shuffling.”

Y’all should be careful about calling system or standard library “shuffle” routines unless you know how good the PRNG behind them is. Another good question is whether the PRNG is thread-safe (srand() / rand() isn’t).

There’s some interesting work out there about how to seed PRNGs from stock hardware by looking at uninitialized memory. You can also fetch “random” bits from /dev/random or /dev/urandom. Does Windows have something like this?

Alex – if you’re using a PRNG for crypto or otherwise want unpredictable outputs, you should run it through a one-way function of some kind. The Mersenne Twister was designed specifically to improve the accuracy of Monte Carlo simulations; it’s not at all meant for crypto or secure applications.

Incidentally, I’ve written a parallel PRNG tutorial at:

http://www.cs.berkeley.edu/~mhoemmen/cs194/Tutorials/prng.pdf

How about some C++:

random_shuffle(cards.begin(),cards.end());

And if we want to use some serious randomness:

int rand_gen(int max, int seed=0)
{
boost::mt19937 mersenne_twister(seed);//uniform distribution
//in 623 dimensions
return mersenne_twister()%max;
}

random_shuffle(v.begin(),v.end(), rand_gen);
//or with a seed
boost::function int (int) f = bind(rand_gen,_1, seedval);
random_shuffle(v.begin(),v.end(), f);

I would not use GUIDs in your shuffling algorithm. Older GUID generation algorithms (such as found in VS6) actually encoded the current time as the first part of the GUID and the MAC address of the computer’s network card in the last part of the GUID. The newer algorithm in Guid.NewGuid() eventually makes a Win32 call to UuidCreate, which generates a random GUID, though nothing in the docs says that it uses a non-pseudo random number generator. So I suspect that Guid.NewGuid() is no better than the pseudo random number generators that you’re recommending against. If you’re working in .NET, you want to use the RNGCryptoServiceProvider (http://msdn2.microsoft.com/en-us/library/system.security.cryptography.rngcryptoserviceprovider.aspx), which generates cryptographic quality random numbers.

@Mark Hoemmen : You should look at the wikipedia ‘Blum Blum Shub’ entry. It uses a well-known one way function : big prime numbers products. I cited it because of the bad security inherent to the Mersenne Twister :wink:

More evidence that physical shuffling is a pretty poor approximation of randomness:

http://www.flatrock.org.nz/topics/art_of_playing_cards/how_to_win_at_poker.htm

Two mathematicians hit the headlines in 1990 when they claimed that it took seven shuffles to make a pack of cards fully random, with no vestige of its original card order. Now comes a challenge to that claim. Five shuffles will almost do the job of randomisation, and six will make it certain, according to a paper in the Proceedings of the Royal Society*.

It all depends on how you define “random”, say Nick Trefethen and Lloyd Trefethen, respectively of Oxford University, UK, and Tufts University in Massachusetts in the US.

The magic number of seven shuffles was proposed by David Bayer and Persi Diaconis in the USA, who considered how shuffling affected a quantity called the “total variation norm.” This is a complicated measure of how effectively an ingenious gambler could be expected to win bets that the arrangement of cards in the deck was not completely arbitrary.

Bayer and Diaconis chose to define randomness in this way because they were interested in how shuffling might affect play in casinos. Some professional card players will go to any lengths to exploit an element of non-randomness in a card deck. Most casino dealers shuffle between two and four times - which, according to Bayer and Diaconis, was nowhere near enough to lose all trace of the starting configuration of the pack. In fact, they claimed that there is virtually no true randomisation, as they defined it, until the 5th shuffle. Only after the 7th, they said, does their measure of “orderliness” of the deck fall below half the initial value - enough to consider the pack well mixed.

Diaconis, himself a card magician, realised that astute card players could capitalise on this. He said that in his experience, shuffling seven times was almost unheard of in casinos. And he once spotted how bridge players in a New York club could anticipate the order of a deck shuffled four times between each hand.

First off, you could easily make a generic swap method if you wanted (I don’t think there is one in .Net already; they do use make one in the documentation as an example of a generic method)

Second, you could use RNGCryptoServiceProvider to get much better random numbers. Random is made to be fast and easy; RNGCryptoServiceProvider is made to be secure.

Are you showing off your lambda expressions knowledge? :stuck_out_tongue:

“although I do wish there was a built in Swap command in the C# language to simplify the code a bit”

http://icr.vox.com/library/post/swapping-variables-in-c.html

Why even bother to shuffle the array? It’s probably easier and simpler to put the cards into a collection and then randomly pick one to remove based on the size of the Collection.

	int pos;
	String card;
	ListString d = newDeck();
	while(!d.isEmpty()) {
		pos = new Double(Math.random() * d.size()).intValue();
		card = d.get(pos);
		d.remove(pos);
	}

Swap an integer, the XOR way:

ValueA ^= ValueB;
ValueB ^= ValueA;
ValueA ^= ValueB;

http://en.wikipedia.org/wiki/XOR_swap_algorithm

“Why even bother to shuffle the array? It’s probably easier and simpler to put the cards into a collection and then randomly pick one to remove based on the size of the Collection.”

I’ve used a similar approach in the past, though I seem to remember abandoning it for some reason. I can’t quite remember why though.

I’m reminded of one of Knuth’s Exercises: “Look at the subroutine library of each computer installation in your organization, and replace the random number generators by good ones. Try to avoid being too shocked at what you find.”