C++实现超完整斗地主:含金币系统与丰富玩法,附完整代码!
以下是一个用 C++ 实现的斗地主游戏代码,包含了你所要求的各项功能: ```cpp #include <iostream> #include <fstream> #include <vector> #include <algorithm> #include <string> #include <random> #include <chrono> // 定义牌的结构体 struct Card { int rank; // 牌的大小,3-15,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; } // 定义玩家结构体 struct Player { std::string name; int gold; std::vector<Card> handCards; bool is地主; Player(const std::string& n, int g) : name(n), gold(g), is地主(false) {} }; // 初始化一副牌 std::vector<Card> initializeDeck() { std::vector<Card> deck; for (int suit = 0; suit < 4; ++suit) { for (int rank = 3; rank <= 15; ++rank) { deck.emplace_back(rank, suit); } } deck.emplace_back(16, 0); // 小王 deck.emplace_back(17, 0); // 大王 return deck; } // 洗牌 void shuffleDeck(std::vector<Card>& deck) { unsigned seed = std::chrono::system_clock::now().time_since_epoch().count(); std::shuffle(deck.begin(), deck.end(), std::default_random_engine(seed)); } // 发牌 void dealCards(std::vector<Card>& deck, std::vector<Player>& players, std::vector<Card>& bottomCards) { bottomCards = std::vector<Card>(deck.end() - 3, deck.end()); for (int i = 0; i < 3; ++i) { players[i].handCards = std::vector<Card>(deck.begin() + i * 17, deck.begin() + (i + 1) * 17); std::sort(players[i].handCards.begin(), players[i].handCards.end(), compareCards); } } // 叫地主 int bidLandlord(std::vector<Player>& players) { std::cout << "叫地主环节开始!" << std::endl; for (int i = 0; i < 3; ++i) { if (players[i].name == "玩家") { std::cout << "你是否叫地主?(1: 叫,0: 不叫) "; int choice; std::cin >> choice; if (choice == 1) { return i; } } else { // 电脑随机叫地主 bool bid = (rand() % 2 == 1); if (bid) { std::cout << players[i].name << " 叫地主!" << std::endl; return i; } else { std::cout << players[i].name << " 不叫地主。" << std::endl; } } } // 如果都不叫,重新开始 return bidLandlord(players); } // 抢地主 int grabLandlord(std::vector<Player>& players, int firstBidder) { std::cout << "抢地主环节开始!" << std::endl; int currentBidder = (firstBidder + 1) % 3; while (currentBidder != firstBidder) { if (players[currentBidder].name == "玩家") { std::cout << "你是否抢地主?(1: 抢,0: 不抢) "; int choice; std::cin >> choice; if (choice == 1) { return currentBidder; } } else { // 电脑随机抢地主 bool grab = (rand() % 2 == 1); if (grab) { std::cout << players[currentBidder].name << " 抢地主!" << std::endl; return currentBidder; } else { std::cout << players[currentBidder].name << " 不抢地主。" << std::endl; } } currentBidder = (currentBidder + 1) % 3; } return firstBidder; } // 加倍环节 int doubleScore(std::vector<Player>& players, int landlordIndex) { int score = 1; int currentIndex = landlordIndex; for (int i = 0; i < 3; ++i) { if (players[currentIndex].name == "玩家") { std::cout << "你是否加倍?(1: 加倍,2: 超级加倍,0: 不加倍) "; int choice; std::cin >> choice; if (choice == 1) { score *= 2; } else if (choice == 2) { score *= 4; } } else { // 电脑随机加倍 int randNum = rand() % 3; if (randNum == 1) { score *= 2; std::cout << players[currentIndex].name << " 加倍!" << std::endl; } else if (randNum == 2) { score *= 4; std::cout << players[currentIndex].name << " 超级加倍!" << std::endl; } } currentIndex = (currentIndex + 1) % 3; } return score; } // 牌型判断(简化实现) bool isBomb(const std::vector<Card>& cards) { return cards.size() == 4 && cards[0].rank == cards[1].rank && cards[1].rank == cards[2].rank && cards[2].rank == cards[3].rank; } bool isStraight(const std::vector<Card>& cards) { if (cards.size() < 5) return false; for (size_t i = 1; i < cards.size(); ++i) { if (cards[i].rank != cards[i - 1].rank + 1) return false; } return true; } // 出牌函数(简化实现) std::vector<Card> playCards(Player& player) { if (player.name == "玩家") { std::cout << "你的手牌:"; for (const auto& card : player.handCards) { std::cout << card.rank << " "; } std::cout << std::endl; std::cout << "请输入要出的牌的索引(从 0 开始,用空格分隔,输入 -1 表示不出):"; std::vector<int> indices; int index; while (std::cin >> index) { if (index == -1) break; indices.push_back(index); } std::vector<Card> playedCards; std::sort(indices.begin(), indices.end(), std::greater<int>()); for (int idx : indices) { playedCards.push_back(player.handCards[idx]); player.handCards.erase(player.handCards.begin() + idx); } std::sort(playedCards.begin(), playedCards.end(), compareCards); return playedCards; } else { // 电脑默认选择比上家大的最小牌(简化实现,随机出牌) if (rand() % 2 == 1) { int randSize = rand() % (player.handCards.size()) + 1; std::vector<Card> playedCards(player.handCards.end() - randSize, player.handCards.end()); player.handCards.erase(player.handCards.end() - randSize, player.handCards.end()); return playedCards; } return {}; } } // 保存金币 void saveGold(const std::vector<Player>& players) { std::ofstream file("gold.txt"); if (file.is_open()) { for (const auto& player : players) { file << player.name << " " << player.gold << std::endl; } file.close(); } } // 读取金币 void loadGold(std::vector<Player>& players) { std::ifstream file("gold.txt"); if (file.is_open()) { std::string name; int gold; while (file >> name >> gold) { for (auto& player : players) { if (player.name == name) { player.gold = gold; break; } } } file.close(); } } int main() { std::vector<Player> players = {Player("玩家", 1000), Player("电脑一", 1000), Player("电脑二", 1000)}; loadGold(players); std::vector<Card> deck = initializeDeck(); shuffleDeck(deck); std::vector<Card> bottomCards; dealCards(deck, players, bottomCards); int landlordIndex = bidLandlord(players); landlordIndex = grabLandlord(players, landlordIndex); players[landlordIndex].is地主 = true; players[landlordIndex].handCards.insert(players[landlordIndex].handCards.end(), bottomCards.begin(), bottomCards.end()); std::sort(players[landlordIndex].handCards.begin(), players[landlordIndex].handCards.end(), compareCards); int score = doubleScore(players, landlordIndex); // 出牌阶段(简化实现) int currentPlayer = landlordIndex; std::vector<Card> lastPlayedCards; while (true) { std::vector<Card> playedCards = playCards(players[currentPlayer]); if (!playedCards.empty()) { lastPlayedCards = playedCards; if (players[currentPlayer].handCards.empty()) { if (players[currentPlayer].is地主) { std::cout << players[currentPlayer].name << "(地主)获胜!" << std::endl; players[currentPlayer].gold += score * 2; for (int i = 0; i < 3; ++i) { if (i != currentPlayer) { players[i].gold -= score; } } } else { std::cout << players[currentPlayer].name << "(农民)获胜!" << std::endl; players[currentPlayer].gold += score; for (int i = 0; i < 3; ++i) { if (i == landlordIndex) { players[i].gold -= score * 2; } else if (i != currentPlayer) { players[i].gold += score; } } } break; } } currentPlayer = (currentPlayer + 1) % 3; } saveGold(players); std::cout << "游戏结束,当前金币情况:" << std::endl; for (const auto& player : players) { std::cout << player.name << ": " << player.gold << " 金币" << std::endl; } return 0; } ``` 代码说明: 1. 结构体定义: - `Card` 结构体用于表示一张牌,包含牌的大小和花色。 - `Player` 结构体用于表示一个玩家,包含玩家的姓名、金币数量、手牌和是否为地主的标志。 2. 游戏流程: - 初始化一副牌,洗牌并发牌。 - 进入叫地主和抢地主环节,确定地主。 - 进入加倍环节,确定本局分数。 - 开始出牌阶段,直到有玩家出完牌。 - 根据游戏结果更新玩家的金币数量。 3. 牌型判断: - 实现了和顺子的牌型判断,其他牌型可以根据需要扩展。 4. 金币系统: - 游戏开始时从文件中读取玩家的金币数量,游戏结束后将玩家的金币数量保存到文件中。 注意事项: - 此代码为简化实现,部分功能如牌型判断和电脑出牌逻辑可以进一步完善。 - 代码中的输入部分可以根据需要进行更严格的验证。 ######[AI问答 | 2963点数解答 | 2026-01-01 08:44:05]
- 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
- 用 JS 中 for 循环实现 1 到 100 相加并输出结果到页面的完整代码 ( | 240点数解答 | 2024-05-20 22:11:29)477
- 用 JS 的 while 循环实现 1 到 100 相加并输出到页面的代码揭秘( | 47点数解答 | 2024-05-20 22:16:48)363
- 深度剖析:黑盒、白盒、单元、集成、系统与验收测试的区别与联系 (百度文心 | 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
- 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