"Robert Redelmeier" <redelm@[EMAIL PROTECTED]
> wrote in message
news:vRthk.30908$co7.2626@[EMAIL PROTECTED]
> Rod Pemberton <do_not_have@[EMAIL PROTECTED]
> wrote in part:
> > Why draw randomly? You can properly simulate a hand shuffled deck of
> > card from an initially ordered deck in a few lines of C code:
[snipped]
>
> Very cute, a simulation of human cut'n'flutter shuffling.
:-) Thank you. Did you look at it enough to understand how it cuts the
deck with an inexact cut without under/overflow from each half of the
deck?
> However, the results are far from random.
Well, I sure didn't perform a statistical analysis on my compilers
rand()/srand()... (You can if you want. It's below.)
> It looks like the
> deepest the top card can move is the 6 last card in the
> deck.
Okay. (Doesn't bother me if it's slightly defective.)
> It is pseudo-random.
First, human shuffling isn't random. If you're intending to mimic human
play, you don't want a truly random shuffle. Do you? I.e., if you start
out with a fully ordered deck, shuffle it three times with "flutter",
without trying to do a perfect shuffle (exact cut and one card for card
from
each half), then you get something very similar, I think.
Second, rand() is usually implemented as pseudo-random number generator
(PRNG). So, there's no way (AFAIK) to get random results from it no
matter
how you use it. From plots I've seen, it seems the first, second, third
order combinations of typical rand() values are still non-random. So, you
may want a better random function (e.g., Mersenne Twister, etc.) if you
need
a truly random shuffle.
The compiler I was using uses the following for rand()/srand(). Your
compiler is likely to use something different. I.e., you're likely
getting
different results from me.
/* Copyright (C) 1994-8 DJ Delorie, see COPYING.DJ for details *//*GPL*/
int rand(void)
{
/* This multiplier was obtained from Knuth, D.E., "The Art of
Computer Programming," Vol 2, Seminumerical Algorithms, Third
Edition, Addison-Wesley, 1998, p. 106 (line 26) & p. 108 */
next = next * 6364136223846793005LL + 1;
/* was: next = next * 0x5deece66dLL + 11; */
return (int)((next >> 21) & RAND_MAX);
}
void srand(unsigned seed)
{
next = seed;
}
The compilers doc's recommended losing the lower bits of it's rand()
function - too static. And, since the results didn't look quite natural
on
my machine with rand(), I randomized the range also on the flutter (i.e,
two
rand()'s). With the dual rand()'s, output looked from my compiler looked
slightly more natural to me after three shuffles. I ran through a
number of deals in my head. They seemed more natural too. Since rand()
is
primed by time(0) via srand(), if you run it multiple times, you'll notice
the results are "different but seemingly similar somehow" until another
second has elapsed... Then, you see larger, more random, deck changes.
And, the shuffle routine was meant to be called random times too, like a
normal shuffler would do. I usually shuffle three and upto eight...
Rod Pemberton


|