Archived

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

RaistlinMajere

help with rand()

Recommended Posts

Lektrix    106
If you want the random numbers to be different each time you execute your program (i.e. random), you will have to seed rand(). Include ctime, in addition to cstdlib:

#include <cstdlib>
#include <ctime>

...
{
    srand( unsigned ( time(0) ) );

    ...

    // now can use rand()
}
...

You don't really need the explicit type cast in there, though.

[ Google || Start Here || ACCU || STL || Boost || MSDN || GotW || MSVC++ Library Fixes || BarrysWorld || E-Mail Me ]

[edited by - Lektrix on September 2, 2003 6:47:03 PM]

Share this post


Link to post
Share on other sites
Guest Anonymous Poster   
Guest Anonymous Poster
quote:
Original post by joseph drake
num = srand(time(NULL));

I think this is more portable

Don''t listen to this, it is very very wrong.

read this: http://www.robertjacobs.fsnet.co.uk/random.htm

it tells the correct way to use rand, even a way that will distribute the numbers more evenly than if you used %

Share this post


Link to post
Share on other sites
Fruny    1658
random_shuffle is much more suitable for card shuffling


#include <algorithm>

int deck[52];
...
std::random_shuffle( deck, deck + 52 );




[ Start Here ! | How To Ask Smart Questions | Recommended C++ Books | C++ FAQ Lite | Function Ptrs | CppTips Archive ]
[ Header Files | File Format Docs | LNK2001 | C++ STL Doc | STLPort | Free C++ IDE | Boost C++ Lib | MSVC6 Lib Fixes ]

Share this post


Link to post
Share on other sites
Lektrix    106
Does the C++ Standard state any rules for the internal random generator used in the overloaded version of std::random_shuffle that takes only two arguments?

For example, in GCC's STL implementation, it seems to merely use rand() (or lrand48() if it is available), and doesn't seem to seed it. In which case, the other overloaded version, which takes a random number generator functor as a third argument, might be more suitable.

Just to add clarity (and reference), I'm talking about these declarations:

template <typename RandomAccessIter>
void random_shuffle(RandomAccessIter first, RandomAccessIter last);

template <typename RandomAccessIter, typename RandomNumberGenerator>
void random_shuffle(RandomAccessIter first, RandomAccessIter last, RandomNumberGenerator& rand);


[ Google || Start Here || ACCU || STL || Boost || MSDN || GotW || MSVC++ Library Fixes || BarrysWorld || E-Mail Me ]

[edited by - Lektrix on September 2, 2003 7:35:20 PM]

Share this post


Link to post
Share on other sites
VbDestroyer    122
Hello,
the thing these people are forgeting is that you want only four of the cards 1 through 13. I used a array and random number to fill each one then ran through 13 if then''s to check if there was more than 4 of that card, then the while loop ran out after all 52 spots were assembled. then you just assign a varible to the current block in the array, and when you need a new card you just do a yourvariablehere++; You might want to look into making the computer count cards and bet, i did this and it makes the game alot more interesting.

Share this post


Link to post
Share on other sites
Thr33d    382
Heads up,

VbDestroyer is correct - If you use the method stated, you will get duplicate cards (well... you have a > 99% chance getting at least one duplicate)

To do it better (one right way of doing it) :

First set up the cards in your array so that each card (if it is indexed 0 to 51) has it's ideal index value.

Then loop though each card. For each card select a "random" value from 0 to 51 ( rand() % 52; )
That's the second card's index. Swap the card's places.
ie.
temp=card[i]; card[i]=card[j]; card[j]=card[i];  

It's ok if i=j by chance.

You can loop though multiple times if you aren't satisfied by the results, but hey - at least now you won't have duplicates.

Good Luck,
-Michael

edit: stupid thing thinks the [i] is italics
Btw, this is kinda like the oposite of what's known as the Selection Sort: Check it out.


[edited by - thr33d on September 2, 2003 7:50:40 PM]

Share this post


Link to post
Share on other sites
Fruny    1658
quote:
Original post by Thr33d
Then loop though each card. For each card select a "random" value from 0 to 51 ( rand() % 52; )
That''s the second card''s index. Swap the card''s places.
ie.
temp=card[‍i][‍i]; card[‍i]=card[j]; card[j]=card[‍i];   

It''s ok if i=j by chance.



std::random_shuffle(card, card+52);



[ Start Here ! | How To Ask Smart Questions | Recommended C++ Books | C++ FAQ Lite | Function Ptrs | CppTips Archive ]
[ Header Files | File Format Docs | LNK2001 | C++ STL Doc | STLPort | Free C++ IDE | Boost C++ Lib | MSVC6 Lib Fixes ]

Share this post


Link to post
Share on other sites
Beer Hunter    712
quote:
Original post by Thr33d
Then loop though each card. For each card select a "random" value from 0 to 51 ( rand() % 52; )
That''s the second card''s index. Swap the card''s places.
Not completely random.
You choose 52 random numbers from [0, 52), so there are 5252 equally likely sequences of numbers outputted by the RNG. However, there are only 52! permutations of a deck of cards. Since 5252 is not evenly divisible by 52!, some permutations must be more likely than others.

Instead, loop through each card (except the first). For each card i, swap it with a random card j where 0 <= j <= i.
In other words: std::random_shuffle(card, card+52).

Share this post


Link to post
Share on other sites
Thr33d    382
Beer Hunter:

Yeah, you're right (so far as I can tell) I'm not so great with proofs of stuff in math, I kinda work from my mind and the practical side of things.

But what you say makes sense:
In the way I mentioned, you repick many of the first cards to be switched with the later cards. I don't really see how this could somehow create any less random distrubution of sets of cards, but, ah, I can see that my concept was off base.

You're right also with the 52^52 and the 52! math parts I now see.

When going through a deck of cards, the first card is (theoretically) completely random. As you choose the next card, it is a random card of the remaining. (My logic is correct, right?) When you get to the last card you need not swap it, it has most likely been swapped, and if not, well, it's just part of the chance of things (required for even spread of cards.)

So really it should look something like

int j;
for(int ì = 0; ì < 51; ì++)
{
j = rand() %(52-ì)+ì;
swap(cards[ì], cards[j]);
}

the swap function would be defined somewhere else (just swaps two variable's values)

As I saw it though, in what you wrote
"
Instead, loop through each card (except the first). For each card i, swap it with a random card j where 0 <= j <= i.
"

You seem to be taking a backwards approach to it, but it doesn't quite look right. (Because you're swapping swapped cards, which seems really funky to me - kinda like what I was doing before)

"
In other words: std::random_shuffle(card, card+52).
"

Can't comment on this - I don't know how random_shuffle works
I'm more of a Java man myself.

Please tell me if my math is off, and explain to me if I'm wrong in my interpretation of your listed method of shuffling. Also, please let me know how random_shuffle works if you reply to other stuff of mine.

Thanks,
-Michael

[edited by - thr33d on September 3, 2003 11:45:24 AM]

Share this post


Link to post
Share on other sites
Fruny    1658

template<typename _RandomAccessIter>
inline void
random_shuffle(_RandomAccessIter __first, _RandomAccessIter __last)
{
// concept requirements

__glibcpp_function_requires(_Mutable_RandomAccessIteratorConcept<
_RandomAccessIter>)

if (__first == __last) return;
for (_RandomAccessIter __i = __first + 1; __i != __last; ++__i)
iter_swap(__i, __first + __random_number((__i - __first) + 1));
}


For all elements i in [first;last) swap i with a random element in (i;last).


[ Start Here ! | How To Ask Smart Questions | Recommended C++ Books | C++ FAQ Lite | Function Ptrs | CppTips Archive ]
[ Header Files | File Format Docs | LNK2001 | C++ STL Doc | STLPort | Free C++ IDE | Boost C++ Lib | MSVC6 Lib Fixes ]

Share this post


Link to post
Share on other sites