C++ 实现完整版斗地主:含全牌型判断与大小比较,代码详解!
以下是一个完整的 C++ 斗地主程序,它包含了发牌、牌型判断和牌型大小比较等功能: ```cpp #include <iostream> #include <vector> #include <algorithm> // 定义牌的结构体 struct Card { int value; // 牌面大小,3-15 分别代表 3 - A, 16 代表小王,17 代表大王 int suit; // 花色,-1 代表大小王 Card(int v, int s) : value(v), suit(s) {} }; // 比较函数,用于对牌进行排序 bool compareCards(const Card& a, const Card& b) { return a.value > b.value; } // 初始化一副牌 std::vector<Card> initCards() { std::vector<Card> cards; // 普通牌 for (int suit = 0; suit < 4; ++suit) { for (int value = 3; value <= 15; ++value) { cards.emplace_back(value, suit); } } // 大小王 cards.emplace_back(16, -1); cards.emplace_back(17, -1); 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); // 对每个玩家的牌进行排序 for (auto& player : players) { std::sort(player.begin(), player.end(), compareCards); } return players; } // 检查是否是单张 bool isSingle(const std::vector<Card>& cards) { return cards.size() == 1; } // 检查是否是对子 bool isPair(const std::vector<Card>& cards) { return cards.size() == 2 && cards[0].value == cards[1].value; } // 检查是否是三张 bool isThreeOfAKind(const std::vector<Card>& cards) { return cards.size() == 3 && cards[0].value == cards[1].value && cards[1].value == cards[2].value; } // 检查是否是 bool isBomb(const std::vector<Card>& cards) { return cards.size() == 4 && cards[0].value == cards[1].value && cards[1].value == cards[2].value && cards[2].value == cards[3].value; } // 检查是否是王炸 bool isJokerBomb(const std::vector<Card>& cards) { return cards.size() == 2 && ((cards[0].value == 16 && cards[1].value == 17) || (cards[0].value == 17 && cards[1].value == 16)); } // 检查是否是顺子 bool isStraight(const std::vector<Card>& cards) { if (cards.size() < 5) return false; for (size_t i = 0; i < cards.size() - 1; ++i) { if (cards[i].value != cards[i + 1].value + 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].value != cards[i + 1].value) return false; if (i < cards.size() - 2 && cards[i].value != cards[i + 2].value + 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].value != cards[i + 1].value || cards[i + 1].value != cards[i + 2].value) return false; if (i < cards.size() - 3 && cards[i].value != cards[i + 3].value + 1) return false; } return true; } // 检查是否是三带一 bool isThreeWithOne(const std::vector<Card>& cards) { if (cards.size() != 4) return false; std::vector<int> counts(18, 0); for (const auto& card : cards) { counts[card.value]++; } bool threeFound = false; bool oneFound = false; for (int i = 3; i <= 17; ++i) { if (counts[i] == 3) threeFound = true; if (counts[i] == 1) oneFound = true; } return threeFound && oneFound; } // 检查是否是三带一对 bool isThreeWithPair(const std::vector<Card>& cards) { if (cards.size() != 5) return false; std::vector<int> counts(18, 0); for (const auto& card : cards) { counts[card.value]++; } bool threeFound = false; bool pairFound = false; for (int i = 3; i <= 17; ++i) { if (counts[i] == 3) threeFound = true; if (counts[i] == 2) pairFound = true; } return threeFound && pairFound; } // 检查是否是四带二 bool isFourWithTwo(const std::vector<Card>& cards) { if (cards.size() != 6) return false; std::vector<int> counts(18, 0); for (const auto& card : cards) { counts[card.value]++; } bool fourFound = false; int oneOrTwoCount = 0; for (int i = 3; i <= 17; ++i) { if (counts[i] == 4) fourFound = true; if (counts[i] == 1 || counts[i] == 2) oneOrTwoCount += counts[i]; } return fourFound && oneOrTwoCount == 2; } // 判断牌型 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 (isThreeWithOne(cards)) return "三带一"; if (isThreeWithPair(cards)) return "三带一对"; if (isFourWithTwo(cards)) return "四带二"; return "无效牌型"; } // 比较牌型大小 bool compareCardTypes(const std::vector<Card>& a, const std::vector<Card>& b) { std::string typeA = getCardType(a); std::string typeB = getCardType(b); if (typeA == "无效牌型" || typeB == "无效牌型") return false; if (typeA == "王炸" || typeB == "王炸") { return typeA == "王炸"; } if (typeA == "" && typeB != "") { return true; } if (typeA != "" && typeB == "") { return false; } if (typeA != typeB) { return false; } if (typeA == "单张" || typeA == "对子" || typeA == "三张" || typeA == "") { return a[0].value > b[0].value; } if (typeA == "顺子" || typeA == "连对" || typeA == "飞机") { return a[0].value > b[0].value; } // 三带一、三带一对、四带二 简单比较三张或四张的牌面大小 if (typeA == "三带一" || typeA == "三带一对" || typeA == "四带二") { std::vector<int> countsA(18, 0); std::vector<int> countsB(18, 0); for (const auto& card : a) { countsA[card.value]++; } for (const auto& card : b) { countsB[card.value]++; } int valueA = 0; int valueB = 0; for (int i = 3; i <= 17; ++i) { if (countsA[i] >= 3) valueA = i; if (countsB[i] >= 3) valueB = i; } return valueA > valueB; } return false; } int main() { auto cards = initCards(); shuffleCards(cards); auto players = dealCards(cards); // 输出每个玩家的牌 for (size_t i = 0; i < 3; ++i) { std::cout << "玩家 " << i + 1 << " 的牌: "; for (const auto& card : players[i]) { std::cout << "(" << card.value << ", " << card.suit << ") "; } std::cout << std::endl; } std::cout << "底牌: "; for (const auto& card : players[3]) { std::cout << "(" << card.value << ", " << card.suit << ") "; } std::cout << std::endl; // 示例牌型比较 std::vector<Card> cardsA = {Card(3, 0), Card(3, 1), Card(3, 2), Card(4, 0)}; std::vector<Card> cardsB = {Card(4, 0), Card(4, 1), Card(4, 2), Card(5, 0)}; std::cout << "牌型A: " << getCardType(cardsA) << std::endl; std::cout << "牌型B: " << getCardType(cardsB) << std::endl; if (compareCardTypes(cardsA, cardsB)) { std::cout << "牌型A 大于 牌型B" << std::endl; } else { std::cout << "牌型A 不大于 牌型B" << std::endl; } return 0; } ``` 代码说明: 1. Card 结构体:用于表示一张牌,包含牌面大小 `value` 和花色 `suit`。 2. 初始化牌:`initCards` 函数创建一副完整的斗地主牌。 3. 洗牌:`shuffleCards` 函数使用 `std::random_shuffle` 对牌进行洗牌。 4. 发牌:`dealCards` 函数将洗好的牌发给三个玩家,并保留三张底牌。 5. 牌型判断:一系列 `isXXX` 函数用于判断牌型,`getCardType` 函数根据这些判断结果返回牌型名称。 6. 牌型比较:`compareCardTypes` 函数比较两个牌型的大小,根据规则判断哪个牌型更大。 7. 主函数:初始化牌、洗牌、发牌,并输出每个玩家的牌和底牌。同时进行了一个简单的牌型比较示例。 这个程序实现了斗地主的基本功能,但要实现一个完整的斗地主游戏,还需要添加玩家交互、出牌逻辑等功能。 ######[AI问答 | 3033点数解答 | 2026-01-10 08:13:54]
- C++ 实现完整版斗地主:含全牌型判断与代码详解(字节豆包 | 3467点数解答 | 2026-01-10 08:08:38)37
- Python 实现球类:精准计算半径、表面积与体积,附输入验证与异常处理!(阿里通义 | 261点数解答 | 2024-11-28 21:19:39)345
- 用C++解决P2197扩建花坛问题:计算长方形花坛扩建为正方形最少增加的面积(字节豆包 | 280点数解答 | 2026-03-22 16:46:21)7
- 深度揭秘 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)465
- 用 JS 的 while 循环实现 1 到 100 相加并输出到页面的代码揭秘( | 47点数解答 | 2024-05-20 22:16:48)356
- 完整 Python 彼岸花源代码:turtle 库绘制绝美造型及开发注意点 (字节豆包 | 550点数解答 | 2025-08-17 12:02:07)521
- C++ 实现斗地主基础框架,完整版功能待你扩展!(字节豆包 | 1050点数解答 | 2026-01-10 08:03:04)26
- C++ 实现完整版斗地主:含代码示例与扩展建议(字节豆包 | 978点数解答 | 2026-01-10 08:03:34)33