Reputation: 1535
I'm trying to program a Texas Hold'em game in C++ as practice. I've just started reading about friend functions, and thought about using them to allow players to draw cards from the deck.
I have currently defined two classes as follows:
#include <string>
#include <vector>
#include <stdio.h>
typedef unsigned int uint;
class deck
{
private:
std::vector<card> cards;
public:
void initialize(void)
{
char suits[] = { 'H', 'C', 'D', 'S' };
uint values[] = { 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14 };
for (uint i = 0; i != 4; i++)
{
for (uint j = 0; j != 13; j++)
{
cards.push_back(card(suits[i], values[j]));
}
}
}
void shuffle(void)
{
uint i = cards.size(), random_index;
card shuffled_card;
while (i > 0)
{
random_index = rand() % (i + 1);
shuffled_card = cards[random_index];
cards[random_index] = cards[i];
cards[i] = shuffled_card;
i--;
}
}
};
class player
{
private:
std::string name;
uint chips;
std::vector<card> hand;
public:
player(std::string set_name, uint set_chips) { name = set_name; chips = set_chips; }
void draw(deck& target_deck, uint number)
{
// Draw cards from the top of the
// target deck.
}
};
I'd like the draw()
method of the player
class to take a reference to a member of the deck
class, and to be able to remove number
cards from cards
of deck
. Since cards
is a private element of deck
, I can't reference it in draw()
as target_deck.cards
. I've tried adding a friend function into the deck
class:
friend void player::draw(deck&target_deck, uint number);
This, however, doesn't solve the problem. Is there something wrong with the code, or are the only solutions (a) defining a friend function outside of player
or (b) making the entire player
class a friend of deck
?
Thanks in advance for any pointers!
Upvotes: 2
Views: 139
Reputation: 2731
You have to put player
's definition before deck. And also try defining the draw
function after defining deck
class.
#include <string>
#include <vector>
#include <stdio.h>
typedef unsigned int uint;
class deck;
class player
{
private:
std::string name;
uint chips;
std::vector<card> hand;
public:
player(std::string set_name, uint set_chips) { name = set_name; chips = set_chips; }
void draw(deck& target_deck, uint number); // define it outside.
};
class deck
{
private:
std::vector<card> cards;
public:
friend void draw(deck& target_deck, uint number);
void initialize(void)
{
char suits[] = { 'H', 'C', 'D', 'S' };
uint values[] = { 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14 };
for (uint i = 0; i != 4; i++)
{
for (uint j = 0; j != 13; j++)
{
cards.push_back(card(suits[i], values[j]));
}
}
}
void shuffle(void)
{
uint i = cards.size(), random_index;
card shuffled_card;
while (i > 0)
{
random_index = rand() % (i + 1);
shuffled_card = cards[random_index];
cards[random_index] = cards[i];
cards[i] = shuffled_card;
i--;
}
}
};
void player::draw(deck& target_deck, uint number)
{
// Draw cards from the top of the
// target deck.
}
Upvotes: 0
Reputation: 994619
I would solve this by providing a public function deck::draw()
, which returns the top card from the deck (and removes it from the deck). Then you can implement player::draw()
in terms of deck::draw()
by calling it as many times as needed.
If you implement a deck::draw()
, then you will probably want deck::initialize()
to clear the deck before pushing 52 new cards onto it.
As a minor style note, the notation of putting void
in the parameter list for a function that takes no arguments is supported in C++ for backwards compatibility with C, but is not commonly used in new C++ code. The reason C supports it is because a function declaration (prototype) foo()
says nothing about the arguments the function takes, while foo(void)
says that the function takes no arguments. C++ always treats foo()
as taking no arguments.
Upvotes: 4