Need Help With ptr** Because Im Going Crazy!!

closed account (37oyvCM9)
Hi Everyone,

newbie here, right I am trying to make a poker game....and I have a deck class and I want to transfer my array of community and hole cards over to my player class so I can start checking hand values etc.

Everything I have tried is just giving me a nightmare...pass by ref, returning pointer the list goes on trust me lol.

I thought if I popped my code up here I could get some much needed advice before my head spontaneously com-bust's(literal stack overflow)!

Yes my code is terrible, yes I should comment more, yes there are alot of things that code be improved but Im just a newbie and am trying to sort out all my bad habits.

Thanks in advance for some much needed advice!

Deck.cpp
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
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
 #include "Deck.h"



//Construct deck from 52 cards
Deck::Deck()
{
	//Loop through suits array
	for (int numSuits = 0; numSuits < SUITS; numSuits++)
	{
		//Loop through faces array for every item in suits array
		for (int numFaces = 0; numFaces < FACES; numFaces++)
		{
			//For every iteration call card constructor and pass in values
			//Items being created on heap so have to be pointers
			Card* card = new Card((Face)(numFaces + 1), (Suit)(numSuits + 1));
			
			//Save pointer of card into _deck array and increment counter
			p_deck[_numCardCounter] = card;
			//Assign values to vector deck
			p_vecDeck.push_back(p_deck[_numCardCounter]);
			//increment counter
			_numCardCounter++;
		}
	}
	//Shuffle deck
	shuffleDeck();
	delete[]p_deck; //by deleting this am I deleting above as well being that they're stored in the array
}


//Depending on what turn it is deal the correct amount of cards
void Deck::dealCommunityCards(short turn)
{
	//Cast turn to type communityCards and check value
	switch ((CommunityCards)turn)
	{
	case CommunityCards::FLOP:
		for (int i = 0; i < NUM_FLOP_CARDS; i++)
		{
			//If equals FLOP then set first 3 elements of communityCards[] to the last three values of the vecDeck
			p_communityCards[i] = p_vecDeck.back();
			//Get rid of the last 3 elements of vecDeck
			p_vecDeck.pop_back();
		}
		break;
	case CommunityCards::TURN:
		//If equals TURN set element 4 of communityCards[] to the last element of vecDeck
		p_communityCards[3] = p_vecDeck.back();
		//Get rid of last element of vecDeck
		p_vecDeck.pop_back();
		break;
	case CommunityCards::RIVER:
		//If equals RIVER set element 5 of communityCards to the last element of vecDeck
		p_communityCards[4] = p_vecDeck.back();
		//Get rid of last element of vecDeck
		p_vecDeck.pop_back();
		break;
	default:
		std::cout << "There was a problem storing vecDeck into community Cards" << std::endl;
		break;
	}
}
//Print community cards
void Deck::printCommunityCards(short turn)
{
	std::cout << "COMMUNITY CARDS: | ";
	//Loop through cards on table 
	for (int i = 0; i < turn; i++)
	{
		//Store each element into temp Card variable
		Card* card = p_communityCards[i];
		//Print the card using GetFace and GetSuit from Card.h
		std::cout << card->GetFaceName() << " of " << card->GetSuitName() << " | ";
	}
	std::cout << std::endl;
}

//Depending on how many players in hand deals the relative number of cards
void Deck::dealHoleCards(short numOfPlayers)
{
	switch (numOfPlayers)
	{
	case 1:
		for (int i = 0; i < 2; i++)
		{
			p_holeCards[i] = p_vecDeck.back();
			p_vecDeck.pop_back();
		}
		break;
	case 2:
		for (int i = 0; i < 4; i++)
		{
			p_holeCards[i] = p_vecDeck.back();
			p_vecDeck.pop_back();
		}
		break;
	case 3:
		for (int i = 0; i < 6; i++)
		{
			p_holeCards[i] = p_vecDeck.back();
			p_vecDeck.pop_back();
		}
		break;
	case 4:
		for (int i = 0; i < 8; i++)
		{
			p_holeCards[i] = p_vecDeck.back();
			p_vecDeck.pop_back();
		}
		break;
	case 5:
		for (int i = 0; i < 10; i++)
		{
			p_holeCards[i] = p_vecDeck.back();
			p_vecDeck.pop_back();
		}
		break;
	case 6:
		for (int i = 0; i < 12; i++)
		{
			p_holeCards[i] = p_vecDeck.back();
			p_vecDeck.pop_back();
		}
		break;
	default:
		std::cout << "there was a problem dealing hole cards" << std::endl;
		break;
	}
}
//Print hole Cards
void Deck::printHoleCards(short numPlayers)
{
	std::cout << "HOLE CARDS: | ";
	//Loop through cards
	for (int i = 0; i < (numPlayers * 2); i++)
	{
		//Store each element into temp Card variable
		Card* card = p_holeCards[i];
		//Print the card using GetFace and GetSuit from Card.h
		std::cout << card->GetFaceName() << " of " << card->GetSuitName() << " | ";
	}
	std::cout << std::endl;
}

//Combine community cards and holeCards into an array to check values
void Deck::combineComHole(short holeCards, short turn)
{
	
	//Loop through community cards and store in combinedCards array
	for (int i = 0; i < turn; i++) 
	{
		p_combinedCards[i] = p_communityCards[i];
	}
	//Loop through holeCards and add to combinedCards array
	for (int j = turn; j < (turn + holeCards); j++)
	{
		p_combinedCards[j] = p_holeCards[j - turn];
	}
}

//Clear VecDeck for next hand
void Deck::clearVecDeck(short holeCards, short turn)
{
	//clear vector ready for next hand
	for (unsigned int i = 0; i < NUM_CARDS_IN_DECK - (holeCards + turn); i++)
	{
		p_vecDeck.pop_back();
	}

}

Deck::~Deck()
{
	
}

deck.h
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
#pragma once
#include <algorithm>
#include <vector>
#include "Card.h"
#include "Enums.h"

class Deck
{

public:
	Deck();
	~Deck();

	void printCommunityCards(short turn);
	void dealCommunityCards(short turn);
	void dealHoleCards(short numOfPlayers);
	void printHoleCards(short numPlayers);
	void combineComHole(short holeCards, short turn);
	void clearVecDeck(short holeCards, short turn);

	//getters
	Card getCombinedCards() { return **p_combinedCards; };

private:
	//Functions
	void shuffleDeck() { std::random_shuffle(p_vecDeck.begin(), p_vecDeck.end()); }

    //Constants
	const static short NUM_CARDS_IN_DECK = 52; //Reps number of cards in deck
	const static short NUM_FLOP_CARDS = 3; //Number of cards in flop
	const static short NUM_TURN_CARDS = 4; //Number of cards in turn
	const static short NUM_RIVER_CARDS = 5; //Number of cards in river

    //Integers
	short _numCardCounter = 0; //Counter for initializing number of cards in deck
	short _numPlayersToDealTo = 0; //Sets number of players at table - number between 1 - 6

    //Cards
	Card** p_deck = new Card*[NUM_CARDS_IN_DECK]; // A pointer to an array of Card pointers (how to access without errors)....
	                                              // If it where allocated on the stack would it only be a pointer?
	
	std::vector<Card*> p_vecDeck; //Deck that I can take a cards away from to deal...wasn't sure how to make it work with p_deck
	Card* p_communityCards[5]; // Cards face up on table
	Card* p_holeCards[12]; //Cards dealt to players
	Card* p_combinedCards[7]; //Combined community and holeCards ready for checking hand values

};


So mainly I want to take Card* p_combinedCards[7] and make it accesible in another class...No i dont want it in global scope, I need help passing it through a function as its a pointer to a pointer. and I'm not sure how to pass it(kinda like a kidney stone extremely hard to pass lol... i digress).

Anyway many Thanks Guys,
Paul
Look at friendship in: http://www.cplusplus.com/doc/tutorial/inheritance/
There can by many ways to pass a member function. Other than directly giving access through friendship (which is generally a bad idea), you can just have a getter function.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class Deck
{
...
public:
    Card** getCombinedCards()
    {
        return p_combinedCards;
    }
...
};

//access it
Card** cards = deck.getCombinedCards();
//use the above like an array
std::cout << cards[i]->GetFaceName() << std::endl;


Why are you using arrays instead of std::vector, if you are using std::vector, you can just pass a reference in the getCombinedCards() function
Last edited on
closed account (37oyvCM9)
I will be using vector instead but for some stupid reason I started with an array and havnt changed it yet...

I tried with Card** getCombinedCards(){ return p_combinedCards }; but when I go to iterate in the other class to assign it there it is just staying stationary or crashing. Hold on will I dig out my example...Sh*t i deleted it but I was doing this...

player.h
1
2
3
4
5
6
7
8
9
class Player
{
public:
    void setPlayerHand(Card* combinedCards);

private:
     Card* p_playerHand[7];

};

player.cpp
1
2
3
4
5
6
7
8
9
10
11
Player::Player()
{
	//Sets _playerID equal to number of number of players created
	static short playerID = 1;
	_playerID = playerID;
	playerID++;
}
void Player::setPlayerHand(Card* combinedCards)
{
       p_playerHand[0] = &combinedCards ;
}

main.cpp( for completeness
 
players[0].setPlayerHand(&deck.getCombinedCards()); //obvisiouly has int main etc in there. 


Okay I know that p_playerHand[0] will eventually go into a for loop....BUT how the hell do I increment my combinedCards parameter to grab the next element of the bloody array.

Like I said newbie here so take it easy guys, my head already feels like it spinning around like pete burn's Proverbial record.

Cheers Paul





Last edited on
closed account (48T7M4Gy)
Why not operate with one deck? All you need is have an attribute that records who, if any, a card is dealt to and whether it is discarded/available. Run through the list and you know what a players hand is.

If you pass a ** array back then you need to pass the sizes of the two dimension back

eg in main()

1
2
3
4
5
6
7
type** array = X.getArray(); // need corresponding method in class X of course that returns a type**

for (int i = 0; i < X.get_I_Size();
 ... and another for loop for X.get_J_Size()
{
    std:: cout << array[i][j];// or whatever
}


 
Card* p_playerHand[7];

That's what you are doing wrong, make it
 
Card** p_playerHand;

And here's your new function
1
2
3
4
void Player::setPlayerHand(Card** combinedCards)
{
       p_playerHand = combinedCards;
}


All of this could be less confusing if you use std::vector (and a reference to it, which you'll have to initialize at the constructor)

Edit:
Also, I suggest read up on std::unique_ptr, since you are creating objects with, unique_ptr will make things safer if not easier.
Last edited on
closed account (37oyvCM9)
Hi AKN,

Thanks very much for that, Its working now! I had a glaring error in my main.cpp as well that was causing my array to go out of bounds(where the crash was coming form!). If not for your help I wouldn't of found it.

code now looks like this
1
2
3
4
5
6
7
8
9
10
void Player::setPlayerHand(Card** combinedCards, int size)
{
	for (int i = 0; i < size; i++)
	{
		p_playerHand[i] = combinedCards++;
		std::cout << (*p_playerHand[i])->GetFaceName() << " Of " << (*p_playerHand[i])->GetSuitName() << std::endl;
		
	}
	
}


I will def have a look at std::unique_ptr!. std::cout is only there to test.

Cheers,
Paul(alot less stressed :)
Last edited on
closed account (37oyvCM9)
Kermot,

You where right as well mate thanks,

I will be operating with a vector later which is already in the constructor I just wanted to get this working first.

I am not using a multi dimensional array, just an array of card objects(struct) as it makes more sense to me that way.

Thanks for your help though! :)

cheers,
Paul
Last edited on
closed account (48T7M4Gy)
That's all good Paul.

It depends where you are on the learning spectrum. Multi-dimension arrays are a bit cumbersome keeping them synchronised, I agree.

Ideally create objects, relate them appropriately, 'stuff' them into STL containers of some sort and shuffle them (or it) around and use the data at will, not unlike a database. The more you know the better the choices.
closed account (37oyvCM9)
The more you know the better the choices.


Def agree lol! I've only been at the language six months now so massive learning curve.

I understand multi-dimension arrays just didn't think it was right for this.

STL no idea lol, I haven't gone there yet as I want to get a firm grasp of the core language first...Not sure im saying that right but every time I look at the STL's I stagger a lil bit(like a drunk man climbing Everest more like lol).

I should change my name to The Sultan of BrokenCode because Ill be back here again in dire straits(bad joke i know but if I didn't do them the good ones would be lost) again.

Later:)




Last edited on
closed account (48T7M4Gy)
Maybe ACDC - Highway to Hell - stay on the road ;)
closed account (37oyvCM9)
Cheers :) ...I wrote that down for plagiarism purposes lol....taken it easy - eagles.... later K:)
Topic archived. No new replies allowed.