21 card trick

Hi,

I am trying to write a program which mimics a card trick that I saw once. The trick starts out by having a person select 1 card from 21 random cards, look at it, remember it, then put it back in the deck. I have begun to write this part of the program but have gotten stuck.

My idea was to use the random number generator built into c++ in order to generate random numbers 1 through 52, and then run it through a loop which would execute 21 times to simulate shuffling the deck then pulling out 21 random cards. I would then use a parallel array to replace these values with strings in another array.That parallel array would consist of pre-determined sets of data with one column for numbers 1 through 52 and the other column for abbreviations for cards. For example, 1=AC which is the ace of clubs, 2=2C (2 of clubs)...52=KD (king of diamonds). This way, when the 21 "cards" are displayed on the screen for the user to look at, they have the abbreviations instead of their corresponding numbers.

I haven even begun to change these int values over to strings yet, but I am close to getting the random number generator to work.The problem however is that each time the loop runs, the random # generator can possibly generate the same #'s more than once since it always has 1 to 52 to choose from.This means that their could be identical cards in the deck which is unrealistic.

I want to be able to some how take out those values that have already been generated so that I will never get a random value more than once. I tried running the random # generator once to get the first #, then run that again through a loop which will check the new random values generated against all of the previous values generated. If it finds a value that is the same, it should some how throw out that value and go through the loop again, and check the new value. If the new value is different, it should display it on the screen and store that value, with the other 20 values in a separate array from the pre-determined data.

Here is my code below. Right now, it gives me an infinite loop.I know what I want it to do, but I'm just not sure how to get it to "throw out" any identical values. I believe the problem is with the logic after the do...while part.

Any help wold be greatly appreciated.

Thanks and happy holidays,

Tom

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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
#include <cstdlib>
#include <iostream>
#include <cstdlib>
#include <ctime>
#include <sstream>
#include <string>

using namespace std;

int main(int argc, char *argv[])
{ const int HIGH=52;//constant for lowest possible card # which is KD.
 const int LOW=1;//Constant for lowest possible card # which is AC.

 const int cardnumbers[52]={1,2,3,4,5,6,7,8,9,10,11,12,13,//CLUBS
                            14,15,16,17,18,19,20,21,22,23,24,25,26,//SPADES
                            27,28,29,30,31,32,33,34,35,36,37,38,39,//HEARTS
                            40,41,42,43,44,45,46,47,48,49,50,51,52//DIAMONDS
                            };//array to hold card #'s.
                            
  string cardnames[52]={"AC","2C","3C","4C","5C","6C","7C","8C","9C","10C","JC","QC","KC",//CLUBS
                        "AS","2S","3S","4S","5S","6S","7S","8S","9S","10S","JS","QS","KS",//SPADES
                        "AH","2H","3H","4H","5H","6H","7H","8H","9H","10H","JH","QH","KH",//HEARTS
                        "AD","2D","3D","4D","5D","6D","7D","8D","9D","10D","JD","QD","KD"//DIAMONDS
                        };//array to hold card abbreviations.
                        
  int rand_cards[21];//array to hold cards  chosen by random number genorator. Populated by a loop and displayed on screen.                      
                         
                         
int choice,card1=1,i,card2,shuffle2,collumn1,collumn2;//shuffle is the integer 0 which initiates a while loop which will go through 21 itterations, therefore, generating 21 random numbers while also eliminating the numbers chosen from the ones remaining.
char shuffle;
    
cout<<"What would you like to do?  "<<endl;//Give user a choice
cout<<"Press 1 to continue "<<endl;//Allows user to continue with program
cout<<"Press 2 to quit "<<endl;//Allows user to escape from program
cin>>choice;//enter choice, either 1 or 2.


if(choice==1)
 {
  cout<<"Lets proceed with the card trick then"<<endl;
  cout<<"Press the letter 's' to shuffle the cards"<<endl<<endl;
  cin>>shuffle;//inputing 0 starts the loop which will generate 21 random numbers coresponding to 21 random cards out of 52 possible cards.
  cout<<endl;
  
        
         card1=(rand()+time(0))%(HIGH - LOW + 1) + LOW;//randomly generates an integer between 1 and 52. GIves the first random # only.
         card1=rand_cards[0];
         cout<<card1 <<",";//out put the card to the screen
         
         for(i=1;i<21;i++)//starts array at position 1 (2nd row) and runs through 20 itterations.
         {
           do 
           {
             card2=(rand()+time(0))%(HIGH - LOW + 1) + LOW;
             rand_cards[i];
             cout<<card2<<",";
           }
           while (card2 != rand_cards[i]);// && i<21);//Checks to see if the newest randomly generated card has been generated before. Displays it on screen an places in aray if it is unique.
           {
              if (card2==rand_cards[i])//If the program finds that the new randomly generated # is the same as one previously generated, then it skips that value and goes through the loop again until a unique value is found. 
                 {
                    rand_cards[i]='/0';
                 }//end of if statement
               }//end of while statement  
             }//end of for statement  
      cout<<endl;
      cout<<"Pick a card, any card but don't tell me which one it is.Press ENTER to continue"<<endl<<endl;
 }//end of if loop
else
    cout<<"Thanks for playing."<<endl<<endl;





    system("PAUSE");
    return EXIT_SUCCESS;
}
You can use a set to verify that the number hasn't appeared yet. A set is a container that allows you to store values of some type, but the values must be unique.

http://www.cplusplus.com/reference/stl/set/
Hey thanks for the tip. I've never used set before but I'll be sure to try that now.

Thanks,

Tom
You're probably going to want a different algorithm altogether. Try this: start out having the cards in order in your stack (actually... any order will work since it will end up shuffled randomly anyway right?).

Then, for each card in the stack, swap it with a random card. After 52 random swaps it will be assorted randomly.

Conveniently enough, if you decide to use std::vector for your project, you can use it in combination with std::random_shuffle (found in algorithm, as in #include<algorithm>) (http://www.cplusplus.com/reference/algorithm/random_shuffle.html).

Sorry if this takes the fun out of it, haha.
Topic archived. No new replies allowed.