当前位置: 首页 > news >正文

自己写的一部分斗地主的程序,没有去写界面,临时是用黑框来显示的

这几天比較空,所以想写一点东西。

斗地主的程序一直以来都想写,但感觉规则推断比較复杂,一直没有较多的时间来写。

这次主要是把跟牌和牌型的推断写出来了。写了一个比較弱智的AI,属于有牌就出的那种。对于AI算法,临时没有什么好的想法,所以打算临时放一放。

后期补上界面之后再进行优化。

在这就把基本的函数和算法列出来吧。

首先是主程序,主要控制显示和游戏的流程。

#include <iostream>
#include "PokerDesk.h"
using namespace std;
int main()
{
	cout<<"-------------------------------------------"<<endl;
	cout<<"-----welcome to the world of black box-----"<<endl;
	cout<<"-------------------------------------------"<<endl;
	char cContinue = 'n';
	//初始化牌库
	CPokerDesk pdPoker;
	do 
	{	
		pdPoker.Reset();
		//自己主动洗牌
		pdPoker.Shuffle();
		//发牌
		pdPoker.Deal();
		pdPoker.ShowPokerDesk();
		//抢地主
		pdPoker.RobLord();
		pdPoker.ShowPokerDesk();
		while(pdPoker.GetGameState() == gsContinue)
		{
			//出牌
			pdPoker.Discard();
			pdPoker.ShowPokerDesk();
		}
		cout<<"----------game over-----------"<<endl;
		cout<<"Left:"<<pdPoker.m_players[piLeft].m_nPoint;
		cout<<",Middle:"<<pdPoker.m_players[piMiddle].m_nPoint;
		cout<<",Right:"<<pdPoker.m_players[piRight].m_nPoint<<endl;
		//又一次開始或退出
		cout<<"Do you want to continue(y,n)?

"<<endl; cin>>cContinue; } while (cContinue == 'Y' || cContinue == 'y'); return 1; }

初始化之后能够反复玩,统计积分。

接下来是牌桌的类。用到了boost库的format来控制string的格式。

头文件:

#pragma once
#include "Card.h"
#include "Player.h"
#include <vector>
#include <set>
using namespace std;
enum enPlayerId
{
	piLeft,
	piMiddle,
	piRight
};
enum enGameState
{
	gsContinue,
	gsLordLose,
	gsLordWin
};
class CPokerDesk
{
private:
	//上一手
	enPlayerId m_piLastDiscard;
	//出牌人
	enPlayerId m_piDiscard;
	//地主
	enPlayerId m_piLord;
	//游戏状态
	enGameState m_gsState;
	//该次分值
	int m_nPoint;
public:
	vector<CCard> m_lastCards;
	//玩家
	vector <CPlayer> m_players;
	//牌库
	vector<CCard> m_cards;
	//地主牌
	vector<CCard> m_lordcards;
	CPokerDesk(void);
	~CPokerDesk(void);
	void Reset();
	void Shuffle();
	void Deal();
	bool Discard();
	enGameState GetGameState();
	void SetGameState(enGameState gsState);
	enPlayerId GetDiscardId();
	void SetDiscardId(enPlayerId piTurn);
	void ShowPokerDesk();
	void RobLord();
};

实现文件:
#include "PokerDesk.h"
#include <iostream>
#include <boost/format.hpp>
using namespace boost;
CPokerDesk::CPokerDesk(void)
{	
	for(int i = 0; i < 54; i++)
	{
		CCard a((enCardName)i);
		m_cards.push_back(a);
	}
	CPlayer p1("Left",true),p2("Middle",false),p3("Right",true);
	m_players.push_back(p1);
	m_players.push_back(p2);
	m_players.push_back(p3);
	srand(time(NULL));
	enPlayerId pi = enPlayerId(rand()%3);
	m_piDiscard = m_piLastDiscard = m_piLord = pi;
	m_gsState = gsContinue;
}


CPokerDesk::~CPokerDesk(void)
{
}

void CPokerDesk::Reset()
{
	m_lordcards.clear();
	m_lastCards.clear();
	for(int i = 0; i < 3; i++)
		m_players[i].m_handcards.clear();
	m_gsState = gsContinue;
}

void CPokerDesk::Shuffle()
{
	srand(time(NULL));
	/*srand(28);*/
	random_shuffle(m_cards.begin(),m_cards.end());
}

void CPokerDesk::Deal()
{
	for(int i = 0; i < m_cards.size()/3-1; i++)
	{
		for(int j = 0; j < 3; j++)
		{
			m_players[j].m_handcards.push_back(m_cards[i*3+j]);
		}
	}
	for(int i = 0; i < 3; i++)
		sort(m_players[i].m_handcards.begin(),m_players[i].m_handcards.end());
	for(int i = 0; i < 3; i++)
		m_lordcards.push_back(m_cards[m_cards.size()-i-1]);
}

bool CPokerDesk::Discard()
{
	vector<CCard> cards;
	if(m_piDiscard == m_piLastDiscard)
	{
		//
		vector<CCard> cardnull;
		do 
		{
			m_players[m_piDiscard].Discard(cardnull,cards);
		} while (cards.empty());
		m_lastCards.assign(cards.begin(),cards.end());
		
		if(m_players[m_piDiscard].m_handcards.empty())
		{
			if(m_piDiscard == m_piLord)
			{
				m_gsState = gsLordWin;
				for(int i = 0; i < 3; i++)
				{
					if(i == m_piLord)
					{
						m_players[i].m_nPoint += 2*m_nPoint;
					}
					else
					{
						m_players[i].m_nPoint -= m_nPoint;
					}
				}
			}
			else
			{
				m_gsState = gsLordLose;
				for(int i = 0; i < 3; i++)
				{
					if(i == m_piLord)
					{
						m_players[i].m_nPoint -= 2*m_nPoint;
					}
					else
					{
						m_players[i].m_nPoint += m_nPoint;
					}
				}
			}
		}
		m_piLastDiscard = m_piDiscard;
		m_piDiscard = enPlayerId((m_piDiscard+1)%3);
		return true;
	}
	m_players[m_piDiscard].Discard(m_lastCards,cards);
	if(!cards.empty())
	{
		m_lastCards.assign(cards.begin(),cards.end());
		if(m_players[m_piDiscard].m_handcards.empty())
		{
			if(m_piDiscard == m_piLord)
			{
				m_gsState = gsLordWin;
				for(int i = 0; i < 3; i++)
				{
					if(i == m_piLord)
					{
						m_players[i].m_nPoint += 2*m_nPoint;
					}
					else
					{
						m_players[i].m_nPoint -= m_nPoint;
					}
				}
			}
			else
			{
				m_gsState = gsLordLose;
				for(int i = 0; i < 3; i++)
				{
					if(i == m_piLord)
					{
						m_players[i].m_nPoint -= 2*m_nPoint;
					}
					else
					{
						m_players[i].m_nPoint += m_nPoint;
					}
				}
			}
		}
		m_piLastDiscard = m_piDiscard;
	}
	//下家
	m_piDiscard = enPlayerId((m_piDiscard+1)%3);
	return true;
}

enGameState CPokerDesk::GetGameState()
{
	return m_gsState;
}

void CPokerDesk::SetGameState(enGameState gsState)
{
	m_gsState = gsState;
}

enPlayerId CPokerDesk::GetDiscardId()
{
	return m_piDiscard;
}
void CPokerDesk::SetDiscardId(enPlayerId piTurn)
{
	m_piDiscard = piTurn;
}

void CPokerDesk::ShowPokerDesk()
{
	format fmt("%c%c %s %c%c");
	format fmtm("|        %2d        |");
	const string strHor = "--------------------";
	const string strVer = "|                  |";
	std::cout<<"-----------begin of the scene-------------"<<std::endl;
	std::cout<<"           ";
	for(int i = 0; i < m_lordcards.size(); i++)
		std::cout<<m_lordcards[i].m_cCard;
	std::cout<<"           "<<std::endl;
	for(int i = 0; i < 10; i++)
	{
		char c1,c2,c3,c4;
		if(2*i < m_players[0].m_handcards.size())
			c1 = m_players[0].m_handcards[2*i].m_cCard;
		else
			c1 = ' ';
		if(2*i+1 < m_players[0].m_handcards.size())
			c2 = m_players[0].m_handcards[2*i+1].m_cCard;
		else
			c2 = ' ';
		if(2*i < m_players[2].m_handcards.size())
			c3 = m_players[2].m_handcards[2*i].m_cCard;
		else
			c3 = ' ';
		if(2*i+1 < m_players[2].m_handcards.size())
			c4 = m_players[2].m_handcards[2*i+1].m_cCard;
		else
			c4 = ' ';
		string strDesk;
		if(i == 0 || i == 9)//最上和最下
		{
			strDesk = strHor;
		}
		else if (i == 4 || i == 5)
		{
			strDesk = strVer;
			if(m_lastCards.size() <= 10)
			{
				if (i == 4)
				{
					int nBegin = (strVer.size() - m_lastCards.size())/2;
					for(int j = nBegin; j < nBegin+m_lastCards.size(); j++)
						strDesk[j] = m_lastCards[j-nBegin].m_cCard;
				}
			}
			else
			{
				if (i == 4)
				{
					int nBegin = (strVer.size() - 10)/2;
					for(int j = nBegin; j < nBegin+10; j++)
						strDesk[j] = m_lastCards[j-nBegin].m_cCard;
				}
				else
				{
					int nBegin = (strVer.size() - 10)/2;
					for(int j = nBegin; j < nBegin+m_lastCards.size()-10; j++)
						strDesk[j] = m_lastCards[j-nBegin+10].m_cCard;
				}
			}
		}
		else
		{
			strDesk = strVer;
		}
		std::cout<<fmt % c1 % c2 % strDesk % c3 % c4<<std::endl;
	}
	//std::cout<<fmt % c % c % strVer % c % c<<std::endl;
	//std::cout<<fmt % c % c % strVer % c % c<<std::endl;
	//std::cout<<fmt % c % c % strVer % c % c<<std::endl;
	//std::cout<<fmt % c % c % strVer % c % c<<std::endl;
	//std::cout<<fmt % c % c % (fmtm % m_cards.size()) % c % c<<std::endl;
	//std::cout<<fmt % c % c % strVer % c % c<<std::endl;
	//std::cout<<fmt % c % c % strVer % c % c<<std::endl;
	//std::cout<<fmt % c % c % strVer % c % c<<std::endl;
	//std::cout<<fmt % c % c % strVer % c % c<<std::endl;
	//std::cout<<fmt % c % c % strHor % c % c<<std::endl;
	std::cout<<"   ";
	for(int i = 0; i < 20; i++)
	{
		if(i < m_players[1].m_handcards.size())
			std::cout<<m_players[1].m_handcards[i].m_cCard;
		else
			std::cout<<' ';
	}
	std::cout<<"   "<<std::endl;
	std::cout<<"------------end of the scene--------------"<<std::endl;
	/*m_cards.size();
	std::cout<<"33 -------------------- 33"<<std::endl;
	std::cout<<"33 |                  | 33"<<std::endl;
	std::cout<<"33 |                  | 33"<<std::endl;
	std::cout<<"33 |                  | 33"<<std::endl;
	std::cout<<"33 |                  | 33"<<std::endl;
	std::cout<<"33 |                  | 33"<<std::endl;
	std::cout<<"33 |                  | 33"<<std::endl;
	std::cout<<"33 |                  | 33"<<std::endl;
	std::cout<<"33 |                  | 33"<<std::endl;
	std::cout<<"33 -------------------- 33"<<std::endl;
	std::cout<<"   33333333333333333333   "<<std::endl;*/
}
//找下一个
enPlayerId FindNextPlayerId(vector<enPlayerId>& piUsers,enPlayerId pi)
{
	for(vector<enPlayerId>::iterator it = piUsers.begin(); it != piUsers.end(); ++it)
	{
		if(*it == pi)
		{
			if(++it != piUsers.end())
			{
				return *it;
			}
			else
				return piUsers[0];
		}
	}
	return pi;
}
//移除一个
void RemovePlayerId(vector<enPlayerId>& piUsers,enPlayerId pi)
{
	for(vector<enPlayerId>::iterator it = piUsers.begin(); it != piUsers.end(); ++it)
	{
		piUsers.erase(it);
		break;
	}
}


void CPokerDesk::RobLord()
{
	m_nPoint = 1;
	vector<enPlayerId> piUsers;
	piUsers.push_back(piLeft);
	piUsers.push_back(piMiddle);
	piUsers.push_back(piRight);
	enPlayerId piNow,piNext;
	piNow = piNext = m_piDiscard;
	for(int i = 0; i < 5&&piUsers.size() > 1; i++)
	{
		piNow = piNext;
		if(m_players[piNow].RobLord())
		{
			m_piDiscard = m_piLastDiscard = m_piLord = piNow;
			m_nPoint = m_nPoint<<1;
			piNext=FindNextPlayerId(piUsers,piNext);
		}
		else
		{
			i--;
			piNext=FindNextPlayerId(piUsers,piNext);
			RemovePlayerId(piUsers,piNow);
		}
		cout<<"now the point is "<<m_nPoint<<endl;
	}
	for(int i = 0; i < m_lordcards.size(); i++)
		m_players[m_piLord].m_handcards.push_back(m_lordcards[i]);
	sort(m_players[m_piLord].m_handcards.begin(),m_players[m_piLord].m_handcards.end());
}
写完这个还要加上玩家。我设计的是两个机器人和一个玩家

头文件:

#pragma once
#include "Card.h"
#include <vector>
using namespace std;
enum{nInitPoint=1000};
class CPlayer
{
public:
	string m_strPlayerName;
	bool m_bAI;
	int m_nPoint;
	vector <CCard> m_handcards;
	CPlayer(string strName,bool bAI);
	CPlayer(void);
	~CPlayer(void);
	void Discard(vector<CCard>& cardSet,vector<CCard>& cardResSet);
	void CreateCards(vector<CCard>& cardSet,vector<CCard>& cardResSet);
	bool RemovePart(vector<CCard>& cardSet);
	bool RobLord();
	void CardTips(vector<CCard>& cardSet,vector<CCard>& cardResSet);
};
实现文件:

#include "Player.h"
#include "CardSet.h"
#include <iostream>
#include <string>
#include <time.h>
CPlayer::CPlayer(void)
{
	m_bAI = false;
	m_nPoint = nInitPoint;
	m_strPlayerName = "NoName";
}

CPlayer::CPlayer(string strName,bool bAI)
{
	m_bAI = bAI;
	m_strPlayerName = strName;
	m_nPoint = nInitPoint;
}

CPlayer::~CPlayer(void)
{
}
//出牌推断
void CPlayer::Discard(vector<CCard>& cardSet,vector<CCard>& cardResSet)
{
	//须要大于
	CreateCards(cardSet,cardResSet);
	if(cardResSet.empty())
		return;
	//输入
	CCardSet csLastCards(cardSet);
	CCardSet csMyCards(cardResSet);
	
	while(! (csLastCards < csMyCards&&RemovePart(cardResSet)))
	{
		CreateCards(cardSet,cardResSet);
		if(cardResSet.empty())
			return;
		csMyCards = CCardSet(cardResSet);
	}
}

void CPlayer::CreateCards(vector<CCard>& cardSet,vector<CCard>& cardResSet)
{
	if (m_bAI)
	{
		CCardSet csCards(cardSet),csCardsRes;
		do
		{
			cout<<"AI testing"<<endl;
			CardTips(cardSet,cardResSet);
			csCardsRes = CCardSet(cardResSet);
		}while(!(csCards < csCardsRes || cardResSet.empty()));
	}
	else
	{
		CCardSet csCards(cardSet),csCardsRes;
		do
		{
			std::cout<<"please input cards you want to deal"<<std::endl;
			string strCards;
			std::cin>>strCards;
			//remove invalid char
			cardResSet.clear();
			if(strCards.find('P')!= string::npos)
			{
				csCardsRes.m_cards.clear();
				csCardsRes.m_ctCardType = ctInvalid;
				continue;
			}
			//将字符串改为向量
			
			for(int i = 0; i < strCards.size(); i++)
			{
				CCard card(strCards[i]);
				cardResSet.push_back(card);
			}
			csCardsRes = CCardSet(cardResSet);
		}while(!(csCards < csCardsRes || cardResSet.empty()));
	}
}

//将已出的部分从手牌中删除
bool CPlayer::RemovePart(vector<CCard>& cardSet)
{
	vector<CCard> dmCardSet;
	dmCardSet.assign(m_handcards.begin(),m_handcards.end());
	for(vector<CCard>::iterator itc = cardSet.begin(); itc != cardSet.end(); ++itc)
	{
		bool bFind = false;
		for(vector<CCard>::iterator it = dmCardSet.begin(); it != dmCardSet.end(); ++it)
		{
			if(*it==*itc)
			{
				bFind = true;
				dmCardSet.erase(it);
				break;
			}
		}
		if(!bFind)
		{
			std::cout<<"error poker!"<<std::endl;
			return false;			
		}
	}
	swap(m_handcards,dmCardSet);
	return true;
}

bool CPlayer::RobLord()
{
	if(m_bAI)
	{
		srand(time(NULL));
		int nRob = rand()%2;
		if(nRob)
		{
			cout<<m_strPlayerName<<" rob the lord"<<endl;
			return true;
		}
		else
		{
			cout<<m_strPlayerName<<" give up the lord"<<endl;
			return false;
		}
	}
	else
	{
		cout<<"Do you want to rob the lord(y,n)?

"<<endl; char c; cin>>c; if(c == 'y'||c=='Y') { cout<<m_strPlayerName<<" rob the lord"<<endl; return true; } else { cout<<m_strPlayerName<<" give up the lord"<<endl; return false; } } } void CPlayer::CardTips(vector<CCard>& cardSet,vector<CCard>& cardResSet) { cardResSet.clear(); if(cardSet.empty()) { //double line //line //triple CCardSet csHandCard(m_handcards); if(CCardSet::FindLeastCards(csHandCard.m_mapcards,3,cardResSet)) { csHandCard.m_mapcards.erase(csHandCard.m_mapcards.find(cardResSet[0])); //double if(CCardSet::FindLeastCards(csHandCard.m_mapcards,2,cardResSet)) { return; } //single if(CCardSet::FindLeastCards(csHandCard.m_mapcards,1,cardResSet)) { return; } return; } //double if(CCardSet::FindLeastCards(csHandCard.m_mapcards,2,cardResSet)) { return; } //single if(CCardSet::FindLeastCards(csHandCard.m_mapcards,1,cardResSet)) { return; } cardResSet.push_back(m_handcards[0]); } else { CCardSet csCard(cardSet); CCardSet csHandCard(m_handcards); CCardSet csResCard; if(!csHandCard.FindBigger(csCard,csResCard)&&csCard.m_ctCardType!=ctBoom&&csCard.m_ctCardType!=ctRooket) { if(!csHandCard.FindBoom(csResCard)) csHandCard.FindRooket(csResCard); } swap(cardResSet,csResCard.m_cards); } }


对于每张牌。我定义了一个类进行管理,主要是控制显示和牌的值

头文件:

#pragma once
enum enCardName
{
	cnBlk3,
	cnRed3,
	cnFlr3,
	cnRct3,
	cnBlk4,
	cnRed4,
	cnFlr4,
	cnRct4,
	cnBlk5,
	cnRed5,
	cnFlr5,
	cnRct5,
	cnBlk6,
	cnRed6,
	cnFlr6,
	cnRct6,
	cnBlk7,
	cnRed7,
	cnFlr7,
	cnRct7,
	cnBlk8,
	cnRed8,
	cnFlr8,
	cnRct8,
	cnBlk9,
	cnRed9,
	cnFlr9,
	cnRct9,
	cnBlk10,
	cnRed10,
	cnFlr10,
	cnRct10,
	cnBlkJ,
	cnRedJ,
	cnFlrJ,
	cnRctJ,
	cnBlkQ,
	cnRedQ,
	cnFlrQ,
	cnRctQ,
	cnBlkK,
	cnRedK,
	cnFlrK,
	cnRctK,
	cnBlkA,
	cnRedA,
	cnFlrA,
	cnRctA,
	cnBlk2,
	cnRed2,
	cnFlr2,
	cnRct2,
	cnjoker,
	cnJoker,
	cnNull
};
class CCard
{
private:
	enCardName m_cnCardId; 
public:
	char m_cCard;
	CCard(enCardName cnId);
	CCard(char cCard);
	CCard(void);
	~CCard(void);
	bool operator<(const CCard& card)const;
	bool operator==(const CCard& card)const;
	bool IsNext(CCard card);
};

实现文件:

#include "Card.h"

CCard::CCard()
{
	m_cnCardId = cnNull;
	m_cCard = '\0';
}
CCard::CCard(char cCard)
{
	m_cCard = cCard;
	switch(m_cCard)
	{
	case '3':
		m_cnCardId = cnBlk3;
		break;
	case '4':
		m_cnCardId = cnBlk4;
		break;
	case '5':
		m_cnCardId = cnBlk5;
		break;
	case '6':
		m_cnCardId = cnBlk6;
		break;
	case '7':
		m_cnCardId = cnBlk7;
		break;
	case '8':
		m_cnCardId = cnBlk8;
		break;
	case '9':
		m_cnCardId = cnBlk9;
		break;
	case '0':
		m_cnCardId = cnBlk10;
		break;
	case 'J':
		m_cnCardId = cnBlkJ;
		break;
	case 'Q':
		m_cnCardId = cnBlkQ;
		break;
	case 'K':
		m_cnCardId = cnBlkK;
		break;
	case 'A':
		m_cnCardId = cnBlkA;
		break;
	case '2':
		m_cnCardId = cnBlk2;
		break;
	case 'z':
		m_cnCardId = cnjoker;
		break;
	case 'Z':
		m_cnCardId = cnJoker;
		break;
	}
}
CCard::CCard(enCardName cnId)
{
	m_cnCardId = cnId;
	switch(m_cnCardId)
	{
	case cnBlk3:
	case cnRed3:
	case	cnFlr3:
	case	cnRct3:
		m_cCard = '3';
		break;
	case	cnBlk4:
	case 	cnRed4:
	case	cnFlr4:
	case	cnRct4:
		m_cCard = '4';
		break;
	case 	cnBlk5:
	case 	cnRed5:
	case	cnFlr5:
	case	cnRct5:
		m_cCard = '5';
		break;
	case	cnBlk6:
	case	cnRed6:
	case	cnFlr6:
	case	cnRct6:
		m_cCard = '6';
		break;
	case	cnBlk7:
	case	cnRed7:
	case	cnFlr7:
	case	cnRct7:
		m_cCard = '7';
		break;
	case	cnBlk8:
	case	cnRed8:
	case	cnFlr8:
	case	cnRct8:
		m_cCard = '8';
		break;
	case	cnBlk9:
	case	cnRed9:
	case	cnFlr9:
	case	cnRct9:
		m_cCard = '9';
		break;
	case	cnBlk10:
	case	cnRed10:
	case	cnFlr10:
	case	cnRct10:
		m_cCard = '0';
		break;
	case	cnBlkJ:
	case	cnRedJ:
	case	cnFlrJ:
	case	cnRctJ:
		m_cCard = 'J';
		break;
	case	cnBlkQ:
	case	cnRedQ:
	case	cnFlrQ:
	case	cnRctQ:
		m_cCard = 'Q';
		break;
	case	cnBlkK:
	case	cnRedK:
	case	cnFlrK:
	case	cnRctK:
		m_cCard = 'K';
		break;
	case	cnBlkA:
	case	cnRedA:
	case	cnFlrA:
	case	cnRctA:
		m_cCard = 'A';
		break;
	case	cnBlk2:
	case	cnRed2:
	case	cnFlr2:
	case	cnRct2:
		m_cCard = '2';
		break;
	case	cnjoker:
		m_cCard = 'z';
		break;
	case	cnJoker:
		m_cCard = 'Z';
		break;
	default:
		m_cCard = '?';
	}
}


CCard::~CCard(void)
{
}

bool CCard::operator<(const CCard& card) const
{
	return m_cnCardId < card.m_cnCardId;
}

bool CCard::operator==(const CCard& card)const
{
	return m_cCard == card.m_cCard;
}
bool CCard::IsNext(CCard card)
{
	if(card.m_cnCardId >= cnBlk2)
		return false;
	if (card.m_cnCardId/4 - m_cnCardId/4 == 1)
		return true;
	return false;
}

最后是比較关键的牌型的推断,写得比較多,在推断跟牌上还没有写完,仅仅写了常见的几种牌型。像飞机和4带2就没有写。

头文件:

#pragma once
#include "Card.h"
#include <vector>
#include <map>
using namespace std;
enum enCardType
{
	ctSingle,
	ctDouble,
	ctTriple,
	ctTripleWithSingle,
	ctTripleWithDouble,
	ctPlane,
	ctSinglePlane,
	ctDoublePlane,
	ctLine,
	ctDoubleLine,
	ctBoom,
	ctRooket,
	ctQuatraWithTwo,
	ctQuatraWithTwoDouble,
	ctInvalid
};
class CCardSet
{
public:
	enCardType m_ctCardType;
	vector<CCard> m_cards;
	map<CCard,int> m_mapcards;
	CCard m_cardmain;
	CCardSet(vector<CCard>& cards);
	CCardSet(void);
	~CCardSet(void);
	bool operator<(const CCardSet& cardset) const;
	bool IsValid();
	enCardType GetCardType();
	bool FindBigger(CCardSet& cardset,CCardSet& cardsetbig);
	bool FindBoom(CCardSet& cardsetbig);
	bool FindRooket(CCardSet& cardsetbig);
	bool IsLine(vector<CCard>& cards);
	static bool FindLeastCards(map<CCard,int>& cardmap,int nCount,vector<CCard>& cardset);
};

实现文件:
#include "CardSet.h"
#include <algorithm>
CCardSet::CCardSet(vector<CCard>& cards)
{
	if(cards.empty())
	{
		m_ctCardType = ctInvalid;
		return;
	}
	m_cards.assign(cards.begin(),cards.end());
	for(vector<CCard>::iterator it = m_cards.begin(); it != m_cards.end(); ++it)
	{
		CCard tmpcard(it->m_cCard);
		map<CCard,int>::iterator l_it = m_mapcards.find(tmpcard);
		if(l_it == m_mapcards.end())
		{
			m_mapcards.insert(pair<CCard,int>(tmpcard,1));
		}
		else
		{
			l_it->second++;
		}
	}
	m_ctCardType = GetCardType();
	m_cardmain = m_mapcards.begin()->first;
	int nCount = m_mapcards.begin()->second;
	for(map<CCard,int>::iterator l_it = m_mapcards.begin();l_it != m_mapcards.end(); l_it++)
	{
		if(nCount < l_it->second)
			m_cardmain = l_it->first;
	}
}

CCardSet::CCardSet(void)
{
	m_cards.clear();
	m_ctCardType = ctInvalid;
}


CCardSet::~CCardSet(void)
{
}

bool CCardSet::operator<(const CCardSet& cardset) const
{
	if(cardset.m_ctCardType != ctInvalid&&m_cards.empty())
		return true;
	if(cardset.m_ctCardType == ctInvalid||m_ctCardType == ctInvalid)
		return false;
	if(cardset.m_cards.empty())
		return false;
	if(m_cards.empty())
		return true;
	if (cardset.m_ctCardType == ctRooket)
		return true;
	if(m_ctCardType == ctRooket)
		return false;
	if(cardset.m_ctCardType == ctBoom && m_ctCardType != ctBoom)
		return true;
	if(cardset.m_ctCardType != ctBoom && m_ctCardType == ctBoom)
		return false;
	if(cardset.m_ctCardType != m_ctCardType)
		return false;
	if(cardset.m_cards.size() != m_cards.size())
		return false;
	if(m_cardmain < cardset.m_cardmain)
		return true;
	else
		return false;
}

bool CCardSet::IsValid()
{
	if(m_ctCardType != ctInvalid)
		return true;
	else
		return false;
}
enCardType CCardSet::GetCardType()
{
	if(m_cards.size() == 1)
		return ctSingle;
	map<char,int> mapCards;
	for(vector<CCard>::iterator it = m_cards.begin(); it != m_cards.end(); ++it)
	{
		map<char,int>::iterator l_it = mapCards.find(it->m_cCard);
		if(l_it == mapCards.end())
		{
			mapCards.insert(pair<char,int>(it->m_cCard,1));
		}
		else
		{
			l_it->second++;
		}
	}
	int nCount[4] = {0};
	for(map<char,int>::iterator l_it = mapCards.begin(); l_it != mapCards.end(); ++l_it)
	{
		nCount[l_it->second-1]++;
	}
	if (nCount[3] > 1)
		return ctInvalid;
	if(nCount[3] == 1)
	{
		if(nCount[0] == 0&&nCount[1] == 0&&nCount[2] == 0)
			return ctBoom;
		if(nCount[0] == 2&&nCount[1] == 0&&nCount[2] == 0)
			return ctQuatraWithTwo;
		if(nCount[0] == 0&&nCount[1] == 2&&nCount[2] == 0)
			return ctQuatraWithTwoDouble;
		return ctInvalid;
	}
	if(nCount[2] > 1)
	{
		vector<CCard> tricard;
		for(map<char,int>::iterator l_it = mapCards.begin(); l_it != mapCards.end(); ++l_it)
		{
			if(l_it->second == 3)
			{
				CCard card(l_it->first);
				tricard.push_back(card);
			}
		}
		bool bLine = IsLine(tricard);
		if(bLine&&nCount[0] == 0&&nCount[1] == 0)
			return ctPlane;
		if(bLine&&nCount[0] == nCount[2]&&nCount[1] == 0)
			return ctSinglePlane;
		if(bLine&&nCount[0] == 0&&nCount[1] == nCount[2])
			return ctDoublePlane;
		return ctInvalid;
	}
	if(nCount[2] == 1)
	{
		if(nCount[0] == 0&&nCount[1] == 0)
			return ctTriple;
		if(nCount[0] == 1&&nCount[1] == 0)
			return ctTripleWithSingle;
		if(nCount[0] == 0&&nCount[1] == 1)
			return ctTripleWithDouble;
		return ctInvalid;
	}
	if (nCount[1] > 1)
	{
		if (nCount[0] > 0)
			return ctInvalid;
		if(nCount[1] == 2)
			return ctInvalid;
		//line
		vector<CCard> doucard;
		for(map<char,int>::iterator l_it = mapCards.begin(); l_it != mapCards.end(); ++l_it)
		{	
			if(l_it->second == 3)
			{
				CCard card(l_it->first);
				doucard.push_back(card);
			}
		}
		bool bLine = IsLine(doucard);
		if(bLine)
			return ctDoubleLine;
		return ctInvalid;
	}
	if (nCount[1] == 1)
	{
		if(nCount[0] == 0)
			return ctDouble;
		if (nCount[0] > 0)
			return ctInvalid;
	}
	if(nCount[0] > 1)
	{
		if(nCount[0] == 2&&m_cards[0].m_cCard == 'z'&&m_cards[1].m_cCard == 'Z')
			return ctRooket;
		if(nCount[0] < 5)
			return ctInvalid;
		bool bLine = IsLine(m_cards);
		if(bLine)
			return ctLine;
		return ctInvalid;
	}
	if(nCount[0] == 1)
		return ctSingle;
	return ctInvalid;
}
//
bool CCardSet::FindBigger(CCardSet& cardset,CCardSet& cardsetbig)
{
	if(cardset.m_ctCardType == ctInvalid)
		return false;
	map<CCard,int> mapCards;
	for(vector<CCard>::iterator it = m_cards.begin(); it != m_cards.end(); ++it)
	{
		CCard tmpcard(it->m_cCard);
		map<CCard,int>::iterator l_it = mapCards.find(tmpcard);
		if(l_it == mapCards.end())
		{
			mapCards.insert(pair<CCard,int>(tmpcard,1));
		}
		else
		{
			l_it->second++;
		}
	}
	switch(cardset.m_ctCardType)
	{
	case ctSingle:
		for(int i = 1; i < 4; i++)
		{
			for(map<CCard,int>::iterator it = mapCards.begin(); it != mapCards.end(); ++it)
			{
				if(it->second == i)
				{
					CCard tmpCard = it->first;
					if(cardset.m_cardmain.m_cCard != tmpCard.m_cCard && cardset.m_cardmain < tmpCard)
					{
						vector<CCard> tmpCards;
						tmpCards.push_back(tmpCard);
						cardsetbig = CCardSet(tmpCards);
						return true;
					}
				}
			}
		}
		break;
	case ctDouble:
		for(int i = 2; i < 4; i++)
		{
			for(map<CCard,int>::iterator it = mapCards.begin(); it != mapCards.end(); ++it)
			{
				if(it->second == i)
				{
					CCard tmpCard = it->first;
					if(cardset.m_cardmain.m_cCard != tmpCard.m_cCard && cardset.m_cardmain < tmpCard)
					{
						vector<CCard> tmpCards;
						for(int j = 0;j < 2; j++)
							tmpCards.push_back(tmpCard);
						cardsetbig = CCardSet(tmpCards);
						return true;
					}
				}
			}
		}
		break;
	case ctTriple:
		for(map<CCard,int>::iterator it = mapCards.begin(); it != mapCards.end();)
		{
			if(it->second != 3)
			{
				it = mapCards.erase(it);
			}
			else
				++it;
		}
		for(map<CCard,int>::iterator it = mapCards.begin(); it != mapCards.end(); ++it)
		{
			if(cardset.m_cardmain < it->first)
			{
				CCard tmpCard = it->first;
				vector<CCard> tmpCards;
				for(int j = 0;j < 3; j++)
					tmpCards.push_back(tmpCard);
				cardsetbig = CCardSet(tmpCards);
				return true;
			}
		}
		break;
	case ctTripleWithSingle:
		for(map<CCard,int>::iterator it = mapCards.begin(); it != mapCards.end(); ++it)
		{
			if(it->second == 3&&cardset.m_cardmain < it->first)
			{
				CCard tmpCard = it->first;
				vector<CCard> tmpCards;
				for(int j = 0;j < 3; j++)
					tmpCards.push_back(tmpCard);
				
				mapCards.erase(it);
				if(FindLeastCards(mapCards,1,tmpCards))
				{
					cardsetbig = CCardSet(tmpCards);
					return true;
				}
				else
				{
					return false;
				}
			}
		}
		break;
	case ctTripleWithDouble:
		for(map<CCard,int>::iterator it = mapCards.begin(); it != mapCards.end(); ++it)
		{
			if(it->second == 3&&cardset.m_cardmain < it->first)
			{
				CCard tmpCard = it->first;
				vector<CCard> tmpCards;
				for(int j = 0;j < 3; j++)
					tmpCards.push_back(tmpCard);
				
				mapCards.erase(it);
				if(FindLeastCards(mapCards,2,tmpCards))
				{
					cardsetbig = CCardSet(tmpCards);
					return true;
				}
				else
					return false;
			}
		}
		break;
	case ctPlane:
	case ctSinglePlane:
	case ctDoublePlane:
		break;
	case ctLine:
		for(map<CCard,int>::iterator it = mapCards.begin(); it != mapCards.end(); ++it)
		{
			if(cardset.m_cardmain < it->first)
			{
				map<CCard,int>::iterator it2 = it;
				it2++;
				int i = 1;
				CCard lastcard(it->first);
				vector<CCard> cards;
				cards.push_back(it->first);
				for(; i < cardset.m_cards.size()&&it2!=mapCards.end(); ++it2,++i)
				{
					cards.push_back(it2->first);
					if(!lastcard.IsNext(it2->first))
						break;
					lastcard = it2->first;
				}
				if(i == cardset.m_cards.size())
				{
					cardsetbig = CCardSet(cards);
					return true;
				}
			}
		}
		break;
	case ctDoubleLine:
		for(map<CCard,int>::iterator it = mapCards.begin(); it != mapCards.end();)
		{
			if(it->second == 1||it->second == 4)
			{
				it = mapCards.erase(it);
			}
			else
				++it;
		}
		for(map<CCard,int>::iterator it = mapCards.begin(); it != mapCards.end(); ++it)
		{
			if(cardset.m_cardmain < it->first)
			{
				map<CCard,int>::iterator it2 = it;
				it2++;
				int i = 1;
				CCard lastcard(it->first);
				vector<CCard> cards;
				for(int j = 0; j < 2; j++)
					cards.push_back(it->first);
				for(; i < cardset.m_cards.size()/2&&it2!=mapCards.end(); ++it2,++i)
				{
					for(int j = 0; j < 2; j++)
						cards.push_back(it2->first);
					if(!lastcard.IsNext(it2->first))
						break;
					lastcard = it2->first;
				}
				if(i == cardset.m_cards.size()/2)
				{
					cardsetbig = CCardSet(cards);
					return true;
				}
			}
		}
		break;
	case ctBoom:
		for(map<CCard,int>::iterator it = mapCards.begin(); it != mapCards.end();)
		{
			if(it->second < 4)
			{
				it = mapCards.erase(it);
			}
			else
				++it;
		}
		for(map<CCard,int>::iterator it = mapCards.begin(); it != mapCards.end(); ++it)
		{
			if(cardset.m_cardmain < it->first)
			{
				CCard tmpCard = it->first;
				vector<CCard> tmpCards;
				for(int j = 0;j < 4; j++)
					tmpCards.push_back(tmpCard);
				cardsetbig = CCardSet(tmpCards);
				return true;
			}
		}
		return false;
	case ctRooket:
		return false;
	case ctQuatraWithTwo:
	case ctQuatraWithTwoDouble:
		break;
	}
	return false;
}


bool CCardSet::IsLine(vector<CCard>& cards)
{
	sort(cards.begin(),cards.end());
	bool bLine = true;
	for(vector<CCard>::iterator it = cards.begin(); it != cards.end(); ++it)
	{
		if( it+1 != cards.end())
			if(!it->IsNext(*(it+1)))
				bLine = false;
	}
	return bLine;
}

bool CCardSet::FindBoom(CCardSet& cardsetbig)
{
	map<CCard,int> mapCards;
	for(vector<CCard>::iterator it = m_cards.begin(); it != m_cards.end(); ++it)
	{
		CCard tmpcard(it->m_cCard);
		map<CCard,int>::iterator l_it = mapCards.find(tmpcard);
		if(l_it == mapCards.end())
		{
			mapCards.insert(pair<CCard,int>(tmpcard,1));
		}
		else
		{
			l_it->second++;
		}
	}

	for(map<CCard,int>::iterator it = mapCards.begin(); it != mapCards.end();)
	{
		if(it->second < 4)
		{
			it = mapCards.erase(it);
		}
		else
			++it;
	}
	if(mapCards.size() > 0)
	{
		cardsetbig.m_cards.push_back(mapCards.begin()->first);
		cardsetbig.m_cards.push_back(mapCards.begin()->first);
		cardsetbig.m_cards.push_back(mapCards.begin()->first);
		cardsetbig.m_cards.push_back(mapCards.begin()->first);
		return true;
	}
	return false;
}

bool CCardSet::FindRooket(CCardSet& cardsetbig)
{
	int nSize = m_cards.size();
	if(nSize < 2)
		return false;
	if(m_cards[nSize-1].m_cCard == 'Z'&&m_cards[nSize-2].m_cCard == 'z')
	{
		cardsetbig.m_cards.push_back(m_cards[nSize-2].m_cCard);
		cardsetbig.m_cards.push_back(m_cards[nSize-1].m_cCard);
	}
	return false;
}

bool CCardSet::FindLeastCards(map<CCard,int>& cardmap,int nCount,vector<CCard>& cardset)
{
	for(int i = nCount; i < 4; i++)
	{
		for(map<CCard,int>::iterator it = cardmap.begin(); it != cardmap.end();++it)
		{
			if (it->second == i)
			{
				for(int j = 0; j < nCount; j++)
				{
					cardset.push_back(it->first);
				}
				return true;
			}
		}
	}
	return false;
}


相关文章:

  • 《计算机网络(第五版)》中学习理论与实践
  • ADB操作命令相关
  • IBM云对象存储Cleversafe 大力拓展全新战场
  • ETHERCHANNEL的配置
  • 使用 FreeMarker 替换 JSP 的 10 个理由
  • flex中textinput限制输入长度与某些字符
  • RxJava 2.x 使用最佳实践
  • 在Cisco路由器上实现PPTP server及 Radius认证
  • svn用户权限管理
  • Oracle数据库管理之创建和删除数据库
  • 浮点数溢出错误
  • BufferedReader的mask和reset
  • nginx学习1
  • 基于VML/SVG配电站接线系统
  • 为您的数据中心环境选择最合适的机架配电装置的最佳方案
  • 分享一款快速APP功能测试工具
  • $translatePartialLoader加载失败及解决方式
  • 2017 年终总结 —— 在路上
  • docker python 配置
  • download使用浅析
  • ES10 特性的完整指南
  • Java 最常见的 200+ 面试题:面试必备
  • JavaScript-Array类型
  • JavaScript实现分页效果
  • JS变量作用域
  • Linux快速复制或删除大量小文件
  • opencv python Meanshift 和 Camshift
  • Python学习笔记 字符串拼接
  • Redash本地开发环境搭建
  • 编写符合Python风格的对象
  • 理解在java “”i=i++;”所发生的事情
  • 前端学习笔记之观察者模式
  • 算法系列——算法入门之递归分而治之思想的实现
  • 一、python与pycharm的安装
  • 因为阿里,他们成了“杭漂”
  • 赢得Docker挑战最佳实践
  • hi-nginx-1.3.4编译安装
  • # Swust 12th acm 邀请赛# [ E ] 01 String [题解]
  • #NOIP 2014#Day.2 T3 解方程
  • #QT项目实战(天气预报)
  • $refs 、$nextTic、动态组件、name的使用
  • (9)YOLO-Pose:使用对象关键点相似性损失增强多人姿态估计的增强版YOLO
  • (AngularJS)Angular 控制器之间通信初探
  • (TipsTricks)用客户端模板精简JavaScript代码
  • (层次遍历)104. 二叉树的最大深度
  • (附源码)计算机毕业设计ssm基于Internet快递柜管理系统
  • (附源码)小程序儿童艺术培训机构教育管理小程序 毕业设计 201740
  • (南京观海微电子)——COF介绍
  • (七)理解angular中的module和injector,即依赖注入
  • (入门自用)--C++--抽象类--多态原理--虚表--1020
  • (一)Mocha源码阅读: 项目结构及命令行启动
  • ****** 二十三 ******、软设笔记【数据库】-数据操作-常用关系操作、关系运算
  • .NET HttpWebRequest、WebClient、HttpClient
  • .net php 通信,flash与asp/php/asp.net通信的方法
  • .NET 中小心嵌套等待的 Task,它可能会耗尽你线程池的现有资源,出现类似死锁的情况