Card game template

Pages: 12
i have a project to create a deck of cards in a class (store them in an array) so i can use them later to create different card games, the class, i have been told, is right by my programming tutor, however i seem to have problems assigning the values to each card in the array.

the last for loop is just to see if they print and have stored ok.

here is what i have:

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
79
80
81
82
#include <iostream>

using namespace std;

class Card
{
    private: string suit; int value;

    public:
            Card(int v, string s)
            {
                value = v;
                suit = s;
            }

            int getvalue()
            {
                return value;
            }

            string getsuit()
            {
                return suit;
            }
};

int main()
{
    int n,i,j;
    string b;
    Card c [52];

    for(j = 0; j < 52; j++)
    {
            Card card (i, b);
            c[j] = card;
        for(n = 0; n < 4; n++)
        {

            switch (n)
            {
                case 1: b = "Hearts";
                break;

                case 2: b = "Spades";
                break;

                case 3: b = "Diamonds";
                break;

                case 4: b = "Clubs";
                break;
            };

                for(i = 0; i < 13; i++)
                {

                }
        }
    }

    for(j = 0; j < 52; j++)
    {
        switch (c[j].getvalue)
        {
            case 1: cout << " Ace";
            break;

            case 11: cout << " Jack";
            break;

            case 12: cout << " Queen";
            break;

            case 13: cout << " King";
            break;

            default: c.getvalue;
        }
        cout << " of " << c[j].getsuit;
    } return 0;
}
Think about what you need to do. You need 13 cards or each suit. So the loop that selects the card value should go from 1 to 13 (or 0 to 12). Then for each iteration of that loop you need another loop selecting each suit for the current value.
1
2
3
4
5
6
7
for(int c = 0; c < 13; ++c) // select card value
{
    for(int s = 0; s < 4; ++s) // select suit
    {
        // now make a Card using the values c and s
    }
}
i already have that part implemented (just the other way around) the problem is making c and s (as you put it) into the array
Well you can solve that a few ways. One is to have an independent counter for the array that you increment after you add each card.
well i have very basic knowledge, reading through my code looks like it sound make sense, but i get errors on line 31 saying it cant call to my constructive function in the class
Can you post the code?

The problem is that your class Card does not have a default constructor which is needed to create an array:
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
class Card
{
    private: string suit; int value;

    public:
            Card() // default constructor (no arguments) allows you to make an array
            {
                value = 0;
            }

            Card(int v, string s)
            {
                value = v;
                suit = s;
            }

            int getvalue()
            {
                return value;
            }

            string getsuit()
            {
                return suit;
            }
};
Last edited on
i dont understand how that makes a difference, wouldn't have two constuctors confuse the program?
Last edited on
so how would the values be implemented? would i need another identifier?
When you create an array there is no way to specify which values to give to the constructor. That is why you need to make a constructor that doesn't take any values.

The compiler is not confused. If you supply values then it will use the constructor that asks for arguments. If you don't supply values (like when you make an array) then the constructor without values is used.
When you make the array the values will have no meaning. It is only when you make a new card (with values) and copy that card into an element of the array that the card in the array gets proper values.
so like on my code in line 35?
i cant seem to make the temporary card in the for loop to equal the c[j] array

this is my int main now:

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
int main()
{
    int n,i,j;
    string b;
    Card c [52];

    for(j = 0; j < 52; j++)
    {
            Card card (i, b);

        for(n = 0; n < 4; n++)
        {

            switch (n)
            {
                case 1: b = "Hearts";
                break;

                case 2: b = "Spades";
                break;

                case 3: b = "Diamonds";
                break;

                case 4: b = "Clubs";
                break;
            };

                for(i = 0; i < 13; i++)
                {
                    c[j] = card;
                }
        }
    }

    for(j = 0; j < 52; j++)
    {
        switch (c[j].getvalue)
        {
            case 1: cout << " Ace";
            break;

            case 11: cout << " Jack";
            break;

            case 12: cout << " Queen";
            break;

            case 13: cout << " King";
            break;

            default: c.getvalue;
        }
        cout << " of " << c[j].getsuit;
    }
}
ok, nearly finished, only one problem now, it doesn't reccognise c[j].getvalue as an integer on line 70.

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
79
80
81
82
83
84
85
86
87
88
89
#include <iostream>
#include <string>
using namespace std;

 class Card
{
    private: string suit; int value;

    public:
            Card()//default constructor (no arguments) allows you to make an
            {     //array
                value = 0;
            }

            Card(int v, string s)
            {
                value = v;
                suit = s;
            }

            int getvalue()
            {
                return value;
            }

            string getsuit()
            {
                return suit;
            }
};


int main()
{
    int n,i,j;
    string b;
    Card c[52];

    for(j = 0; j < 52; j++)
    {
            Card card (i, b);

        for(n = 0; n < 4; n++)
        {

            switch (n)
            {
                case 1: b = "Hearts";
                break;

                case 2: b = "Spades";
                break;

                case 3: b = "Diamonds";
                break;

                case 4: b = "Clubs";
                break;
            };

                for(i = 0; i < 13; i++)
                {
                    c[j] = card;
                }
        }
    }

    for(j = 0; j < 52; j++)
    {
        switch (c[j].getvalue)
        {
            case 1: cout << " Ace";
            break;

            case 11: cout << " Jack";
            break;

            case 12: cout << " Queen";
            break;

            case 13: cout << " King";
            break;

            default: c.getvalue;
        }
        cout << " of " << c[j].getsuit;
    }
}
Last edited on
needs to be c[j].getvalue()
now for some reason it compiles, but just repeats the 'king of diamonds' over and over
I think that's because you create your card outside the loop that set's its values. Also your outside loop j resets the entire pack over and over again 52 times. You don't need that outer loop. All you need is a variable j that you set to 0 before your two loops and increment it every time you add a new card.
Last edited on
closed account (o1vk4iN6)
1
2
3
4
for(i = 0; i < 13; i++)
                {
                    c[j] = card;
                }


line 61.

You assign the same card multiple times.


I find something like this a bit cleaner than what you have. It is easy to see what it is doing and is only ~10 lines.
1
2
3
4
5
6
7
8
9
10

for(int i = 0; i < 52; i++){
    switch( i / 12 ){
        case 0: cards[i] = Card(i % 12, "Hearts"); break;
        case 1: cards[i] = Card(i % 12, "Clubs"); break;
        case 2: cards[i] = Card(i % 12, "Spade"); break;
        case 3: cards[i] = Card(i % 12, "Diamond"); break;
        default: cerr << "undefined behavior\n"; break;
   }
}


Also rather than having the type as a string, you can create an enum:

1
2
3
4
5
6
enum card_type {
   ACE,
   SPADE,
   HEART,
   DIAMOND
};


Than for your get function:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

class Card {
    card_type suit;
    
    const char* getsuit()
    {
          switch(suit){
              case ACE: return "Ace";
              case HEART: return "Heart";
              case DIAMOND: return "Diamond";
              case SPADE: return "Spades";
          }
          return "Undefined";
     }
};


This will be memory efficient compared to your other class, since you will be storing the string each time in memory for each card. With the above method the string is only stored in memory once, you could probably even do something a bit fancier with inheritence.

1
2
3
4
5
6
7
8
9
10

class BaseCard {
    virtual const char* getsuit() = 0;
};

class SpadeCard : public BaseCard {
    const char* getsuit(){ return "Spade"; }
};

//same for heart, diamond, clubs... 
Last edited on
Galik- After looking at my code, yes i can see where you are coming from about the j for loop resetting the pack, would it be something like this instead:

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
   for(n = 0; n < 4; n++)
        {
            Card card (i, b);

            switch (n)
            {
                case 1: b = "Hearts";
                break;

                case 2: b = "Spades";
                break;

                case 3: b = "Diamonds";
                break;

                case 4: b = "Clubs";
                break;
            };

                if (i < 13)
                {
                    ++i;
                }
                c[j] = card;
                ++j;
        }





xerzi- thank you for putting in time to help me, i really appreciate it, however i am relatively new to c++ and dont know what 'enum' is, i dont want to include anything fancy because i want to be able to understand it.
I can still see some problems with your code. You create your card before you set the suit, but you need to create it after you set the suit. Also your variable i is going to stick on 12.

Take another look at the loop I showed you, I've added some extra bits:
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
int i = 0; // index into array

for(int c = 1; c < 14; ++c) // select card value
{
	for(int s = 0; s < 4; ++s) // select suit
	{
		// now make a Card using the values c and s
		std::string suit;

		switch(s)
		{
			case 0: suit = "Hearts";
			break;

			case 1: suit = "Spades";
			break;

			case 2: suit = "Diamonds";
			break;

			case 3: suit = "Clubs";
			break;
		};

		c[i] = Card(c, suit);

		++i; // ready for next position in the array
	}
}

Note here we have two for() loops. The inner for() loop with execute entirely for every iteration of the outer for() loop. That means for every card value, we will loop through the different suits creating a card for each one.

Last edited on
i need the cards stored in order though i.e. ace of hearts, 2 of hearts....king of hearts, ace of spades ect, reading this seems it will store it; ace of hearts, ace of spades etc.
Pages: 12