Производные классы C ++ не могут изменять атрибуты базового класса, но внешний класс может - PullRequest
0 голосов
/ 08 февраля 2020

Я использую Poker Engine, чтобы разные агенты PokerPlayer могли играть друг против друга в симуляции турниров. Когда мой проект будет завершен, я бы хотел, чтобы люди представили своих агентов в PR. Для этого им нужно только получить класс PokerPlayer с их классом MyPokerPlayer и переопределить метод play () . Но я хочу убедиться, что их агенты не обманывают. Я не хочу, чтобы они могли менять деньги, которые у них есть, и при этом я не хочу, чтобы они могли менять карты, которые им дали в начале игры.

Проблема в том, что класс Game должен иметь возможность брать деньги PokerPlayer , когда они делают ставку (или дают им банк, когда они выигрывают), и должен иметь возможность установить * 1013 Карта * PokerPlayer в начале игры. Так что PokerPlayer производные классы не могут напрямую обновлять свои собственные деньги и карты, но внешний класс Game может.

PokerPlayer.h (This это класс, который должен быть получен агентами)

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 (где я назначаю игрокам их карты, беру их ставки и т. д. c ... )

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

Чего я не хочу: MYPokerPlayer. cpp (Агент)

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

Как мне этого добиться?

Спасибо за ваше время,

Ответы [ 2 ]

0 голосов
/ 08 февраля 2020

Давайте рассмотрим концепции ваших занятий. PokerPlayer является одним из игроков. Этот игрок отвечает за отслеживание, если он жив, какие у него карты и сколько у него денег. Похоже ли это на точную симуляцию игры, в которой нельзя обманывать?

Нет? Почему бы нет? Во-первых, дилер / дом решает, кто какие карты получит. Игроки могут просматривать карты, но не менять их. Так что ваш класс должен быть похожим. (Деньги - интересный аспект для анализа, поскольку реальный игрок может принести карту банкомата ...;)) Игроки покупают свои фишки, садятся и делают ходы. Все остальное контролируется (или, по крайней мере, контролируется) домом. Игрок приносит только стартовые деньги и мозги (т.е. как play()).

Давайте посмотрим, сможем ли мы смоделировать игру в покер более точно. За столом сидит кучка людей. На столе есть несколько карт, некоторые из которых могут просматривать некоторые игроки. Так что ... возможно, то, что вы называете "игроком", следует более точно считать "стулом" после того, как вы уберете метод play. Стол владеет стульями, дает каждому карточку стула и обрабатывает движущиеся фишки для покера в / из стула (из / в банк).

Каждый игрок может быть уменьшен до вида стола (используется для ставки, фолд и т. д. c.), const вид их стула (используется для просмотра их карт и статуса), плюс виртуальный метод play. Игрок присоединяется к игре, покупая фишки у table, затем table назначает им chair. player может влиять на игру только с помощью методов, предусмотренных table.


По общему признанию, обман все еще возможен (например, выбрасывать const из chair). Язык C ++ не касается безопасности в исходном коде. Существующие ограждения предназначены для предотвращения случайных нарушений; они не остановят злонамеренность от кого-то, кто работает над той же программой. Тем не менее, вы можете ввести уровень косвенности, чтобы сделать вещи немного более безопасными. chair, предоставленный игрокам для просмотра, может быть копией chair, поддерживаемой table. Злонамеренный программист, манипулирующий своей копией стула, не изменит то, что отслеживает table.

0 голосов
/ 08 февраля 2020

Вы можете хранить деньги и другие ценности, которые не следует обманывать как частные члены вашего базового класса, и ограничивать их изменения только личными функциями PokerPlayer, которые должны вызываться Игрой или что-либо, что должно их изменять. :

class Game;

class PokerPlayer {
  friend class Game;
private:
  int money;
public:
  int getMoney() const;
};
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...