这几天比較空,所以想写一点东西。
斗地主的程序一直以来都想写,但感觉规则推断比較复杂,一直没有较多的时间来写。
这次主要是把跟牌和牌型的推断写出来了。写了一个比較弱智的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;
}