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


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

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

    这次主要是把跟牌和牌型的推断写出来了。写了一个比較弱智的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 = '';
    }
    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;
    }


  • 相关阅读:
    OpenJudge 2753 菲波那契数列
    Jmeter的介绍、安装及汉化
    spring集成Java性能监控调优工具-Javamelody
    js-xlsx + handsontable + echarts实现excel上传编辑然后显示成图表
    spring mybatis设置SQL语句打印
    Ribbon负载均衡策略详解
    JVM内存结构、Java内存模型以及Java对象模型之间的区别
    Java的自动拆装箱
    elasticsearch集群管理指南
    ElasticSearch最全分词器比较及使用方法
  • 原文地址:https://www.cnblogs.com/brucemengbm/p/7266656.html
Copyright © 2020-2023  润新知