110202 Poker Hands


#include <algorithm>
#include <stdio.h>
#include <iostream>
#include <string.h>

using namespace std;

enum Color_t
{
	RED_HEART,
	BLACK_HEART,
	SQUARE,
	GRASS
};

enum RankType_t
{
	MAX = 0,
	PAIR,
	DOUBLE_PAIR,
	TRIPLE,
	SEQ,
	SAME_COLOR,
	TRIPLE_PAIR,
	QUATERNARY,
	SAME_COLOR_SEQ
};

struct Poker
{
	void Set(char* input)
	{
		char num = input[0];
		if ((num >= '2') && (num <= '9'))
			Number = num - '0';
		else
		{
			switch(num)
			{
			case 'T':
				Number = 10;
				break;
			case 'J':
				Number = 11;
				break;
			case 'Q':
				Number = 12;
				break;
			case 'K':
				Number = 13;
				break;
			default: //case 'A':
				Number = 14;
				break;
			}
		}

		switch(input[1])
		{
		case 'C':
			Color = GRASS;
			break;
		case 'D':
			Color = SQUARE;
			break;
		case 'H':
			Color = RED_HEART;
			break;
		default: // case 'S':
			Color = BLACK_HEART;
			break;
		}
	}

	bool operator > (const Poker& other) const
	{
		return (Number > other.Number);
	}

	bool operator < (const Poker& other) const
	{
		return (Number < other.Number);
	}

	bool operator >= (const Poker& other) const
	{
		return !(this->operator<(other));
	}

	bool operator <= (const Poker& other) const
	{
		return !(this->operator>(other));
	}

	bool operator == (const Poker& other) const
	{
		return (Number == other.Number);
	}

	bool operator != (const Poker& other) const
	{
		return !(this->operator==(other));
	}

	int operator - (const Poker& other) const
	{
		return Number - other.Number;
	}

	operator int ()
	{
		return Number;
	}

	int Number;
	Color_t Color;
};

#define MAX_POKER_NUM 5

class PokerSeq
{
public:
	PokerSeq(char* input) 
	{
		for(int i = 0; i < MAX_POKER_NUM; ++i)
		{
			m_pokers[i].Set(input);
			input += 3;
		}

		Analyze();
	}

	int CompareTo(const PokerSeq& other)
	{
		if (m_RankType > other.m_RankType)
			return 1;

		if (m_RankType < other.m_RankType)
			return -1;

		int compairPokerNum = 0;
		switch (m_RankType)
		{
		case SAME_COLOR_SEQ:
		case QUATERNARY:
		case TRIPLE_PAIR:
		case SEQ:
		case TRIPLE:
			compairPokerNum = 1;
			break;

		case SAME_COLOR:
		case MAX:
			compairPokerNum = MAX_POKER_NUM;
			break;

		case PAIR:
			compairPokerNum = MAX_POKER_NUM - 1;
			break;

		case DOUBLE_PAIR:
			compairPokerNum = MAX_POKER_NUM - 2;
		default:
			break;
		}

		for (int i = 1; i <= compairPokerNum; ++i)
		{
			int diff = m_Max[MAX_POKER_NUM - i] - other.m_Max[MAX_POKER_NUM - i];
			if (diff == 0)
				continue;
			return diff;
		}

		return 0;
	}

private:
	void Analyze()
	{
		sort(m_pokers, m_pokers + MAX_POKER_NUM);
		for (int i = 0; i < MAX_POKER_NUM; ++i)
			m_Max[i] = m_pokers[i];
		m_RankType = MAX;

		bool isSeq = IsSequence();
		bool isSameColor = IsSameColor();

		if (isSeq && isSameColor)
		{
			m_RankType = SAME_COLOR_SEQ;
			return;
		}

		if (isSeq)
		{
			m_RankType = SEQ;
			return;
		}

		if (isSameColor)
		{
			m_RankType = SAME_COLOR;
			return;
		}

		int index = GetMultipleSameIndex(4, MAX_POKER_NUM, m_pokers);
		if (index >= 0)
		{
			m_RankType = QUATERNARY;
			m_Max[MAX_POKER_NUM - 1] = m_pokers[index];
			return;
		}

		index = GetMultipleSameIndex(3, MAX_POKER_NUM, m_pokers);
		if (index >= 0)
		{
			m_Max[MAX_POKER_NUM - 1] = m_pokers[index];

			if (index == (MAX_POKER_NUM - 1))
				index = GetMultipleSameIndex(2, 2, m_pokers);
			else if (index == (MAX_POKER_NUM - 3))
				index = GetMultipleSameIndex(2, 2, m_pokers + 3);
			else
				index = -1;

			m_RankType = (index < 0) ? TRIPLE : TRIPLE_PAIR;
			return;
		}

		int maxPairindex = GetMultipleSameIndex(2, MAX_POKER_NUM, m_pokers);
		if (maxPairindex >= 0)
		{
			m_Max[MAX_POKER_NUM - 1] = m_pokers[maxPairindex];

			int secondPairIndex = -1;
			if (maxPairindex == (MAX_POKER_NUM - 1))
			{
				secondPairIndex = GetMultipleSameIndex(2, 3, m_pokers);
				if (secondPairIndex >= 0)
				{
					m_Max[MAX_POKER_NUM - 2] = m_pokers[secondPairIndex];
					m_Max[MAX_POKER_NUM - 3] = (secondPairIndex == 2) ? m_pokers[0] : m_pokers[2];
				}
			}
			else if (maxPairindex == (MAX_POKER_NUM - 2))
			{
				secondPairIndex = GetMultipleSameIndex(2, 2, m_pokers);
				if (secondPairIndex >= 0)
				{
					m_Max[MAX_POKER_NUM - 2] = m_pokers[secondPairIndex];
					m_Max[MAX_POKER_NUM - 3] = m_pokers[MAX_POKER_NUM - 1];
				}
			}

			if (secondPairIndex < 0)
			{
				index = MAX_POKER_NUM - 1;
				for (int i = MAX_POKER_NUM - 1; i >= 0; --i)
				{
					if ((maxPairindex == i) || ((maxPairindex - 1) == i))
						continue;
					--index;
					m_Max[index] = m_pokers[i];
				}
			}

			m_RankType = (secondPairIndex < 0) ? PAIR : DOUBLE_PAIR;
			return;
		}
	}

	bool IsSequence()
	{
		for (int i = 1; i < MAX_POKER_NUM; ++i)
		{
			if ((m_pokers[i] - m_pokers[i - 1]) != 1)
				return false;
		}

		return true;
	}

	bool IsSameColor()
	{
		for (int i = 1; i < MAX_POKER_NUM; ++i)
		{
			if ((m_pokers[i].Color != m_pokers[i - 1].Color))
				return false;
		}

		return true;
	}

	int GetMultipleSameIndex(int times, int total, Poker* pStartPoker)
	{
		for(int i = total - 1; i >= (times - 1); --i)
		{
			bool bingo = true;
			for (int j = (i - times + 2); j <= i; ++j)
			{
				if (pStartPoker[j] != pStartPoker[j - 1])
				{
					bingo = false;
					break;
				}

			}

			if (bingo)
				return i;
		}
		return -1;
	}

private:
	Poker m_pokers[MAX_POKER_NUM];
	int m_Max[MAX_POKER_NUM];
	RankType_t m_RankType;
};

void DoWork()
{
	char buf[MAX_POKER_NUM * 6 + 1];
	while(fgets(buf, MAX_POKER_NUM * 6 + 1, stdin))
	{
		if (strlen(buf) < (MAX_POKER_NUM * 6))
			return;

		PokerSeq black(buf), white(buf + MAX_POKER_NUM * 3);
		int result = black.CompareTo(white);
		if (result == 0)
			cout << "Tie." << endl;
		else if (result > 0)
			cout << "Black wins." << endl;
		else
			cout << "White wins." << endl;
	}
}

int main(int argc, char* argv[])
{
	DoWork();
	return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值