C++写个卡牌游戏,没报错却始终无法运行,如何解决?

代码语法啥的都没有报错,但就是无法运行。能帮我看看问题出在哪里吗?T_T

#include 
#include 
#include 
#include 
#include 

class Player {
public:
    Player(std::string name) : name_(name), life_(20) {}

    int getLife() const { return life_; }
    void setLife(int life) { life_ = life; }
    std::string getName() const { return name_; }

    // 从牌组中抽一张牌,加入手牌
    void drawCard(std::vector& deck) {
        if (deck.empty()) return;
        hand_.push_back(deck.back());
        deck.pop_back();
    }

    // 从手牌中打出一张牌,发动该牌的效果
    void playCard(int index, Player& player1, Player& player2) {
        if (index < 0 || index >= hand_.size()) return;
        hand_[index].play(player1, player2);
        hand_.erase(hand_.begin() + index);
    }

    virtual void chooseCardToPlay(Player& player1, Player& player2) = 0;

public:
    std::string name_;
    int life_;
    std::vector hand_;
};

class HumanPlayer : public Player {
public:
    HumanPlayer(std::string name) : Player(name) {}

    void chooseCardToPlay(Player& player1, Player& player2) override {
        // 让人类玩家选择要打出的牌
        std::cout << "手牌:" << std::endl;
        for (int i = 0; i < hand_.size(); ++i) {
            std::cout << i << ": " << hand_[i].getName() << std::endl;
        }
        int index;
        std::cout << "请输入要打出的牌的编号:";
        std::cin >> index;
        playCard(index, player1, player2);
    }
};

class ComputerPlayer : public Player {
public:
    ComputerPlayer(std::string name) : Player(name) {}

    void chooseCardToPlay(Player& player1, Player& player2) override {
        // 让计算机玩家随机选择要打出的牌
        std::uniform_int_distribution<> dist(0, hand_.size() - 1);
        int index = dist(gen_);
        playCard(index, player1, player2);
    }

private:
    std::mt19937 gen_;
};

class Card {
public:
    virtual void play(Player& player1, Player& player2) = 0;
        virtual std::string getName() = 0;
};

class PainfulLessonCard : public Card {
public:
    void play(Player& player1, Player& player2) override {
        // 这张牌的效果:对手失去 2 点生命值并重新抽取一张牌
        player2.setLife(player2.getLife() - 2);
        player2.drawCard(deck_);
    }
    std::string getName() override { return "Painful Lesson"; }

public:
    std::vector deck_;
};

class ResentmentCard : public Card {
public:
    void play(Player& player1, Player& player2) override {
        // 这张牌的效果:两名玩家都失去 1 点生命值
        player1.setLife(player1.getLife() - 1);
        player2.setLife(player2.getLife() - 1);
    }
    std::string getName() override { return "Resentment"; }
};

class CompleteHealingCard : public Card {
public:
    void play(Player& player1, Player& player2) override {
        // 这张牌的效果:将您的健康恢复到 20
        player1.setLife(20);
    }
    std::string getName() override { return "Complete Healing"; }
};

class SwitcherooCard : public Card {
public:
    void play(Player& player1, Player& player2) override {
        // 这张牌的效果:将你手牌抽取一张与对手的手牌交换
        if (player1.hand_.empty() || player2.hand_.empty()) return;
        std::swap(player1.hand_, player2.hand_);
    }
    std::string getName() override { return "Switcheroo"; }
};

class RefreshCard : public Card {
public:
    void play(Player& player1, Player& player2) override {
        // 这张牌的效果:失去 3 点生命值并将弃牌堆洗回牌组
        player1.setLife(player1.getLife() - 3);
        deck_.insert(deck_.end(), discardPile_.begin(), discardPile_.end());
        discardPile_.clear();
        std::shuffle(deck_.begin(), deck_.end(), gen_);
    }
    std::string getName() override { return "Refresh"; }

private:
    std::vector deck_;
    std::vector discardPile_;
    std::mt19937 gen_;
};

class PeekCard : public Card {
public:
    void play(Player& player1, Player& player2) override {
        // 这张牌的效果:查看双方牌组顶牌
        if (deck1_.empty() || deck2_.empty()) return;
        std::cout << "你的牌组顶牌:" << deck1_.back().getName() << std::endl;
        std::cout << "对手的牌组顶牌:" << deck2_.back().getName() << std::endl;
    }
    std::string getName() override { return "Peek"; }

private:
    std::vector deck1_;
    std::vector deck2_;
};

class Game {
public:
    void start() {
        std::cout << "欢迎来到纸牌游戏!" << std::endl;
        std::cout << "请输入你的名字:";
        std::string name;
        std::cin >> name;
        player1_ = std::make_unique(name);
        player2_ = std::make_unique("Computer");
        // 初始化牌组
        deck1_.insert(deck1_.end(), 5, PainfulLessonCard());
        deck1_.insert(deck1_.end(), 6, ResentmentCard());
        deck1_.insert(deck1_.end(), 1, CompleteHealingCard());
        deck1_.insert(deck1_.end(), 2, SwitcherooCard());
        deck1_.insert(deck1_.end(), 2, RefreshCard());
        deck1_.insert(deck1_.end(), 4, PeekCard());
        deck2_ = deck1_; // 复制牌组
        std::shuffle(deck1_.begin(), deck1_.end(), gen_);
        std::shuffle(deck2_.begin(), deck2_.end(), gen_);

        // 开始游戏循环
        while (true) {
            std::cout << "---新回合开始---" << std::endl;
            player1_->drawCard(deck1_);
            player2_->drawCard(deck2_);
            player1_->chooseCardToPlay(*player1_, *player2_);
            player2_->chooseCardToPlay(*player2_, *player1_);
            if (player1_->getLife() <= 0 || deck1_.empty()) {
                std::cout << player2_->getName() << "胜利!" << std::endl;
                break;
            }
            if (player2_->getLife() <= 0 || deck2_.empty()) {
                std::cout << player1_->getName() << "胜利!" << std::endl;
                break;
            }
        }
    }

private:
    std::vector deck1_;
    std::vector deck2_;
    std::unique_ptr player1_;
    std::unique_ptr player2_;
    std::mt19937 gen_;
};

int main() {
    Game game;
    game.start();
    return 0;
}

我猜测题主不太会用C++的面向对象用法, 我没有深入你的业务逻辑, 只是改了一下多态的用法, 在C++中, 多态的调用需要基类的引用或指针, 把抽象基类对象装在一个vector容器中的用法, 不知是哪里学的, 这个问题较大. 我没有做析构部分, 所以代码会有资源泄漏, 题主需要自己加上.

#include <algorithm>
#include <iostream>
#include <random>
#include <string>
#include <utility>
#include <vector>

class Player;

class Card
{
  public:
    virtual ~Card() = default;

    virtual void play(Player &player1, Player &player2) = 0;
    virtual auto getName() -> std::string = 0;
};

class Player
{
  public:
    explicit Player(std::string name)
        : name_(std::move(name))
    {}

    virtual ~Player() = default;

    [[nodiscard]] auto getLife() const -> int
    {
        return life_;
    }

    void setLife(int life)
    {
        life_ = life;
    }

    [[nodiscard]] auto getName() const -> std::string
    {
        return name_;
    }

    // 从牌组中抽一张牌,加入手牌
    void drawCard(std::vector<Card *> &deck)
    {
        if (deck.empty())
        {
            return;
        }
        hand_.push_back(deck.back());
        deck.pop_back();
    }

    // 从手牌中打出一张牌,发动该牌的效果
    void playCard(int index, Player &player1, Player &player2)
    {
        if (index < 0 || index >= hand_.size())
        {
            return;
        }
        hand_[index]->play(player1, player2);
        hand_.erase(hand_.begin() + index);
    }

    virtual void chooseCardToPlay(Player &player1, Player &player2) = 0;

    std::string name_;
    int life_ = 20;
    std::vector<Card *> hand_;
};

class HumanPlayer : public Player
{
  public:
    explicit HumanPlayer(std::string name)
        : Player(std::move(name))
    {}

    void chooseCardToPlay(Player &player1, Player &player2) override
    {
        // 让人类玩家选择要打出的牌
        std::cout << "手牌:" << std::endl;
        for (int i = 0; i < hand_.size(); ++i)
        {
            std::cout << i << ": " << hand_[i]->getName() << std::endl;
        }
        int index;
        std::cout << "请输入要打出的牌的编号:";
        std::cin >> index;
        playCard(index, player1, player2);
    }
};

class ComputerPlayer : public Player
{
  public:
    explicit ComputerPlayer(std::string name)
        : Player(std::move(name))
    {}

    void chooseCardToPlay(Player &player1, Player &player2) override
    {
        // 让计算机玩家随机选择要打出的牌
        std::uniform_int_distribution<> dist(0, static_cast<int>(hand_.size()) -
                                                    1);
        int const index = dist(gen_);
        playCard(index, player1, player2);
    }

  private:
    std::mt19937 gen_;
};

class PainfulLessonCard : public Card
{
  public:
    void play(Player & /*player1*/, Player &player2) override
    {
        // 这张牌的效果:对手失去 2 点生命值并重新抽取一张牌
        player2.setLife(player2.getLife() - 2);
        player2.drawCard(deck_);
    }
    auto getName() -> std::string override
    {
        return "Painful Lesson";
    }

    std::vector<Card *> deck_;
};

class ResentmentCard : public Card
{
  public:
    void play(Player &player1, Player &player2) override
    {
        // 这张牌的效果:两名玩家都失去 1 点生命值
        player1.setLife(player1.getLife() - 1);
        player2.setLife(player2.getLife() - 1);
    }

    auto getName() -> std::string override
    {
        return "Resentment";
    }
};

class CompleteHealingCard : public Card
{
  public:
    void play(Player &player1, Player & /*player2*/) override
    {
        // 这张牌的效果:将您的健康恢复到 20
        player1.setLife(20);
    }

    auto getName() -> std::string override
    {
        return "Complete Healing";
    }
};

class SwitcherooCard : public Card
{
  public:
    void play(Player &player1, Player &player2) override
    {
        // 这张牌的效果:将你手牌抽取一张与对手的手牌交换
        if (player1.hand_.empty() || player2.hand_.empty())
        {
            return;
        }
        std::swap(player1.hand_, player2.hand_);
    }

    auto getName() -> std::string override
    {
        return "Switcheroo";
    }
};

class RefreshCard : public Card
{
  public:
    void play(Player &player1, Player & /*player2*/) override
    {
        // 这张牌的效果:失去 3 点生命值并将弃牌堆洗回牌组
        player1.setLife(player1.getLife() - 3);

        deck_.insert(deck_.end(), discardPile_.begin(), discardPile_.end());

        discardPile_.clear();
        std::shuffle(deck_.begin(), deck_.end(), gen_);
    }

    auto getName() -> std::string override
    {
        return "Refresh";
    }

  private:
    std::vector<Card *> deck_;
    std::vector<Card *> discardPile_;
    std::mt19937 gen_;
};

class PeekCard : public Card
{
  public:
    void play(Player & /*player1*/, Player & /*player2*/) override
    {
        // 这张牌的效果:查看双方牌组顶牌
        if (deck1_.empty() || deck2_.empty())
        {
            return;
        }
        std::cout << "你的牌组顶牌:" << deck1_.back()->getName() << std::endl;
        std::cout << "对手的牌组顶牌:" << deck2_.back()->getName()
                  << std::endl;
    }
    auto getName() -> std::string override
    {
        return "Peek";
    }

  private:
    std::vector<Card *> deck1_;
    std::vector<Card *> deck2_;
};

class Game
{
  public:
    void start()
    {
        std::cout << "欢迎来到纸牌游戏!" << std::endl;
        std::cout << "请输入你的名字:";
        std::string name;
        std::cin >> name;
        player1_ = std::make_unique<HumanPlayer>(name);
        player2_ = std::make_unique<ComputerPlayer>("Computer");
        // 初始化牌组
        for (int i = 0; i != 5; ++i)
        {
            deck1_.insert(deck1_.end(), 1, new PainfulLessonCard());
        }
        for (int i = 0; i != 6; ++i)
        {
            deck1_.insert(deck1_.end(), 1, new ResentmentCard());
        }
        deck1_.insert(deck1_.end(), 1, new CompleteHealingCard());
        for (int i = 0; i != 2; ++i)
        {
            deck1_.insert(deck1_.end(), 1, new SwitcherooCard());
        }
        for (int i = 0; i != 2; ++i)
        {
            deck1_.insert(deck1_.end(), 1, new RefreshCard());
        }
        for (int i = 0; i != 4; ++i)
        {
            deck1_.insert(deck1_.end(), 1, new PeekCard());
        }
        // deck2_ = deck1_; // 复制牌组
        for (int i = 0; i != 5; ++i)
        {
            deck2_.insert(deck2_.end(), 1, new PainfulLessonCard());
        }
        for (int i = 0; i != 6; ++i)
        {
            deck2_.insert(deck2_.end(), 1, new ResentmentCard());
        }
        deck2_.insert(deck2_.end(), 1, new CompleteHealingCard());
        for (int i = 0; i != 2; ++i)
        {
            deck2_.insert(deck2_.end(), 1, new SwitcherooCard());
        }
        for (int i = 0; i != 2; ++i)
        {
            deck2_.insert(deck2_.end(), 1, new RefreshCard());
        }
        for (int i = 0; i != 4; ++i)
        {
            deck2_.insert(deck2_.end(), 1, new PeekCard());
        }
        std::shuffle(deck1_.begin(), deck1_.end(), gen_);
        std::shuffle(deck2_.begin(), deck2_.end(), gen_);

        // 开始游戏循环
        while (true)
        {
            std::cout << "---新回合开始---" << std::endl;
            player1_->drawCard(deck1_);
            player2_->drawCard(deck2_);
            player1_->chooseCardToPlay(*player1_, *player2_);
            player2_->chooseCardToPlay(*player2_, *player1_);
            if (player1_->getLife() <= 0 || deck1_.empty())
            {
                std::cout << player2_->getName() << "胜利!" << std::endl;
                break;
            }
            if (player2_->getLife() <= 0 || deck2_.empty())
            {
                std::cout << player1_->getName() << "胜利!" << std::endl;
                break;
            }
        }
    }

  private:
    std::vector<Card *> deck1_;
    std::vector<Card *> deck2_;
    std::unique_ptr<Player> player1_;
    std::unique_ptr<Player> player2_;
    std::mt19937 gen_;
};

auto main() -> int
{
#ifdef __WIN64
    system("chcp 65001");
#endif
    Game game;
    game.start();
    return 0;
}


你这代码中,有一些明显的错误导致了程序无法运行:

1、Card 类的构造函数没有提供任何参数,但是在 PainfulLessonCard 类的构造函数中,却传递了一个参数给了它。

2、Card 类中没有 getName 函数的实现。

3、PainfulLessonCard 类中没有 play 函数的实现。

还有一个问题,就是 Player 类的 drawCard 函数中传递的参数是一个 std::vector& 类型的引用,但是在 PainfulLessonCard 类中没有定义一个叫做 deck_ 的 std::vector 类型的数组。这可能导致程序的错误。
仅供参考,望采纳,谢谢。

望采纳!!!点击回答右侧即可采纳!
我看了一下问题大概出在
在Card类中,getName函数没有实现。
在PainfulLessonCard和ResentmentCard类中,deck_变量应该是从外部传进来的,应该改为参数。
在ComputerPlayer类中,gen_变量的初始化应该改为std::mt19937 gen_(std::random_device{}());
修改后的代码:

#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <random>

class Player {
public:
Player(std::string name) : name_(name), life_(20) {}


int getLife() const { return life_; }
void setLife(int life) { life_ = life; }
std::string getName() const { return name_; }

// 从牌组中抽一张牌,加入手牌
void drawCard(std::vector<Card>& deck) {
    if (deck.empty()) return;
    hand_.push_back(deck.back());
    deck.pop_back();
}

// 从手牌中打出一张牌,发动该牌的效果
void playCard(int index, Player& player1, Player& player2) {
    if (index < 0 || index >= hand_.size()) return;
    hand_[index].play(player1, player2);
    hand_.erase(hand_.begin() + index);
}

virtual void chooseCardToPlay(Player& player1, Player& player2) = 0;
public:
std::string name_;
int life_;
std::vector<Card> hand_;
};

class HumanPlayer : public Player {
public:
HumanPlayer(std::string name) : Player(name) {}


void chooseCardToPlay(Player& player1, Player& player2) override {
    // 让人类玩家选择要打出的牌
    std::cout << "手牌:" << std::endl;
    for (int i = 0; i < hand_.size(); ++i) {
        std::cout << i << ": " << hand_[i].getName() << std::endl;
    }
    int index;
    std::cout << "请输入要打出的牌的编号:";
    std::cin >> index;
    playCard(index, player1, player2);
}
};

class ComputerPlayer : public Player {
public:
ComputerPlayer(std::string name) : Player(name), gen_(std::random_device{}()) {}


void chooseCardToPlay(Player
& player1, Player& player2) override {
// 让计算机玩家随机选择要打出的牌
std::uniform_int_distribution<> dist(0, hand_.size() - 1);
int index = dist(gen_);
playCard(index, player1, player2);
}

private:
std::mt19937 gen_;
};

class Card {
public:
virtual void play(Player& player1, Player& player2, std::vector<Card>& deck) = 0;
virtual std::string getName() = 0;
};

class PainfulLessonCard : public Card {
public:
void play(Player& player1, Player& player2, std::vector<Card>& deck) override {
// 这张牌的效果:对手失去 2 点生命值并重新抽取一张牌
player2.setLife(player2.getLife() - 2);
player2.drawCard(deck);
}
std::string getName() override { return "Painful Lesson"; }
};

class ResentmentCard : public Card {
public:
void play(Player& player1, Player& player2, std::vector<Card>& deck) override {
// 这张牌的效果:两名玩家都失去 1 点生命值
player1.setLife(player1.getLife() - 1);
player2.setLife(player2.getLife() - 1);
}
std::string getName() override { return "Resentment"; }
};

int main() {
std::vector<Card> deck;
deck.push_back(PainfulLessonCard());
deck.push_back(ResentmentCard());


HumanPlayer player1("player1");
ComputerPlayer player2("player2");

while (player1.getLife() > 0 && player2.getLife() > 0) {
    player1.drawCard(deck);
    player2.drawCard(deck);
    player1.chooseCardToPlay(player1, player2);
    player2.chooseCardToPlay(player1, player2);
}

if (player1.getLife() > 0) {
    std::cout << player1.getName() << "胜利!" << std::endl;
} else {
    std::cout << player2.getName() << "胜利!" << std::endl;
}

return 0;
}