I'm working on a cards game.
In this game I have players, who are members of a team (2 players per team), and they can join a lobby.
So the lobby has a teams member, and the teams both have a players member. I'd like to iterate over the players directly without going through the teams every time.
Relevant C++ code:
lobby.h
class Lobby {
public:
Lobby(std::string const& name, std::vector<Team> const& teams = std::vector<Team>());
Lobby(){};
~Lobby();
// give cards to all players
void deal();
std::vector<std::shared_ptr<Player> > getPlayers(); // this is the one I'm trying to implement
[...]
private:
std::string _name;
std::vector<Team> _teams;
};
lobby.cpp
[...]
void Lobby::deal()
{
vector<Card> cards = Card::getAllCardsShuffled();
for (int i = 0; i < cards.size(); i++) {
getPlayers()[i % 4].addCard(cards[i]); // this is how I'd like to use getPlayers()
}
cout << _teams[0].getPlayers().at(0).getCards().size() << endl;
// this compiles but I'm not getting any cards in my players (prints 0)
// I think a copy is made somewhere, so I'm always getting new players
}
// this is the method I'm trying to implement...
vector<shared_ptr<Player> > Lobby::getPlayers()
{
return {
make_shared<Player>(_teams[0].getPlayers().at(0)),
make_shared<Player>(_teams[0].getPlayers().at(1)),
make_shared<Player>(_teams[1].getPlayers().at(0)),
make_shared<Player>(_teams[1].getPlayers().at(1))
};
}
[...]
team.h
class Team {
public:
Team();
Team(std::string name);
~Team();
void addPlayer(Player const& player);
void addTrick(Trick const& trick);
void setScore(int const& newScore);
void addPoints(int const& score);
int getScore();
std::vector<Trick> getTricks();
std::vector<Player>& getPlayers();
bool isTeamDealing();
private:
std::string _name;
std::shared_ptr<std::vector<Player> > _players;
int _score;
std::vector<Trick> _wonTricks;
};
team.cpp
Team::Team(string name)
: _name(name)
, _score(0)
, _players(vector<Player>())
{
}
void Team::addPlayer(Player const& player)
{
if (_players.size() < 2) {
_players.push_back(player);
}
}
vector<Player>& Team::getPlayers()
{
return _players;
}
[...]
Now the code works when iterating over teams and then players:
void Lobby::deal()
{
vector<Card> cards = Card::getAllCardsShuffled();
for (int i = 0; i < cards.size(); i += 4) {
_teams[0].getPlayers().at(0).addCard(cards[i]);
_teams[0].getPlayers().at(1).addCard(cards[i + 1]);
_teams[1].getPlayers().at(0).addCard(cards[i + 2]);
_teams[1].getPlayers().at(1).addCard(cards[i + 3]);
}
cout << getPlayers().at(0)->getCards().size() << endl;
}
... but I'd like to be able to iterate over the players directly, without using 2 nested loops. Is there a simple way to do this?
TL;DR Is there a way to implement getPlayers() that would allow me to iterate over a vector of players and mutate my players directly?
EDIT: I updated the code in Team to have Team.getPlayers() return a reference to the vector instead of a pointer.