Search code examples
c++oopfriendderived-class

C++ Derived classes cannot modify a base class' attributes but an external class can


I am doing a Poker Engine so that different PokerPlayer agents can play against each other in tournament simulations. Once my project is done, I would like people to submit their own agents in a PR. In order to do so, they would only have to derive the PokerPlayer class with their MyPokerPlayer class and override the play() method. But I want to make sure that their agents don't cheat. I don't want them to be able to change the money that they have, nor do I want them to be able to change the cards that they have been given at the beginning of the game.

The problem is that the Game class needs to be able to take a PokerPlayer's money when they bet (or give them the pot when they win) and needs to be able to set the PokerPlayer's card at the beginning of the Game. So PokerPlayer's derived classes cannot directly update their own money and cards but the external class Game can.

PokerPlayer.h (This is the class that sould be derived by agents)

class PokerPlayer
{
private:
    bool alive = true;
    QList<Card> cards;
    int money;

public:
    PokerPlayer();
    int getMoney() const;
    bool isAlive() const;
    virtual Action* play() = 0;
};

Game.cpp (where I assign the Players their cards, take their bets, etc...)

...
void Game::assignCardsToEveryPlayer() {
    foreach (PokerPlayer* player, this->getPlayers()) {
        QSet<Card> cards = PokerGameManager::generateUniqueCards(2);
        player->setCards(cards.toList());
    }
}
...

What I do not want: MYPokerPlayer.cpp (An Agent)

Action* MYPokerPlayer::play() override {
    this->setMoney(1000000);
    this->setCards(ACE, ACE);
    // you get the idea...
}

How could I achieve this?

Thank you for your time,


Solution

  • Let's review the concepts behind your classes. PokerPlayer is one of the players. This player is in charge of tracking if it is alive, which cards it has, and how much money it has. Does that sound like an accurate simulation of a game that does not allow cheating?

    No? Why not? For one thing, the dealer/house decides who gets which cards. Players can view the cards but not change them. So your class should be similar. (The money is an interesting aspect to analyze, as a real player might bring an ATM card... ;) ) Players buy their chips, sit down, and make moves. Everything else is controlled (or at least overseen) by the house. The player brings just the starting money and the brains (i.e. how to play()).

    Let's see if we can model a poker game more accurately. There are a bunch of people sitting around a table. On the table there are a number of cards, some of which can be viewed by certain players. So... perhaps what you call a "player" should be more accurately deemed a "chair" after you take away the play method. The table owns the chairs, gives each chair cards, and handles moving poker chips to/from the chair (from/to the pot).

    Each player could be reduced to a view of the table (used for making bets, folding, etc.), a const view of their chair (used to see their cards and status), plus the virtual play method. The player joins the game by buying chips from the table, then the table assigns them a chair. The player can only influence the game via the methods provided by the table.


    Admittedly, cheating is still possible (e.g. cast away the const from the chair). The C++ language is not about security within source code. The guardrails that exist are there to prevent accidental infringements; they will not stop maliciousness from someone else working on the same program. Still, you could introduce a level of indirection to make things a little more secure. The chair given to players to look at could be a copy of the chair maintained by the table. A malicious programmer manipulating their copy of the chair would not change what the table tracks.