C++ 实现完整版斗地主:含全牌型判断与代码详解
以下是一个较为完整的 C++ 实现的斗地主程序,包含了牌的初始化、发牌、牌型判断等功能。 ```cpp #include <iostream> #include <vector> #include <algorithm> #include <string> // 定义扑克牌的结构体 struct Card { int rank; // 牌面大小,3-15 对应 3 - A,16 对应小王,17 对应大王 std::string suit; // 花色,这里不影响牌的大小,可用于显示 Card(int r, const std::string& s) : rank(r), suit(s) {} }; // 比较两张牌的大小 bool compareCards(const Card& a, const Card& b) { return a.rank > b.rank; } // 初始化一副扑克牌 std::vector<Card> initCards() { std::vector<Card> cards; std::string suits[] = {"♥", "♠", "♣", "♦"}; for (int rank = 3; rank <= 15; ++rank) { for (const auto& suit : suits) { cards.emplace_back(rank, suit); } } cards.emplace_back(16, ""); // 小王 cards.emplace_back(17, ""); // 大王 return cards; } // 洗牌 void shuffleCards(std::vector<Card>& cards) { std::random_shuffle(cards.begin(), cards.end()); } // 发牌 std::vector<std::vector<Card>> dealCards(const std::vector<Card>& cards) { std::vector<std::vector<Card>> players(3); for (int i = 0; i < 17; ++i) { for (int j = 0; j < 3; ++j) { players[j].push_back(cards[i * 3 + j]); } } std::vector<Card> bottomCards(cards.begin() + 51, cards.end()); players.push_back(bottomCards); return players; } // 对玩家的牌进行排序 void sortPlayerCards(std::vector<Card>& playerCards) { std::sort(playerCards.begin(), playerCards.end(), compareCards); } // 判断是否是单张 bool isSingle(const std::vector<Card>& cards) { return cards.size() == 1; } // 判断是否是对子 bool isPair(const std::vector<Card>& cards) { return cards.size() == 2 && cards[0].rank == cards[1].rank; } // 判断是否是三张 bool isThreeOfAKind(const std::vector<Card>& cards) { return cards.size() == 3 && cards[0].rank == cards[1].rank && cards[1].rank == cards[2].rank; } // 判断是否是 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 isJokerBomb(const std::vector<Card>& cards) { return cards.size() == 2 && (cards[0].rank == 16 && cards[1].rank == 17 || cards[0].rank == 17 && cards[1].rank == 16); } // 判断是否是顺子 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; } // 判断是否是连对 bool isConsecutivePairs(const std::vector<Card>& cards) { if (cards.size() < 6 || cards.size() % 2 != 0) return false; for (size_t i = 0; i < cards.size(); i += 2) { if (cards[i].rank != cards[i + 1].rank) return false; if (i > 0 && cards[i].rank != cards[i - 2].rank - 1) return false; } return true; } // 判断是否是飞机 bool isPlane(const std::vector<Card>& cards) { if (cards.size() < 6 || cards.size() % 3 != 0) return false; for (size_t i = 0; i < cards.size(); i += 3) { if (cards[i].rank != cards[i + 1].rank || cards[i + 1].rank != cards[i + 2].rank) return false; if (i > 0 && cards[i].rank != cards[i - 3].rank - 1) return false; } return true; } // 判断是否是飞机带翅膀 bool isPlaneWithWings(const std::vector<Card>& cards) { if (cards.size() < 10) return false; int threeCount = 0; int singleOrPairCount = 0; std::vector<int> ranks; for (const auto& card : cards) { ranks.push_back(card.rank); } std::sort(ranks.begin(), ranks.end(), std::greater<int>()); // 统计三张的数量 for (size_t i = 0; i < ranks.size() - 2; ++i) { if (ranks[i] == ranks[i + 1] && ranks[i + 1] == ranks[i + 2]) { ++threeCount; i += 2; } } if (threeCount < 2) return false; // 统计单张或对子的数量 singleOrPairCount = static_cast<int>(cards.size()) - threeCount * 3; // 检查三张是否连续 std::vector<int> threeRanks; for (size_t i = 0; i < ranks.size() - 2; ++i) { if (ranks[i] == ranks[i + 1] && ranks[i + 1] == ranks[i + 2]) { threeRanks.push_back(ranks[i]); i += 2; } } for (size_t i = 1; i < threeRanks.size(); ++i) { if (threeRanks[i] != threeRanks[i - 1] - 1) return false; } // 检查单张或对子的数量是否符合要求 if (singleOrPairCount == threeCount) { // 飞机带单张 return true; } else if (singleOrPairCount == threeCount * 2) { // 飞机带对子 std::vector<int> remainingRanks; for (const auto& rank : ranks) { bool isThree = false; for (const auto& threeRank : threeRanks) { if (rank == threeRank) { isThree = true; break; } } if (!isThree) { remainingRanks.push_back(rank); } } for (size_t i = 0; i < remainingRanks.size(); i += 2) { if (remainingRanks[i] != remainingRanks[i + 1]) return false; } return true; } return false; } // 判断是否是三带一 bool isThreeWithOne(const std::vector<Card>& cards) { if (cards.size() != 4) return false; std::vector<int> ranks; for (const auto& card : cards) { ranks.push_back(card.rank); } std::sort(ranks.begin(), ranks.end()); return (ranks[0] == ranks[1] && ranks[1] == ranks[2]) || (ranks[1] == ranks[2] && ranks[2] == ranks[3]); } // 判断是否是三带一对 bool isThreeWithPair(const std::vector<Card>& cards) { if (cards.size() != 5) return false; std::vector<int> ranks; for (const auto& card : cards) { ranks.push_back(card.rank); } std::sort(ranks.begin(), ranks.end()); return ((ranks[0] == ranks[1] && ranks[1] == ranks[2] && ranks[3] == ranks[4]) || (ranks[0] == ranks[1] && ranks[2] == ranks[3] && ranks[3] == ranks[4])); } // 判断是否是四带二 bool isFourWithTwo(const std::vector<Card>& cards) { if (cards.size() != 6) return false; std::vector<int> ranks; for (const auto& card : cards) { ranks.push_back(card.rank); } std::sort(ranks.begin(), ranks.end()); return (ranks[0] == ranks[1] && ranks[1] == ranks[2] && ranks[2] == ranks[3]) || (ranks[1] == ranks[2] && ranks[2] == ranks[3] && ranks[3] == ranks[4]) || (ranks[2] == ranks[3] && ranks[3] == ranks[4] && ranks[4] == ranks[5]); } // 判断牌型 std::string getCardType(const std::vector<Card>& cards) { if (isJokerBomb(cards)) return "王炸"; if (isBomb(cards)) return ""; if (isSingle(cards)) return "单张"; if (isPair(cards)) return "对子"; if (isThreeOfAKind(cards)) return "三张"; if (isStraight(cards)) return "顺子"; if (isConsecutivePairs(cards)) return "连对"; if (isPlane(cards)) return "飞机"; if (isPlaneWithWings(cards)) return "飞机带翅膀"; if (isThreeWithOne(cards)) return "三带一"; if (isThreeWithPair(cards)) return "三带一对"; if (isFourWithTwo(cards)) return "四带二"; return "无效牌型"; } int main() { // 初始化扑克牌 std::vector<Card> cards = initCards(); // 洗牌 shuffleCards(cards); // 发牌 std::vector<std::vector<Card>> players = dealCards(cards); // 对每个玩家的牌进行排序 for (auto& playerCards : players) { sortPlayerCards(playerCards); } // 输出每个玩家的牌和底牌 for (int i = 0; i < 3; ++i) { std::cout << "玩家 " << i + 1 << " 的牌: "; for (const auto& card : players[i]) { std::string rankStr; switch (card.rank) { case 11: rankStr = "J"; break; case 12: rankStr = "Q"; break; case 13: rankStr = "K"; break; case 14: rankStr = "A"; break; case 15: rankStr = "2"; break; case 16: rankStr = "小王"; break; case 17: rankStr = "大王"; break; default: rankStr = std::to_string(card.rank); break; } std::cout << card.suit << rankStr << " "; } std::cout << std::endl; } std::cout << "底牌: "; for (const auto& card : players[3]) { std::string rankStr; switch (card.rank) { case 11: rankStr = "J"; break; case 12: rankStr = "Q"; break; case 13: rankStr = "K"; break; case 14: rankStr = "A"; break; case 15: rankStr = "2"; break; case 16: rankStr = "小王"; break; case 17: rankStr = "大王"; break; default: rankStr = std::to_string(card.rank); break; } std::cout << card.suit << rankStr << " "; } std::cout << std::endl; // 示例:判断玩家 1 的前 5 张牌的牌型 std::vector<Card> sampleCards(players[0].begin(), players[0].begin() + 5); std::string cardType = getCardType(sampleCards); std::cout << "玩家 1 前 5 张牌的牌型是: " << cardType << std::endl; return 0; } ``` 代码说明: 1. 结构体 `Card`:用于表示一张扑克牌,包含牌面大小 `rank` 和花色 `suit`。 2. 函数 `initCards`:初始化一副扑克牌,包含 54 张牌。 3. 函数 `shuffleCards`:使用 `std::random_shuffle` 对扑克牌进行洗牌。 4. 函数 `dealCards`:将洗好的牌发给三个玩家,每人 17 张,剩余 3 张作为底牌。 5. 函数 `sortPlayerCards`:对玩家的牌进行排序,从大到小。 6. 牌型判断函数:`isSingle`、`isPair`、`isThreeOfAKind`、`isBomb`、`isJokerBomb`、`isStraight`、`isConsecutivePairs`、`isPlane`、`isPlaneWithWings`、`isThreeWithOne`、`isThreeWithPair`、`isFourWithTwo` 分别用于判断各种牌型。 7. 函数 `getCardType`:根据牌型判断函数的结果,返回牌型的字符串表示。 8. 主函数 `main`:初始化扑克牌,洗牌,发牌,对玩家的牌进行排序,输出每个玩家的牌和底牌,并示例判断玩家 1 的前 5 张牌的牌型。 注意事项: - 该程序只是一个基本的斗地主实现,没有实现完整的游戏逻辑,如叫地主、出牌等。 - 代码中使用了 C++11 及以上的特性,编译时需要确保编译器支持。 ######[AI问答 | 3467点数解答 | 2026-01-10 08:08:38]
- Python 实现球类:精准计算半径、表面积与体积,附输入验证与异常处理!(阿里通义 | 261点数解答 | 2024-11-28 21:19:39)345
- 深度揭秘 Oracle Workarea Size Policy:参数调优助力数据库性能飞升(阿里通义 | 372点数解答 | 2024-05-13 10:54:45)229
- 51 单片机:定时器 0 实现 8 个 LED 循环点亮,附代码及优化建议(字节豆包 | 1193点数解答 | 2024-12-27 15:10:29)314
- JS 代码:判断“red”改值为“green”并弹窗显示结果( | 176点数解答 | 2024-05-20 21:33:04)416
- 用 JS 代码巧妙判断 a 与 b 关系:输出对应结果 ( | 47点数解答 | 2024-05-20 22:10:14)325
- 用 JS 中 for 循环实现 1 到 100 相加并输出结果到页面的完整代码 ( | 240点数解答 | 2024-05-20 22:11:29)464
- 用 JS 的 while 循环实现 1 到 100 相加并输出到页面的代码揭秘( | 47点数解答 | 2024-05-20 22:16:48)356
- 完整 Python 彼岸花源代码:turtle 库绘制绝美造型及开发注意点 (字节豆包 | 550点数解答 | 2025-08-17 12:02:07)520
- C++ 实现斗地主基础框架,完整版功能待你扩展!(字节豆包 | 1050点数解答 | 2026-01-10 08:03:04)25
- C++ 实现完整版斗地主:含代码示例与扩展建议(字节豆包 | 978点数解答 | 2026-01-10 08:03:34)32
- C++ 实现完整版斗地主:含全牌型判断与代码详解(字节豆包 | 3467点数解答 | 2026-01-10 08:08:38)36
- C++ 实现完整版斗地主:含全牌型判断与大小比较,代码详解!(字节豆包 | 3033点数解答 | 2026-01-10 08:13:54)33