how to shuffle cards without repeating

Dec 24, 2011 at 5:30pm
Hello everyone
I am making a card game but I have problem of shuffling cards.
I have to put the cards in a linked list. When I shuffle the list I get the same card number of time.

How can I shuffle them so that the number of elements of the list remain the same, no elements are repeated in the list. Thus, only the order of the cards are changed.

This is the function that i have made
1
2
3
4
5
6
7
8
9
10
11
12
13
void Deck::shuffle()
{
	CppLists::List sCards;
	int i, j;
	srand( time(0) );

for (int k=0; k < 52; k++){
	i = rand() % 13;
	j = rand() % 4;
	sCards.addCard(ranks.get(i), suits.get(j));
	}
	sCards.printCard();
}
Last edited on Dec 24, 2011 at 5:31pm
Dec 24, 2011 at 5:57pm
closed account (S6k9GNh0)
http://www.cplusplus.com/reference/algorithm/random_shuffle/
Dec 24, 2011 at 6:00pm
Rather have your shuffle method operate on a loaded deck of cards as opposed to it adding new cards.

This then implies that you should have some method (maybe in constructor or called from constructor) to initialize deck, ie just adding all cards to deck.

Then your shuffle method neads to choose 2 numbers within range of number of cards in deck (52 - I think) and swap the elements of those 2 positions. It should ideally repeat this process enough times (50 ~100) - then the deck should be well shuffled and have all its cards with no repeats.

Continue to use rand to choose your 2 positions each time, but applying scaling to the values so that they fit within range [0 .. 51].

Also try to seed your random generator with srand at least once when Deck is created. Use one of the time function values with which to seed random generator.
Dec 24, 2011 at 6:08pm
In a simple C# program I wrote I needed to shuffle a deck. What I did is create a bool dealt[52] initialized false to track which cards are dealt and pick the cards with
1
2
3
4
5
6
7
8
 //get unique cards
  do
  {
       mycard = rand.Next(52);//rand()%52
  }
  while (dealt[mycard]);
  dealt[mycard] = true;
  myval = (mycard % 13) + 2;
Dec 24, 2011 at 6:08pm

Thx for reply. I already have intialized the deck in the constructor like this.
But I actually don't know how can I change the order of the Cards randomly.

all the cards are saved in the list "cards".

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
Deck::Deck() {

	suits.add("Clubs");
	suits.add("Diamonds");
	suits.add("Spades");
	suits.add("Hearts");

	ranks.add("Ace");
	ranks.add("2");
	ranks.add("3");
	ranks.add("4");
	ranks.add("5");
	ranks.add("6");
	ranks.add("7");
	ranks.add("8");
	ranks.add("9");
	ranks.add("10");
	ranks.add("Jack");
	ranks.add("Queen");
	ranks.add("King");

	for (int j=0; j < 4; j++){
		for (int i=0; i < 13; i++){
			cards.addCard(ranks.get(i), suits.get(j));
		}
	}
}

Last edited on Dec 24, 2011 at 6:10pm
Dec 24, 2011 at 6:12pm
closed account (S6k9GNh0)
I literally gave you the link to the most convenient solution. Why is it being ignored?
Dec 24, 2011 at 6:24pm
@computerquip
Will that work if the OP is using a custom list class (ie: not std::list) that doesn't include iterators?
Dec 24, 2011 at 6:38pm
closed account (S6k9GNh0)
1. Why are you not using std::list?
2. Adding a basic iteration concept to your linked list is not difficult while the payout is generally high (i.e. compatibility with any generic iteration algorithm). The most difficult being the concept of generic programming. I wrote a rather poor article giving a very basic (and somewhat unfinished) implementation of the idea. While the commenting is poor, it's a bit better documented than what you'll find in your compiler implementation (although what isn't amiright?).

http://cplusplus.com/articles/Lw6AC542/
Last edited on Dec 24, 2011 at 6:52pm
Dec 24, 2011 at 6:53pm
I am not allowed to use std::list. I should use doubly linked list that I have created before.
Dec 24, 2011 at 7:18pm
closed account (S6k9GNh0)
Well, perhaps complicating implementation of your doubly-linked list isn't for the best...
However, the idea still applies right? Mark two random nodes in your linked list and swap them. To make sure you don't switch them up again, black list them somehow, maybe using a mask or something.
Topic archived. No new replies allowed.