pureyounger 2023-01-06 20:59 采纳率: 100%
浏览 125
已结题

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

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

#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) {}

    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<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);
    }
    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<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;
    }
    std::string getName() 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");
        // 初始化牌组
        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<Card> deck1_;
    std::vector<Card> deck2_;
    std::unique_ptr<Player> player1_;
    std::unique_ptr<Player> player2_;
    std::mt19937 gen_;
};

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

  • 写回答

3条回答 默认 最新

  • 关注

    我猜测题主不太会用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;
    }
    
    
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(2条)

报告相同问题?

问题事件

  • 系统已结题 1月15日
  • 已采纳回答 1月7日
  • 赞助了问题酬金15元 1月6日
  • 创建了问题 1月6日

悬赏问题

  • ¥20 机器学习能否像多层线性模型一样处理嵌套数据
  • ¥20 西门子S7-Graph,S7-300,梯形图
  • ¥50 用易语言http 访问不了网页
  • ¥50 safari浏览器fetch提交数据后数据丢失问题
  • ¥15 matlab不知道怎么改,求解答!!
  • ¥15 永磁直线电机的电流环pi调不出来
  • ¥15 用stata实现聚类的代码
  • ¥15 请问paddlehub能支持移动端开发吗?在Android studio上该如何部署?
  • ¥20 docker里部署springboot项目,访问不到扬声器
  • ¥15 netty整合springboot之后自动重连失效