PC/UVa:110202/10315
这道题根据题目中的描述的大小,把每一手牌的类型都记录下来,然后再比较就好了,因为只有5张牌,有些就硬编码了,如果像打升级一下子能甩一大堆该怎么判断大小还真不知道。
#include <iostream>
#include <string>
#include <sstream>
#include <vector>
#include <algorithm>
using namespace std;
enum class Suit
{
C,D,H,S
};
typedef struct Card
{
int num;
Suit suit;
}Card;
enum class Type
{
HIGHCARD,//最大牌
PAIR,//一对
TWOPAIR,//两对
THREEKIND,//三张相同,
STRAIGHT,//顺子
FLUSH,//同花
FULLHOUSE,//三张相同加一对
FOURKIND,//四张相同
STRAIGHTFLUSH,//同花顺
};
typedef struct Rank
{
Type type;
union
{
int begin;//顺子的最小牌
int four;//四张相同的点数
int three;//三张相同的点数
union
{
struct
{
char pair1;
char pair2;
char other;
}two;
}two;
union
{
struct
{
char pair;
char o1, o2, o3;
}one;
}one;
}rank;
}Rank;
istream& operator>>(istream& is, Card& card)
{
string strCard;
is >> strCard;
char chNum = strCard[0], chSuit = strCard[1];
if (chNum >= '2' && chNum <= '9') card.num = chNum - '0';
else if (chNum == 'T') card.num = 10;
else if (chNum == 'J') card.num = 11;
else if (chNum == 'Q') card.num = 12;
else if (chNum == 'K') card.num = 13;
else if (chNum == 'A') card.num = 14;
if (chSuit == 'C') card.suit = Suit::C;
else if (chSuit == 'D') card.suit = Suit::D;
else if (chSuit == 'H') card.suit = Suit::H;
else if (chSuit == 'S') card.suit = Suit::S;
return is;
}
bool operator<(const Card &card1, const Card &card2)
{
if (card1.num < card2.num) return true;
else return false;
}
Rank getRank(const vector<Card> &vc)
{
Rank rank;
rank.type = Type::HIGHCARD;
rank.rank.begin = vc[0].num;
//判断顺子和花色
bool bFlush = true, bStraight = true;
for (size_t i = 1; i < vc.size(); i++)
{
if (vc[i].suit != vc[i - 1].suit){
bFlush = false;
break;
}
}
for (size_t i = 1; i < vc.size(); i++)
{
if (vc[i].num != vc[i - 1].num + 1){
bStraight = false;
break;
}
}
if (bFlush && bStraight){
rank.type = Type::STRAIGHTFLUSH;
rank.rank.begin = vc[0].num;
return rank;
}
else if (bFlush){
rank.type = Type::FLUSH;
return rank;
}
else if (bStraight){
rank.type = Type::STRAIGHT;
rank.rank.begin = vc[0].num;
return rank;
}
//判断是否有连续的4张
if (vc[0].num == vc[1].num && vc[1].num == vc[2].num && vc[2].num == vc[3].num){
rank.type = Type::FOURKIND;
rank.rank.four = vc[1].num;
return rank;
}
if (vc[1].num == vc[2].num && vc[2].num == vc[3].num && vc[3].num == vc[4].num){
rank.type = Type::FOURKIND;
rank.rank.four = vc[1].num;
return rank;
}
//判断是否有连续的3张,并记下起始位置
size_t pos = vc.size();
for (size_t i = 0; i < vc.size() - 2; i++)
{
if (vc[i].num == vc[i + 1].num && vc[i + 1].num == vc[i + 2].num){
pos = i;
break;
}
}
if (pos == 0){
rank.rank.three = vc[pos].num;
if (vc[3].num == vc[4].num) rank.type = Type::FULLHOUSE;
else rank.type = Type::THREEKIND;
return rank;
}
else if (pos == 1){
rank.type = Type::THREEKIND;
rank.rank.three = vc[pos].num;
return rank;
}
else if (pos == 2){
rank.rank.three = vc[pos].num;
if (vc[0].num == vc[1].num) rank.type = Type::FULLHOUSE;
else rank.type = Type::THREEKIND;
return rank;
}
//判断是否有连续的2张,并记下数目和位置
size_t pair = 0;
vector<size_t> vsPair, vsSingle;
for (size_t i = 0; i < vc.size(); i++)
{
if (i + 1 < vc.size() && vc[i].num == vc[i + 1].num){
vsPair.push_back(i);
pair++;
i++;
}
else vsSingle.push_back(i);
}
if (pair == 2){
rank.type = Type::TWOPAIR;
rank.rank.two.two.pair1 = (char)vc[vsPair[0]].num;
rank.rank.two.two.pair2 = (char)vc[vsPair[1]].num;
rank.rank.two.two.other = (char)vc[vsSingle[0]].num;
return rank;
}
else if (pair == 1){
rank.type = Type::PAIR;
rank.rank.one.one.pair = (char)vc[vsPair[0]].num;
rank.rank.one.one.o1 = (char)vc[vsSingle[0]].num;
rank.rank.one.one.o2 = (char)vc[vsSingle[1]].num;
rank.rank.one.one.o3 = (char)vc[vsSingle[2]].num;
return rank;
}
else return rank;
}
int compare(const vector<Card> &vcA, const vector<Card> &vcB)
{
/*
-1表示白方胜
0表示平局
1表示黑方胜
*/
Rank rankA = getRank(vcA), rankB = getRank(vcB);
if (rankA.type == rankB.type){
switch (rankA.type)
{
case Type::STRAIGHTFLUSH:
case Type::STRAIGHT:
if (rankA.rank.begin < rankB.rank.begin) return -1;
else if (rankA.rank.begin == rankB.rank.begin) return 0;
else return 1;
case Type::FOURKIND:
if (rankA.rank.four < rankB.rank.four) return -1;
else return 1;
case Type::FULLHOUSE:
case Type::THREEKIND:
if (rankA.rank.three < rankB.rank.three) return -1;
else return 1;
case Type::TWOPAIR:
if (rankA.rank.two.two.pair2 < rankB.rank.two.two.pair2) return -1;
else if (rankA.rank.two.two.pair2 > rankB.rank.two.two.pair2) return 1;
else{
if (rankA.rank.two.two.pair1 < rankB.rank.two.two.pair1) return -1;
else if (rankA.rank.two.two.pair1 > rankB.rank.two.two.pair1) return 1;
else{
if (rankA.rank.two.two.other < rankB.rank.two.two.other) return -1;
else if (rankA.rank.two.two.other > rankB.rank.two.two.other) return 1;
else return 0;
}
}
case Type::PAIR:
if (rankA.rank.one.one.pair < rankB.rank.one.one.pair) return -1;
else if (rankA.rank.one.one.pair > rankB.rank.one.one.pair) return 1;
else{
if (rankA.rank.one.one.o3 < rankB.rank.one.one.o3) return -1;
else if (rankA.rank.one.one.o3 > rankB.rank.one.one.o3) return 1;
else{
if (rankA.rank.one.one.o2 < rankB.rank.one.one.o2) return -1;
else if (rankA.rank.one.one.o2 > rankB.rank.one.one.o2) return 1;
else{
if (rankA.rank.one.one.o1 < rankB.rank.one.one.o1) return -1;
else if (rankA.rank.one.one.o1 > rankB.rank.one.one.o1) return 1;
else{
return 0;
}
}
}
}
case Type::FLUSH:
case Type::HIGHCARD:
for (size_t i = vcA.size(); i > 0; i--)
{
if (vcA[i - 1].num < vcB[i - 1].num) return -1;
else if (vcA[i - 1].num > vcB[i - 1].num) return 1;
}
return 0;
default:
return 0;
}
}
else if (rankA.type < rankB.type) return - 1;
else return 1;
}
int main()
{
string strLine;
while (getline(cin, strLine)){
istringstream iss(strLine);
vector<Card> vcA, vcB;
Card card;
for (int i = 0; i < 5; i++)
{
iss >> card;
vcA.push_back(card);
}
sort(vcA.begin(), vcA.end());
for (int i = 0; i < 5; i++)
{
iss >> card;
vcB.push_back(card);
}
sort(vcB.begin(), vcB.end());
int iRet = compare(vcA, vcB);
if (iRet == -1) cout << "White wins." << endl;
else if (iRet == 0) cout << "Tie." << endl;
else if (iRet == 1) cout << "Black wins." << endl;
}
return 0;
}
/*
2H 3D 5S 9C KD 2C 3H 4S 8C AH
2H 4S 4C 2D 4H 2S 8S AS QS 3S
2H 3D 5S 9C KD 2C 3H 4S 8C KH
2H 3D 5S 9C KD 2D 3H 5C 9S KH
*/
本文详细解析了一种扑克牌游戏的算法实现,通过定义扑克牌的结构和类型,使用枚举和结构体来组织牌面信息,实现了对手牌类型的识别和比较。文章深入探讨了从顺子到同花顺的各种牌型的判断逻辑,并通过比较不同类型的手牌来确定胜负。
229

被折叠的 条评论
为什么被折叠?



