problem with creating object

I'm trying to make a pack of cards but I have a problem with how to create the object (Card and Deck), now I'm testing the Card class and I don't know why it doesn't work.

thanks in advance.

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
#include  <iostream>
#include "Card.h"

using namespace std;

void Card::getCard(){
	
	switch (rank){
	case 1:
    		cout << "Ace of "<< suit;
    		break;
    	
		case 2:
    		cout << "2 of " << suit;
    		break;
    		
    	case 3:
    		cout << "3 of " << suit;
    		break;
    	
	case 4:
    		cout << "4 of " << suit;
    		break;
    		
	case 5:
    		cout << "5 of " << suit;
    		break;
    	
	case 6:
    		cout << "6 of " << suit;
    		break;
    		
	case 7:
    		cout << "7 of " << suit;
    		break;
    	
	case 8:
    		cout << "8 of " << suit;
    		break;
			
	case 9:
    		cout << "9 of " << suit;
    		break;
    	
	case 10:
    		cout << "10 of " << suit;
    		break;
			
	case 11:
    		cout << "Jack of " << suit;
    		break;
    	
	case 12:
    		cout << "Queen of " << suit;
    		break;
			
	case 13:
    		cout << "King of " << suit;
    		break;			
	}
}


1
2
3
4
5
6
7
8
9
10
11
12
13
14
#ifndef CARD_H
#define CARD_H

class Card {
	private:
		int rank; //1-13 //exclude joker
		char suit[10]; // clubs, diamonds, hearts and spades
		
	public:
		void getCard(); //cout the card
		Card(int, char* );
		
};
#endif 


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <iostream>
//#include "Deck.h"
#include "Card.h"
using std::cout;
using std::endl;



/* run this program using the console pauser 
or add your own getch, system("pause") or input loop */

int main(int argc, char** argv) {
	Card _card(3,"test");   //problem is here  
	
	_card.getCard();

	cout << "test"<<endl;

	return 0;
}
Last edited on
you haven't defined the constructor. something like:
1
2
3
Card::Card( int r, char* s ) : rank{ r }, suit{ s }
{
}
ah thanks a lot!

now the second part is creating the cards in the class Deck which I am not able to do, here is what I have tried:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#ifndef DECK_H
#define DECK_H
#include "Card.h"

class Deck{
	
	private:
		Card pack [51];
		int nextCard;
		
	public:
		//constructor
		Deck(Card, int);
		
		void Shuffle();
		
		Card distribute;
		
		
};
#endif



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
#include  <iostream>
#include "Card.h"
#include "Deck.h"

Deck::Deck(Card pack, int nextCard){
	int y=1;
	
	for (int i=0; i = 12; i++){
		nextCard=i;
		pack[nextCard] = new Card(y, "Heart");
		y++;
	}
	
	y=1;
	for (int i=13; i = 25; i++){
		nextCard=i;
		pack[nextCard] = new Card(y, "Spade");
		y++;
	}
	y=1;
	
	for (int i=26; i = 38; i++){
		nextCard=i;
		pack[nextCard] = new Card(y, "Club");
		y++;
	}
	y=1;
	
	for (int i=39; i < 51; i++){
		nextCard=i;
		pack[nextCard] = new Card(y, "Diamond");
		y++;
	}
	
}
	
void Deck::Shuffle{

 rand (time(NULL));

	Card tempCard;
	int rand1, rand2;
	
	for (i = 0; i < 52; i ++)
	std::swap( card(i), card(rand() % 52);

}	

void Deck::distribute{
	if (nextCard >= 0 && nextCard <= 51){
		Deck[nextCard].getface  // not sure if possible, but i want to cout the card 
		nextCard++;}
	else{
		return nil;
	}
			
}


edit
Last edited on
You can simplify your setup and shuffling a lot:

To setup your basic deck, consider this:

The rank is sequence % 13, the suit is sequence / 13:

0 % 13 = 0 (rank zero), 0/13 = 0 (suit zero)
. . .
16 % 13 = 3 (rank three), 16/13 = 1 (suit 1)
. . .
51 % 13 = 12 (rank 12), 51/13 = 3 (suit 3)

so your ranks are 0 - 12, your suits are 0 - 3.

You can decide based on what you want, whether ace is zero or 12, depending on how you want to use it (low or high).

To shuffle, all you need to do is step one time, one-by-one, through your deck array, and use

1
2
for (i = 0; i < 52; i ++)
std::swap( card(i), card(rand() % 52);


(Make sure you srand(time(NULL)) somewhere early to initialize rand()

std::swap has a lot of overloads for a variety of data types; I've used it to swap vectors, int, char, etc. . .

Very handy for sorts, too, of course.
Last edited on
And if you do this:

char[][10] rank = {"Ace","Deuce","Trey","Four","Five","Six","Seven". . ."King"};
char[][10] suit = {"Spades","Diamonds","Hearts","Clubs"};

then:

struct card{ int suit; int rank; };

then create either a vector or array of cards:

card deck[52]; or
std::vector<card> deck;

if you run a setup like:

1
2
3
4
5
6
7
//for array

for (i = 0; i < 52; i++)
{ 
    deck[i].rank = i % 13;
    deck[i].suit = i/13;
}


or
1
2
3
4
5
6
7
8
9
// for vector

for (i = 0; 1 < 52; i++)
{
    card tcard;
    tcard.rank = i %13;
    tcard.suit = i/13;
    deck.push_back(tcard);
}

To display a given card [ n ]:

cout <<rank [ deck[n].rank ] << " of " suit[ deck[n].suit ] << endl;

thanks for the advice about the shuffling.

Do I do this part in the deck.cpp ? if yes, does this mean I no longer need the other class (card)?
{
char[][10] rank = {"Ace","Deuce","Trey","Four","Five","Six","Seven". . ."King"};
char[][10] suit = {"Spades","Diamonds","Hearts","Clubs"};

then:

struct card{ int suit; int rank; };
char[][10] rank = {"Ace","Deuce","Trey","Four","Five","Six","Seven". . ."King"};
char[][10] suit = {"Spades","Diamonds","Hearts","Clubs"};
then:
struct card{ int suit; int rank; };
}


And when i do : card deck[52];

does this mean the array is already full of card that i have to edit like that? :
deck[i].rank = i % 13;
deck[i].suit = i/13;
Last edited on
Do I do this part in the deck.cpp ? if yes, does this mean I no longer need the other class (card)?

In my view, I don't think a class declaration is needed for a card unless you intend to have it display front/back in a graphic presentation. If you do need this at a later point you can always create a class, and include the assigned values for suit and rank.

A deck class can create a deck of cards for itself in its constructor, it can have shuffle and deal methods. You need a destination for your deck / deal objects, so you create players, each owning either an array or a vector of cards. The players can evaluate their hands for comparison with the others, they can display their card values and accept/discard cards however you want to do it.

You can put the initialization anywhere you need it, providing it is available to the rest of your source code.

And when i do : card deck[52];

does this mean the array is already full of card that i have to edit like that? :
deck[i].rank = i % 13;
deck[i].suit = i/13;


1
2
3
4
5
6
card deck[52]; // creates one-dimension array of struct cards, all uninitialized.  
// The values of the members of the struct are undefined, so could be anything.

//To initialize them, you use 
deck[i].rank = i % 13;
deck[i].suit = i/13;


only once is needed, somewhere before you shuffle and deal

but if you create:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
class deck
{ card deck[52]

    deck() // constructor creates a deck of cards owned by object dealer when created.
   {
        for (int i = 0; i < 52;i ++)
        {
            deck[i].rank = i % 13;
            deck[i].suit = i/13;
        }
    }

    void shuffle()
    {
        // put the shuffle routine here
    }

    void deal(int players, int handsize)
    {
        // put some code here that fills the players' arrays or vectors, whichever you use
    }
}


Then you can create a dealer and let him have the fun.

1
2
3
4
5
6
7
8
int main()
{
    // whatever you need to initialize
    deck dealer
    { // play game
          dealer.shuffle
          dealer.deal(2,5)  //2 players, 5 cards. ..
    }
Last edited on
thanks for the explanation.

But I still have some question:

Do I have to do the struct card in my deck constructor (deck.cpp) ?

And why : char[][10] rank and char[][10] and not bi-dimensional array like char rank[10] and char suit [10]?

anyways thanks again, I will continue to work with the tips you gave me and post if I have further problems
Do I have to do the struct card in my deck constructor (deck.cpp) ?

I'm sure you could do that, but it can go in the preliminary header as well.

And why : char[][10] rank and char[][10] and not bi-dimensional array like char rank[10] and char suit [10]?


There are 13 ranks, filled by the = {"Deuce","Trey". . .etc.} The first index in the array is to the rank itself, the second index allows up to 9 char plus terminating zero for each string value

There are four suits, same thing - the designation[] leaves the first index open for the initialization with the contents of {"Spades","Diamonds","Hearts","Clubs"}

If, for example, your suits[][10] is declared:

constant char suits[][10]={"Spades","Diamonds","Hearts","Clubs"};

suits[0] will contain "Spades" plus /0 and three uninitialized bytes
suits[1] will contain "Diamonds" plus /0 and one uninitialized byte
so:

cout << suits[0] will display "Spades", and you do not use the second index.

If you did include this statement:

cout << suits[0][1] it would display only a "p" (second element of row 0 of array) And
cout << suits[0][7] would likely display nonsense, if anything. In row 0, element 7 is after the zero that ends "Spades", so is uninitialized.
so if I understand, it should gives something like that :

--0 1 2 3 4 5 6 7 8 9 10
0 A C E \0
1 D E U C E \0
2 T R E Y \0
3 ....
4
5
6
7
8
9
10
11
12 Q U E E N \0
13 K I N G \0

basically I had the same idea but I would have done something like that: char[0] = "Spades\0";
char[1] = "Heart\0";
...

I don't know if it possible but I will test it.
Thanks again, I will modify my program.
Last edited on
If you want to use only single-dimension array, do this:

1
2
3
4
5
6
7
8
#include <string>

string suits[4] = {"Spades","Diamonds","Hearts","Clubs"};
//and
string ranks[13] = {"Deuce","Trey",. . . ,"King","Ace"};

// access the members of suits and rank
// same as char version 
Last edited on
I have made the changes in the code and I still have a problem with creating the cards in the deck. It gives me an error that says multiple definition of rank and suit. I have also tried a lot of things and even my old way :
1
2
3
4
5
6
7
int y=1;
	
	for (int i=0; i = 12; i++){
		i=i;
		deck[i].suit="Heart";
		deck[i].rank=y;
		y++;


but it gives me an other error. I'm sure the error is in the struct or in the rank array and in the suit array but I don't know what it is.

thanks in advance

my header
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
#ifndef DECK_H
#define DECK_H
//#include "Card.h"

	char rank  [][10] = {"Ace","Deuce","Trey","Four","Five","Six",
	"Seven","Eight","Nine","Ten","Jack","Queen","King"};
	
	char suit [][10] = {"Spades","Diamonds","Hearts","Clubs"};
	

struct Card{ 
int suit; int rank; 
};

class Deck{
	
	private:
		Card deck [51];
		Card cards;
		int nextCard;
		
	public:
		//constructor
		Deck();
		
		void Shuffle();
		
		Card distribute();
		
		void displayCard(int);
};
#endif 



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
#include  <iostream>
//#include "Card.h"
#include "Deck.h"
#include <time.h>
#include <stdlib.h>  

Deck::Deck(){
	for (int k=0; k < 51; k++){	
	   deck[k].rank = k % 13;
       deck[k].suit = k/13;
	}
	
	/*
	 int y=1;
	
	for (int i=0; i = 12; i++){
		i=i;
		deck[i].suit="Heart";
		deck[i].rank=y;
		y++;
	}
	
	y=1;
	for (int i=13; i = 25; i++){
		deck[i].suit="Spade";
		deck[i].rank=y;
		y++;
	}
	y=1;
	
	for (int i=26; i = 38; i++){
		deck[i].suit="Club";
		deck[i].rank=y;
		y++;
	}
	y=1;
	
	for (int i=39; i < 51; i++){
		deck[i].suit="Heart";
		deck[i].rank=y;
		y++;
	}*/
	
}
 
void Deck::Shuffle(){

srand (time(NULL));

for(int i = 0; i < 52; i ++){
//	std::swap( deck(i), deck(rand() % 52);
}	

}

Card Deck::distribute(){
	if (nextCard >= 0 && nextCard <= 51){
		return deck[nextCard];
		nextCard++;
	}else{
		
		return deck[0];
	}
}

void Deck::displayCard(int d){
	 std::cout <<rank [ deck[d].rank ] << " of " << suit[ deck[d].suit ] << std::endl;
	 }
I have been using () for array indices for so long . . . Line 51, should work if the parentheses are replaced with []. deck[i],deck[rand() % 52]

Line 8 leaves the last card uninitialized; should be i < 52

Apart from that I can compile and this works:

1
2
3
4
5
6
7
8
9
int main()
{
	Deck dealer;
	dealer.Shuffle();
	for (int i= 0; i < 52; i++)
	dealer.displayCard(i);
	system("Pause");
	return 0;
}

I have corrected the lines 8 and 51 but it's still gives me "multiple definition of suit" and"multiple definition of rank".

when I remove
1
2
3
4
5
	char rank  [][10] = {"Ace","Deuce","Trey","Four","Five","Six",
	"Seven","Eight","Nine","Ten","Jack","Queen","King"};
	
	char suit [][10] = {"Spades","Diamonds","Hearts","Clubs"};
	


the error says that rank and suit are not declare.
Last edited on
Have you got your int main() { } code started yet? If so, maybe you have a definition there that you're overlooking?

Everything you've got here compiled normally again here, after making those two corrections. . .
Last edited on
no, I haven't start the int main.
Well, you only define suit and rank two places; once in the declaration of suit [][10], the other in the struct declaration as far as I can see.

Maybe your compiler doesn't like that for some reason? You could try changing the variable name of one location to suits/ranks? I don't know why it should matter. . .
I finally found what was the error, I have remove this segment from the header file,
1
2
3
char rank  [][10] = {"Ace","Deuce","Trey","Four","Five","Six",
	"Seven","Eight","Nine","Ten","Jack","Queen","King"};	
	char suit [][10] = {"Spades","Diamonds","Hearts","Clubs"};

and put it in the constructor.

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
#include  <iostream>
//#include "Card.h"
#include "Deck.h"
#include <time.h>
#include <stdlib.h>  

Deck::Deck(){
	
	char rank  [][10] = {"Ace","Deuce","Trey","Four","Five","Six",
	"Seven","Eight","Nine","Ten","Jack","Queen","King"};
	
	char suit [][10] = {"Spades","Diamonds","Hearts","Clubs"};

	
	for (int k=0; k < 52; k++){	
	   deck[k].rank = k % 13;
       deck[k].suit = k/13;
	}

	
	/*
	 int y=1;
	
	for (int i=0; i = 12; i++){
		i=i;
		deck[i].suit="Heart";
		deck[i].rank=y;
		y++;
	}
	
	y=1;
	for (int i=13; i = 25; i++){
		deck[i].suit="Spade";
		deck[i].rank=y;
		y++;
	}
	y=1;
	
	for (int i=26; i = 38; i++){
		deck[i].suit="Club";
		deck[i].rank=y;
		y++;
	}
	y=1;
	
	for (int i=39; i < 51; i++){
		deck[i].suit="Heart";
		deck[i].rank=y;
		y++;
	}
	*/
}
 


now I have to understand why it wasn't working...

Thanks a lot PCrumley48 lot for the help and the tips you gave me.
Last edited on
As long as objects created from the class remain responsible to display the cards, you're fine, but I don't know why it wouldn't work in your header file. In Visual Studio 2012 Express I did put it into the deck.h file and it compiled just fine.
Topic archived. No new replies allowed.