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.
#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 (unsignedint i = 0; i < NUM_CARDS_IN_DECK - (holeCards + turn); i++)
{
p_vecDeck.pop_back();
}
}
Deck::~Deck()
{
}
#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
conststaticshort NUM_CARDS_IN_DECK = 52; //Reps number of cards in deck
conststaticshort NUM_FLOP_CARDS = 3; //Number of cards in flop
conststaticshort NUM_TURN_CARDS = 4; //Number of cards in turn
conststaticshort 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).
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
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
staticshort 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.
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
}
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.
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.
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.