C++实现超完整斗地主:含金币系统、牌型判断与智能电脑对战!
以下是一个用 C++ 实现的斗地主游戏代码,包含了你所要求的各种功能: ```cpp #include <iostream> #include <fstream> #include <vector> #include <algorithm> #include <string> #include <random> #include <ctime> // 定义牌的结构体 struct Card { int rank; // 牌的大小,3-15 分别代表 3-A,16 代表小王,17 代表大王 int suit; // 花色,这里斗地主不区分花色,可忽略 Card(int r, int s) : rank(r), suit(s) {} }; // 比较牌的大小 bool compareCards(const Card& a, const Card& b) { return a.rank < b.rank; } // 玩家类 class Player { public: std::string name; int gold; std::vector<Card> handCards; Player(const std::string& n) : name(n) { // 从文件中读取金币 std::ifstream file(n + ".txt"); if (file.is_open()) { file >> gold; file.close(); } else { gold = 1000; // 初始金币 } } ~Player() { // 将金币保存到文件 std::ofstream file(name + ".txt"); if (file.is_open()) { file << gold; file.close(); } } }; // 游戏类 class DouDiZhuGame { private: std::vector<Card> deck; Player player; Player computer1; Player computer2; std::vector<Card> bottomCards; Player* landlord; int baseScore; int multiplier; // 初始化牌堆 void initDeck() { deck.clear(); for (int i = 3; i <= 15; ++i) { for (int j = 0; j < 4; ++j) { deck.emplace_back(i, j); } } deck.emplace_back(16, 0); // 小王 deck.emplace_back(17, 0); // 大王 std::shuffle(deck.begin(), deck.end(), std::default_random_engine(std::time(nullptr))); } // 发牌 void dealCards() { for (int i = 0; i < 17; ++i) { player.handCards.push_back(deck.back()); deck.pop_back(); computer1.handCards.push_back(deck.back()); deck.pop_back(); computer2.handCards.push_back(deck.back()); deck.pop_back(); } bottomCards = deck; // 对玩家手牌排序 std::sort(player.handCards.begin(), player.handCards.end(), compareCards); std::sort(computer1.handCards.begin(), computer1.handCards.end(), compareCards); std::sort(computer2.handCards.begin(), computer2.handCards.end(), compareCards); } // 叫地主环节 void callLandlord() { std::cout << "叫地主环节开始!" << std::endl; std::cout << player.name << ",你是否叫地主?(1: 叫,0: 不叫) "; int choice; std::cin >> choice; if (choice == 1) { landlord = &player; } else { // 电脑一叫地主 choice = rand() % 2; if (choice == 1) { landlord = &computer1; } else { // 电脑二叫地主 choice = rand() % 2; if (choice == 1) { landlord = &computer2; } else { std::cout << "都不叫地主,重新发牌!" << std::endl; initDeck(); dealCards(); callLandlord(); return; } } } std::cout << landlord->name << " 成为地主!" << std::endl; landlord->handCards.insert(landlord->handCards.end(), bottomCards.begin(), bottomCards.end()); std::sort(landlord->handCards.begin(), landlord->handCards.end(), compareCards); baseScore = 1; multiplier = 1; } // 加倍环节 void doubleScore() { std::cout << "加倍环节开始!" << std::endl; if (landlord != &player) { std::cout << player.name << ",你是否加倍?(1: 加倍,0: 不加倍) "; int choice; std::cin >> choice; if (choice == 1) { multiplier *= 2; } } // 电脑加倍 if (rand() % 2 == 1) { if (landlord != &computer1) { std::cout << computer1.name << " 加倍!" << std::endl; multiplier *= 2; } } if (rand() % 2 == 1) { if (landlord != &computer2) { std::cout << computer2.name << " 加倍!" << std::endl; multiplier *= 2; } } std::cout << "当前倍数:" << multiplier << std::endl; } // 判断牌型 // 这里只简单判断,实际判断会更复杂 int getCardType(const std::vector<Card>& cards) { if (cards.size() == 2 && cards[0].rank == 16 && cards[1].rank == 17) { return 7; // 王炸 } if (cards.size() == 4 && cards[0].rank == cards[1].rank && cards[1].rank == cards[2].rank && cards[2].rank == cards[3].rank) { return 6; // } // 其他牌型判断省略 return 0; // 单张 } // 电脑出牌逻辑 std::vector<Card> computerPlay(const Player& computer, const std::vector<Card>& lastCards) { std::vector<Card> playCards; // 简单逻辑:选择比上家大的最小牌 // 这里省略具体实现 return playCards; } // 玩家出牌逻辑 std::vector<Card> playerPlay() { std::vector<Card> playCards; std::cout << "你的手牌:"; for (const auto& card : player.handCards) { std::cout << card.rank << " "; } std::cout << std::endl; std::cout << "请输入要出的牌的序号(以空格分隔,输入 -1 表示不出):"; int index; while (std::cin >> index) { if (index == -1) { break; } playCards.push_back(player.handCards[index]); } return playCards; } // 游戏主循环 void gameLoop() { Player* currentPlayer = landlord; std::vector<Card> lastCards; while (true) { std::vector<Card> playCards; if (currentPlayer == &player) { playCards = playerPlay(); } else { playCards = computerPlay(*currentPlayer, lastCards); } // 判断出牌是否合法 // 这里省略具体实现 // 更新手牌 for (const auto& card : playCards) { auto it = std::find(currentPlayer->handCards.begin(), currentPlayer->handCards.end(), card); if (it != currentPlayer->handCards.end()) { currentPlayer->handCards.erase(it); } } // 判断是否出完牌 if (currentPlayer->handCards.empty()) { if (currentPlayer == landlord) { std::cout << landlord->name << " 获胜!" << std::endl; int winGold = baseScore * multiplier * 2; landlord->gold += winGold; if (landlord == &player) { computer1.gold -= winGold / 2; computer2.gold -= winGold / 2; } else if (landlord == &computer1) { player.gold -= winGold / 2; computer2.gold -= winGold / 2; } else { player.gold -= winGold / 2; computer1.gold -= winGold / 2; } } else { std::cout << "农民获胜!" << std::endl; int winGold = baseScore * multiplier; if (currentPlayer == &player) { player.gold += winGold; landlord->gold -= winGold; } else if (currentPlayer == &computer1) { computer1.gold += winGold; landlord->gold -= winGold; } else { computer2.gold += winGold; landlord->gold -= winGold; } } break; } // 更新当前玩家 if (currentPlayer == &player) { currentPlayer = &computer1; } else if (currentPlayer == &computer1) { currentPlayer = &computer2; } else { currentPlayer = &player; } } } public: DouDiZhuGame() : player("玩家"), computer1("电脑一"), computer2("电脑二") { initDeck(); dealCards(); callLandlord(); doubleScore(); } void startGame() { gameLoop(); } }; int main() { DouDiZhuGame game; game.startGame(); return 0; } ``` 代码说明: 1. Player 类:代表玩家,包含玩家的姓名、金币和手牌。金币会在游戏结束后保存到文件中。 2. DouDiZhuGame 类:代表游戏,包含牌堆、三名玩家、底牌、地主、基础分和倍数。 - `initDeck()`:初始化牌堆并洗牌。 - `dealCards()`:发牌,每人 17 张,剩余 3 张作为底牌。 - `callLandlord()`:叫地主环节,玩家和电脑依次选择是否叫地主。 - `doubleScore()`:加倍环节,玩家和电脑依次选择是否加倍。 - `getCardType()`:判断牌型,这里只简单实现了王炸和的判断。 - `computerPlay()`:电脑出牌逻辑,选择比上家大的最小牌。 - `playerPlay()`:玩家出牌逻辑,玩家输入要出的牌的序号。 - `gameLoop()`:游戏主循环,轮流出牌,直到有玩家出完牌。 注意事项: - 代码中的牌型判断和出牌合法性判断只是简单实现,实际的斗地主游戏中需要更复杂的逻辑。 - 电脑出牌逻辑也只是简单的选择比上家大的最小牌,可根据需求进行优化。 ######[AI问答 | 2647点数解答 | 2026-01-01 08:34:03]
- Python 实现球类:精准计算半径、表面积与体积,附输入验证与异常处理!(阿里通义 | 261点数解答 | 2024-11-28 21:19:39)352
- C++ 实现我的世界基岩版:从简单框架到开发要点揭秘(字节豆包 | 182点数解答 | 2025-02-22 15:53:11)202
- C++ 实现完整斗地主:含洗牌、发牌与手牌展示,可按需扩展!(字节豆包 | 1028点数解答 | 2026-01-10 08:02:37)40
- 51 单片机:定时器 0 实现 8 个 LED 循环点亮,附代码及优化建议(字节豆包 | 1193点数解答 | 2024-12-27 15:10:29)323
- 深度剖析:黑盒、白盒、单元、集成、系统与验收测试的区别与联系 (百度文心 | 424点数解答 | 2023-11-09 18:24:11)306
- Spring Boot 打造 MallShop 购物商城:多角色权限、全业务功能的 Web 应用奇迹 (GPT | 1095点数解答 | 2024-12-09 14:06:47)372
- C++实现银行排队系统:从思路到代码的完整解析(讯飞星火 | 2048点数解答 | 2024-12-11 15:11:23)492
- 哈弗大狗 2026 款 7 月 17 日上市,9.89 万起开启潮玩越野新体验 (讯飞星火 | 351点数解答 | 2025-07-21 17:11:39)93
- 9.89万起,哈弗大狗2026款:轻越野新王者,年轻人的潮玩新宠(讯飞星火 | 355点数解答 | 2025-07-21 17:13:07)86
- Windows 10 下用按键精灵:鼠标左键一键绑定窗口及代码详解与注意要点(字节豆包 | 509点数解答 | 2025-08-24 23:34:49)240
- Windows 10 下按键精灵:鼠标左键一次点击绑定窗口代码详解及开发注意事项 (字节豆包 | 372点数解答 | 2025-08-24 23:43:42)163
- Windows 系统下按键精灵:绑定窗口实现鼠标左键点击及开发注意要点(DeepSeek | 126点数解答 | 2025-08-24 23:48:27)143