Arrays in classes

Hey,

I am getting some unexpected errors in my code, I am wondering if the following is legal;

class information{
public:
string hole_cards[4];
};

information player[9];

int main(){
player[0].hole_cards[0] = "Ace";
}

I am trying to assign 'cards' to 'players' in a for loop inside a function.
But it freezes up when I try to use two for loops. Basically it just behaves really unexpectedly.

Also I have to use;
for(int j = 1; j <= 9; j++){
cout << player[j].hole_cards[0] << player[j].hole_cards[1] << " ";
}

Notice that j is set to 1, rather than 0 as expected. When I put 0, the program crashes at runtime. player[9] does not exist, but the above for loop gets it with no problems.

What is going on here?

Thanks for taking a look
What's the purpose for using the class for only one member? I'd suggest creating the class so that it does everything for you, then make a player class that have hands. Try writing what you want your code to do down on paper. I find it helps me a lot when I'm stuck.
The class will be used for a lot more than what I have stated. The code I wrote above is for simplicity and clarity for the readers.

The arrays don't seem to work how I want.

Am I referencing them correctly?
This is my complete code if it helps:

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<cstdlib>
#include <string>
#include <ctime>
#define PLAYERS 9
using namespace std;

//create information class which stores player's chip count, hole cards, position etc
class information{
    public:
    string hole_cards[4];
};

information player[PLAYERS]; //set number of players
int RNG(int n); //random number generator

string suits[4] = {"s", "c", "d", "h"}; //use to give a card suit
string ranks[13] = {"A", "2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K"}; //use to give a card rank

bool card_drawn[52];
int cards_remaining = 52;
int select_available_card(int card);

void deal_hole_cards(void);

int main(){
    srand(time(NULL)); //set seed for randomizing

    deal_hole_cards();

    for(int j = 1; j <= PLAYERS; j++){
        cout << player[j].hole_cards[0] << player[j].hole_cards[1] << " ";
    }

    system("PAUSE");
    return 0;
}

int RNG(int n) {
    return rand() % n;
}

void deal_hole_cards(void){
    int card, r, s, k;
    int i = 0;
    k = i + 1;
        for(int j = 1; j <= PLAYERS; j++){
            card = select_available_card(RNG(cards_remaining--)); //get a random card, based on cards left
            r = card % 13;
            s = card / 13;
            player[j].hole_cards[i] = ranks[r]; //set players hole_cards using the information class
            player[j].hole_cards[k] = suits[s];
        }
}

int select_available_card(int card){
    int i = -1;
    card++;

    while(card-->0){
        i++; //go to next card as we have counted one card off
        while(card_drawn[i]){
            i++; //if current card has already been drawn skip to next card
        }
    }
    card_drawn[i] = true; //set card selected to be shown as drawn
    return i;
}


This program runs pretty much the way I want it too, apart from every so often it gives 'player 9' the same rank card twice rather than rank and suit. i.e instead of 6s or 5c, the player gets 66 or 99. This only happens with the last player.

I would appreciate any help right now
Last edited on
Array indexes starts at zero so player[0] is the first element and player[8] is the last element in the player array. You need to change you loops from for(int j = 1; j <= PLAYERS; j++) to for(int j = 0; j < PLAYERS; j++).
Your issue resides in the deal hole cards function. anytime you use indexs, they should start at 0 and move up to the max size, but never reach, or exceed, the max size.

Your code:
1
2
3
4
5
6
7
8
9
10
11
12
void deal_hole_cards(void){
    int card, r, s, k;
    int i = 0;
    k = i + 1;
        for(int j = 1; j <= PLAYERS; j++){
            card = select_available_card(RNG(cards_remaining--)); //get a random card, based on cards left
            r = card % 13;
            s = card / 13;
            player[j].hole_cards[i] = ranks[r]; //set players hole_cards using the information class
            player[j].hole_cards[k] = suits[s];
        }
}


Should be:
1
2
3
4
5
6
7
8
9
10
11
12
void deal_hole_cards(void){
    int card, r, s, k;
    int i = 0;
    k = 0;
        for(int j = 0; j < PLAYERS; j++){
            card = select_available_card(RNG(cards_remaining--)); //get a random card, based on cards left
            r = card % 13;
            s = card / 13;
            player[j].hole_cards[i] = ranks[r]; //set players hole_cards using the information class
            player[j].hole_cards[k] = suits[s];
        }
}


If you still get an error, I believe it would be related to another one of your functions. Trying to read through your code is hard since I don't know what each one letter variable is for.
Yeah, that was one of my questions. When I set it to what it should be; for(int j = 0; j < PLAYERS; j++) then it does not work, the system crashes. When I set it to for(int j = 1; j <= PLAYERS; j++) then every player gets cards, but occassionally (and randomly) the last player gets the same rank twice rather than a suit.

What is going on?
Have now just changed it back to for(int j = 0; j < PLAYERS; j++) for the millionth time and somehow it now works.

It must have been something else which was causing the crash, rather than my code. Weird.

Thanks for all the replies though guys. I have only just joined the site, but I am sure I will be posting a lot more questions. So I appreciate all the help

Andy
Maybe making a card class and a deck class will help you understand better. I think it's bad practice to store an array as so:

array[0] = rank
array[1] = suit
array[n-1] = rank
array[n] = suit

You could also number the cards numerically. 0 = Ace of Spades, 13 = Ace of Hearts, 26 = Ace of Clubs, 39 = Ace of Diamonds

Then do a cardNumber / 13 to get the suit and cardNumber % 13 to get the value. I see that you do that in your function to seperate the values, but I think that's counter intuitive.
I don't entirely understand your suggestion. If you have the time, could you please expand upon what you mean by a deck class and card class. Also, why would storing it as so be bad practice.

The cards are technically numbered numerically, bool card_drawn[52] is effectively the deck. The numbers in this array correspond to your suggestion. Is this what you mean?

I am more than willing to implement more efficient programming, but I don't understand (only been using c++ for a month).
A quick example would be:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
struct Card{
   public:
      Card() : // Default Constructor
         suit(0), // Set's suit to Spades
         value(0) {} // Set's value to Ace
      Card(int cardVal) : // Handle value Seperation Constructor
         suit(cardVal / 13), // Set's suit to cardVal's suit
         value(cardVal % 13) {} // Set's value to cardVal's value
      Card(int suitVal; int valueVal) : // Two parameter Constructor
         suit(suitVal), // Set's suit to suitVal
         value(valueVal) {} // Set's value to valueVal
      int suit;
      int value;
}

class Deck{
   // ...
}


I don't have the time to type up the Deck class, but it's fairly straight forward, it should hold 52 cards, and they can be in order. You could make a function to shuffle the deck, pop a card off the deck, or whatever else. The way I looked at it is that my classes should do all the heavy lifting and keep my main as clean as possible.

When someone looks at your code and sees that it's nice looking, they will assume that your classes are working well. And if someone wants to jump deeper into your classes, they'll be impressed by your work. I'm sorry I couldn't write the classes for you, but maybe I can get some time later or someone will have a card/deck class already typed up for you that they can share.
When I set it to for(int j = 1; j <= PLAYERS; j++) then every player gets cards, but occassionally (and randomly) the last player gets the same rank twice rather than a suit.
That's easy. Accessing out of bounds causes undefined behaviour.
Don't do it.

When I set it to what it should be; for(int j = 0; j < PLAYERS; j++) then it does not work, the system crashes
Can't reproduce it.
Run through a debugger, perform a backtrace.
Hey Volatile Pulse,

Thanks dude, I am not really sure I fully understand the beauty of classes yet.

Your example definitely helps as well, I see what you mean. I will try to implement it.

Don't worry about the deck class, thank you for writing up the card class to give me a clearer insight.

Andy
Topic archived. No new replies allowed.