Cards Program Crashing

Hi! So, I've written a cards program, written and compiled in Dev-C++ 4.9.9.2. It defines a class "card", a class "hand"- which includes an array of "card"s- and a class "player", which includes a hand, "PlayerHand". Then there are certain functions for things like containing the Pack- "Pack"- shuffles the pack- "ShufflePack()" and also an array to include all the players- "Table[]". Everything works thus far, except the function Deal()- which assigns a certain number of cards to each player in "Table[]"- when called, makes the program crash. I can't see anything wrong with it. Here's the code:
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
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
#include <iostream>
#include <windows.h>
#include <conio.h>
#include <string>
using namespace std;

VOID WINAPI Sleep(DWORD dwMilliseconds);

#define TableSize 5
#define HandSize 2

char SuitNameOptions[] = { 'H', 'D', 'C', 'S' };
char ValueNameOptions[] = { 'A', '2', '3', '4', '5', '6', '7', '8', '9', 'T', 'J', 'Q', 'K' };
string CardName1Options[] = { "Ace", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine", "Ten", "Jack", "Queen", "King" };
string CardName2Options[] = { " of Hearts", " of Diamonds", " of Clubs", " of Spades" };
int ValueOptions[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13 };
int SuitOptions[] = { 1, 2, 3, 4 };

class card {
      public:
             char ValueName, SuitName;
             //eg A, 2, 3... eg H, C, D
             int Value, Suit;
             //eg 1, 2, 3... eg 1, 2, 3
             string CardName;
             //eg "Ace of Hearts"
             int PosInPack;
             };

class hand {
      public:
             card CardsInHand[HandSize];
             };

class player {
      public:
             int pos;
             hand PlayerHand;
             };

card Pack[4][13];

void create_pack() {
     for (int i = 0; i < 4; i++) {
         for (int j = 0; j < 13; j++) {
             Pack[i][j].SuitName = SuitNameOptions[i];
             Pack[i][j].Suit = SuitOptions[i];
             Pack[i][j].ValueName = ValueNameOptions[j];
             Pack[i][j].Value = ValueOptions[j];
             Pack[i][j].CardName = CardName1Options[Pack[i][j].Value-1] + CardName2Options[Pack[i][j].Suit-1];
             Pack[i][j].PosInPack = (j+1)+13*(i);
             }
             }
             }

card PackList[52];
void create_packlist() {
         for (int j = 0; j < 4; j++) {
             for (int k = 0; k < 13; k++) {
                 PackList[(j*13)+k] = Pack[j][k];
                 }
                 }
                 }

player Table[TableSize-1];

void create_table() {
     for (int a = 0; a < TableSize; a++) {
         Table[a].pos = a;
         }
     }

void Deal() {
     for (int a = 0; a < HandSize; a++) {
         for (int b = 0; b < TableSize; b++) {
             int c = b+1+a*3;
             Table[b].PlayerHand.CardsInHand[a] = PackList[c];
             }
             }
             }

void OutputCardArray(card a[], int len) {
     for (int i = 0; i < len; i++) {
         cout << a[i].CardName;
         cout << endl;
         }
         }

void OutputPackList() {
     OutputCardArray(PackList, 52);
     }

void shuffleElements(card theArr[], int length) {
     for (int last = length; last > 1; last--) {
         int randomNum = rand()%last;
         card temp = theArr[randomNum];
         theArr[randomNum] = theArr[last-1];
         theArr[last-1] = temp;
         // Chooses a random card in the array and swaps it with the last, then the next one with the second-last, etc.
         }
         }

void shuffleCards(card arrPack[]) {
     for (int a = 0; a < 52; a++) {
         int randNum = rand()%52;
         card Temp = arrPack[a];
         arrPack[a] = arrPack[randNum];
         arrPack[randNum] = Temp;
         /* Swaps each card with a random one - each card could be swapped with itself;
         or twice, back to its original position, but this can happen in real life. */
         }
         }


void ShufflePack() {
     shuffleElements(PackList, 52);
     shuffleCards(PackList);
     shuffleElements(PackList, 52);
     shuffleCards(PackList);
     shuffleElements(PackList, 52);
     shuffleCards(PackList);
     }

void init() {
     create_pack();
     create_packlist();
     create_table();
     }

int main() {
    init();
    ShufflePack();
    cout << endl;
    Deal();
    OutputPackList();
    getch();
    return 0;
}


I get this:

Ace of Hearts
Two of Hearts
Three of Hearts
Four of Hearts
Five of Hearts
Six of Hearts
Seven of Hearts
Eight of Hearts
Nine of Hearts
Ten of Hearts
Jack of Hearts
Queen of Hearts
King of Hearts
Ace of Diamonds
Two of Diamonds
Three of Diamonds
Four of Diamonds
Five of Diamonds
Six of Diamonds
Seven of Diamonds
Eight of Diamonds
Nine of Diamonds
Ten of Diamonds
Jack of Diamonds
Queen of Diamonds
King of Diamonds
Ace of Clubs
Two of Clubs
Three of Clubs
Four of Clubs
Five of Clubs
Six of Clubs
Seven of Clubs
Eight of Clubs
Nine of Clubs
Ten of Clubs
Jack of Clubs
Queen of Clubs
King of Clubs
Ace of Spades
Two of Spades
Three of Spades
Four of Spades
Five of Spades
Six of Spades
Seven of Spades
Eight of Spades
Nine of Spades
Ten of Spades
Jack of Spades
Queen of Spades
King of Spades



And then the program crashes.
Thanks for any answers in advance!

intint50
closed account (DSLq5Di1)
intint50 wrote:
Everything works thus far, except the function Deal()
1
2
3
4
5
6
7
8
void Deal() {
     for (int a = 0; a < HandSize; a++) {
         for (int b = 0; b < TableSize; b++) {
             int c = b+1+a*3;
             Table[b].PlayerHand.CardsInHand[a] = PackList[c];
             }
             }
             }
Set a breakpoint on the bold line above and watch the value of c, ensure it is not accessing elements out of bounds.
Thanks very much for the very quick and very accurate reply! Deal() works fine now, although I realised it was meant to be
int c = b+a*TableSize;
For those of you who wanted to know!
But thanks sloppy9, I've spent ages trying to work out what was wrong!
-intint50
Hi! Sorry to be a pain in the neck, but, noob as I am, I've yet another problem:

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
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
#include <iostream>
#include <windows.h>
#include <conio.h>
#include <string>
using namespace std;

VOID WINAPI Sleep(DWORD dwMilliseconds);

#define TableSize 5
#define HandSize 2

char SuitNameOptions[] = { 'H', 'D', 'C', 'S' };
char ValueNameOptions[] = { 'A', '2', '3', '4', '5', '6', '7', '8', '9', 'T', 'J', 'Q', 'K' };
string CardName1Options[] = { "Ace", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine", "Ten", "Jack", "Queen", "King" };
string CardName2Options[] = { " of Hearts", " of Diamonds", " of Clubs", " of Spades" };
int ValueOptions[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13 };
int SuitOptions[] = { 1, 2, 3, 4 };

class card {
      public:
             char ValueName, SuitName;
             //eg A, 2, 3... eg H, C, D
             int Value, Suit;
             //eg 1, 2, 3... eg 1, 2, 3
             string CardName;
             //eg "Ace of Hearts"
             int PosInPack;
             };

class hand {
      public:
             card CardsInHand[HandSize];
             };

class player {
      public:
             int pos;
             hand PlayerHand;
             };

card Pack[4][13];

void create_pack() {
     for (int i = 0; i < 4; i++) {
         for (int j = 0; j < 13; j++) {
             Pack[i][j].SuitName = SuitNameOptions[i];
             Pack[i][j].Suit = SuitOptions[i];
             Pack[i][j].ValueName = ValueNameOptions[j];
             Pack[i][j].Value = ValueOptions[j];
             Pack[i][j].CardName = CardName1Options[Pack[i][j].Value-1] + CardName2Options[Pack[i][j].Suit-1];
             Pack[i][j].PosInPack = (j+1)+13*(i);
             }
             }
             }

card PackList[52];
void create_packlist() {
         for (int j = 0; j < 4; j++) {
             for (int k = 0; k < 13; k++) {
                 PackList[(j*13)+k] = Pack[j][k];
                 }
                 }
                 }

player Table[TableSize-1];

void create_table() {
     for (int a = 0; a < TableSize; a++) {
         Table[a].pos = a;
         }
     }

void Deal() {
     for (int a = 0; a < HandSize; a++) {
         for (int b = 0; b < TableSize; b++) {
             int c = b+a*TableSize;
             Table[b].PlayerHand.CardsInHand[a] = PackList[c];
             break;
             }
             }
             }

void OutputCardArray(card a[], int len) {
     for (int i = 0; i < len; i++) {
         cout << a[i].CardName;
         cout << endl;
         }
         }

void OutputPackList() {
     OutputCardArray(PackList, 52);
     }

void shuffleElements(card theArr[], int length) {
     for (int last = length; last > 1; last--) {
         int randomNum = rand()%last;
         card temp = theArr[randomNum];
         theArr[randomNum] = theArr[last-1];
         theArr[last-1] = temp;
         // Chooses a random card in the array and swaps it with the last, then the next one with the second-last, etc.
         }
         }

void shuffleCards(card arrPack[]) {
     for (int a = 0; a < 52; a++) {
         int randNum = rand()%52;
         card Temp = arrPack[a];
         arrPack[a] = arrPack[randNum];
         arrPack[randNum] = Temp;
         /* Swaps each card with a random one - each card could be swapped with itself;
         or twice, back to its original position, but this can happen in real life. */
         }
         }
         
void ShowCards() {
     for (int i = 0; i < TableSize; i++) {
         cout << "Player " << i+1 << ":\n";
         for (int j = 0; j < HandSize; j++) {
             cout << Table[i].PlayerHand.CardsInHand[j].CardName << endl;
             }
     cout << endl;
     }
     }



void ShufflePack() {
     srand(time(0));
     shuffleElements(PackList, 52);
     shuffleCards(PackList);
     shuffleElements(PackList, 52);
     shuffleCards(PackList);
     shuffleElements(PackList, 52);
     shuffleCards(PackList);
     }

void init() {
     create_pack();
     create_packlist();
     create_table();
     }

int main() {
    init();
    ShufflePack();
    Deal();
    ShowCards();
    getch();
    return 0;
}


ShowCards() doesn't work. Not sure why, I get this output:

Player 1:
Ten of Clubs
Four of Spades

Player 2:



Player 3:



Player 4:



Player 5:



Then it crashes. Thanks in advance.

-intint50
closed account (DSLq5Di1)
1
2
3
4
5
6
7
8
9
10
11
12
player Table[TableSize-1]; // Screwing up your bounds checking.
...

void Deal() {
     for (int a = 0; a < HandSize; a++) {
         for (int b = 0; b < TableSize; b++) {
             int c = b+a*TableSize;
             Table[b].PlayerHand.CardsInHand[a] = PackList[c];
             break; // First player is dealt cards then you.. break from the loop?
             }
             }
             }

VOID WINAPI Sleep(DWORD dwMilliseconds); // Just include the Windows header.

1
2
#define TableSize 5 // Dont use the preprocessor for constants.
const int TableSize = 5;

Thanks for the reply. Sorry, I though when you said
Set a breakpoint on the bold line above
you meant put a break statement after it. What did you mean? When I don't include the break; statement, Deal() crashes. changing #define TableSize 5 to const int TableSize = 5; didn't make a difference either. Any ideas?
-intint50
closed account (DSLq5Di1)
Ah, no worries.. I meant a debugging breakpoint so you could step through each loop and see what is happening. This is your error:-

1
2
3
4
5
6
7
8
9
10
11
12
13
const int TableSize = 5;
...

player Table[TableSize-1]; // Table is now an array of 4 elements.. [0, 1, 2, 3]
...

for (int b = 0; b < TableSize; b++) { // TableSize = 5.

// 1st loop: 0 < 5; Table[0] // first element
// 2nd loop: 1 < 5; Table[1] // 2nd element
// 3rd loop: 2 < 5; Table[2] // 3rd element
// 4th loop: 3 < 5; Table[3] // 4th and last element!
// 5th loop: 4 < 5; Table[4] // Error! out of bounds. 

Long story short, drop the -1. ^^
Thanks so much! Of course, haha that was really stupid!! Brilliant, time to start writing a game!

-intint50
Topic archived. No new replies allowed.