Two random cards, random but there the same.

Started by
36 comments, last by bloodisblue 12 years, 10 months ago
@Zahlman: Again, this depends on what the random card generator is used for. Casinos routinely use multiple decks for blackjack. In the limit of an infinite number of decks, this is equal to just choosing a uniformly random card each time. Casinos don't do this since getting an infinite number of decks is kind of difficult, but if there were a technologically simple way of creating a perfect independent uniform distribution, they would probably prefer to do it that way.
Widelands - laid back, free software strategy
Advertisement

but if there were a technologically simple way of creating a perfect independent uniform distribution, they would probably prefer to do it that way.

Actually casinos now generally use continuous shuffle machines. It's not a perfectly independent uniform distribution but it's close, and the major advantage to the casino isn't from improved distribution but from the simple fact that the game goes faster and so more hands are played.

In any case, whatever the mechanism is used to randomize the cards, having the individual cards themselves implement the randomization is a violation of SRP.

In any case, whatever the mechanism is used to randomize the cards, having the individual cards themselves implement the randomization is a violation of SRP.


Right, that's the point. If you want to model several decks shuffled together, then model several decks shuffled together. If you want to model a magic box that creates cards out of thin air with equal probability, then model that - but don't model cards that randomize themselves. That's not what a card is.
You need to move away from the thinking that you create a random card, and instead, create a deck of 52 cards, and randomize the deck. For the blackjack game, it's what you will need.

Here's a simplified version




class Card
{
public:
Card();
int mType;
int mValue;
void Apply(int x, int y);
}

Card::Card()
{
// type and value will be assigned later
}

void Card::Apply(int x, int y)
{
// whatever
}

int main()
{
Card cardDeck[52];

for (int i = 0; i < 52; i++)
{
cardDeck.mValue = i % 13;
cardDeck.mType = i / 13;
}

// now you have an array of cards, of value 0 - 13, and types 0 - 3; shuffle them
Shuffle(cardDeck);

/* now they are in random order, so just deal from, starting at 0 */
cardDeck[0].Apply(100, 238);
// whatever
}

void Shuffle (Card *CardDeck)
{
srand(time(0));

for (int i = 0; i < 52; i++)
{
int RandNum = rand() % 52;
CardDeck = CardDeck[RandNum];
}
}

}

My Gamedev Journal: 2D Game Making, the Easy Way

---(Old Blog, still has good info): 2dGameMaking
-----
"No one ever posts on that message board; it's too crowded." - Yoga Berra (sorta)

That doesn't shuffle the array, that corrupts the array. Presumably you want a swap rather than an assign inside your loop. Of course, even if you made that change, your choice of randomization algorithm will create a slightly biased deck. std::random_shuffle() exists for a reason.
[font=arial, verdana, tahoma, sans-serif][size=2]An interesting observation about BeerNutts's algorithm (after changing the assignment for a swap) is that the probability of generating an even permutation and the probability of generating an odd permutation are different. If instead of 52 cards we were to sort a longer list of things, the probabilities would remain separated. Exercise: Compute the limit of the differences between those two probabilities, as the length of the list goes to infinity.[/font][font=arial, verdana, tahoma, sans-serif][size=2]
[/font][font=arial, verdana, tahoma, sans-serif][size=2]
[/font]

That doesn't shuffle the array, that corrupts the array. Presumably you want a swap rather than an assign inside your loop. Of course, even if you made that change, your choice of randomization algorithm will create a slightly biased deck. std::random_shuffle() exists for a reason.


Oops, I missed the swap. I was trying to give him a solution using simple terms; it sounds like he's not well versed in std library. I should have swapped them. And, I realize it won't be a very good shuffle, but again, it was a simple example.

My Gamedev Journal: 2D Game Making, the Easy Way

---(Old Blog, still has good info): 2dGameMaking
-----
"No one ever posts on that message board; it's too crowded." - Yoga Berra (sorta)

Recently I did something similar to this.
I created two classes, one card class and one deck class.

In the deck class I created a Vector and added an entire decks worth of cards (using nested for loops)

Then I created a temporary Vector called shuffledDeck. To get the cards into this deck I used this code

int cardsLeft = baseDeck.size();
for(int i = 0; i < 52; i++){
Random r = new Random();
int toRemove = r.nextInt() % cardsLeft;
if (toRemove < 0) toRemove *= -1;
cardsLeft --;
shuffledDeck.add(baseDeck.remove());
}
baseDeck = shuffledDeck;


From here you just need a method drawTopCard which removes and returns the top card from the deck. Whenever you run out of cards just recreate the base deck and shuffle again.

This topic is closed to new replies.

Advertisement