斗地主52张牌,每行十三张,要有花色和牌号,怎么用vs实现?
//牌型枚举
enum CardTypes
{
Error_Card,//错误出牌
Single_Card,//单牌
Double_Card,//对子
Three_Card,//三张
ThreeOne_Card,//三带一
ThreeTwo_Card,//三代二
Line_Card,//单顺
Double_Line_Card,//连对
Plane_Card,//飞机(两个三张连)
Plane_TwoSingle_Card,//飞机带俩单
Plane_TwoDouble_Card,//飞机带两对
Four_TwoSingle_Card,//四带俩单
Four_TwoDouble_Card,//四带两对
Bomb_Card,//炸弹
Rocket_Card//王炸(火箭)
};
//牌值枚举
enum CardValue{
// 以下为牌的面值,从3开始
kCard_ValueLeast = 2,
kCard_Value3 = 3,
kCard_Value4 = 4,
kCard_Value5 = 5,
kCard_Value6 = 6,
kCard_Value7 = 7,
kCard_Value8 = 8,
kCard_Value9 = 9,
kCard_ValueT = 10,
kCard_ValueJ = 11,//J
kCard_ValueQ = 12,//Q
kCard_ValueK = 13,//K
kCard_ValueA = 14,//A
kCard_Value2 = 15,//2
kCard_ValueJoker1 = 16,//小王
kCard_ValueJoker2 = 17,//大王
kCard_ValueMax = 18,
kCard_TableMax = 20,
kCard_KindMax = 5,
// 特殊牌值
kCard_Joker1 = 53,
kCard_Joker2 = 54,
kCard_Flower = 55,
kCardMask_CardValue = 0x00ff, // 牌的面值
kCardMask_AnyMatch = 0x0100, // 任意配
kMaxCardNum = 56,
kMaxPlayers = 3,
// 牌型定义
kCardType_Single = 1, // 单纯类型, seriaNum == 1
kCardType_Serial = 2, // 单顺, 双顺, 三顺(飞机), 4顺
kCardType_Rocket = 3, // 火箭(大小王)
CarcAngle = 130 //牌的角度,另外两家的牌是倾斜的
};
//cardType是牌型,只有三种,王炸,单纯,连续;
//value 是牌型的值,单纯类型为牌的面值,连续类型为起始牌的面值,相同牌型以此比较大小;
//mainNum是主牌张数,比如三带二和飞机里mainNum=3, 连对时, mainNum=2;
//seralNum是连续张数,seralNum=1是单纯牌型,顺子时seralNum>=5;
//subNum是副牌数目,三带一和四带二时subNum=1,三带二和四带两对时,subNum=2;
//cards是牌型里包括的牌的牌值,比如三带一时,可能就是[3, 16, 42, 4], 连对时,可能就是 [3, 16, 4, 17, 5, 18, 6, 19]等等
//aggregate是权重,根据不同的情况求出权重,再按照权重排序所有牌型。可以是本牌型的权重,也可以是手牌里除了本牌型外剩下所有牌加在一起的权重。
struct CardNode {
int32_t cardType : 4;
int32_t mainNum : 4;
int32_t value : 10;
int32_t seralNum : 10;
int32_t subNum : 4;
float aggregate;
std::vector<int> cards;
public:
CardNode();
CardNode(int type, int val, int mainN, int len, int sub);
CardNode(const CardNode &other);
CardNode & operator = (const CardNode &other);
bool isValidNode() const;
void resetNode();
int getTopValue() const;
int getMaxCapacity() const;
void fillJokers() ;
void merge(const CardNode & other);
bool isRocket() const;
bool isBomb() const;
bool isExactLessThan(const CardNode & other) const;
bool isStrictLessThan(const CardNode &other) const;
float getPower() const;
bool operator < (const CardNode & other) const;
bool isEqualTo(const CardNode & other) const;
std::string description() const ;
};
//获取牌的面值
int getCardValue(int card) {
//55为花牌,本软件中没有用到
if (v == kCard_Flower) {
return kCard_ValueMax;
}
//为53即为小王
if (v == kCard_Joker1) {
return kCard_ValueJoker1;
}
//为54即为大王
if (v == kCard_Joker2) {
return kCard_ValueJoker2;
}
int t = v % 13;
//小于3为 A 2
if (t < 3) {
t += 13;
}
return t;
}
//手牌结构体
struct OneHand {
float totalPower;//权重
int handNum;//值
CardNode bestNode;//牌型(里面是哪些牌组成)
public:
OneHand():bestNode() {
totalPower = kMinPowerValue;
handNum = 0;
}
};
//游戏主控件类
class CardGame
{
public:
//当前位置0-自己 1-右边(下家) 2-左边(上家)
int curSeatId;
///一副牌
vector<int> allCards;
//过牌次数
int passtimes;
//叫地主的次数
int m_times;
//自己是否机器出牌
bool isRobotMode=false;
//是否开启音效
bool isSound=true;
//谁是地主
int landlordId;
//翻倍数 取决于叫的倍数和炸弹
int multiple;
//当前状态 0-发牌 1-叫分 2-出牌
int state;
//胜利id
int winId;
//底分
int scroe=1000;
//当前上家最大的牌,也就是自己要打他的牌
CardNode currCardNode;
//选手金币输赢统计,初始化100000
int handsScore[kMaxPlayers]={100000,100000,100000};
//选手名字,完全是瞎写 哈哈
string handName[3]={"Keepmoving","Lily","AngelaBaby"};
int minScore=50;//最低底分
int maxScore=5000;//最高底分
//记录打的牌
int playedCards[kCard_TableMax];
//选手牌数组
LordCards * seatHands[kMaxPlayers];
unordered_map<std::string, OneHand> * powerOfCards;
public:
//初始化
void init();
//获取一副打乱的扑克
vector<int> getCards();
};
//主牌类
class LordCards
{
public:
static int getMinSerialLength(int mainNum);
static int getMaxSubNum(int mainNum);
static int getDupSubNum(int mainNum);
static int getCardSuit(int card);
static int getCardValue(int v);
static bool updateHandForNode(OneHand & best, OneHand &left, CardNode & node, bool isTrim);
public:
LordCards(class CardGame * game,int id, const std::vector<int>&vec);
LordCards(class CardGame * game, int id,int cards[], int num);
~LordCards();
LordCards & operator = (const LordCards & other);
void assign(class CardGame * game, const std::vector<int>&vec);
void assign(class CardGame * game, int cards[], int num);
public:
float winRateIfLord();
bool bigEnough();
std::vector<int> removeSubset(const std::vector<int> & subset);
int scanToTable();
public:
std::string getKey(bool checkFlower, int &leastValue, int &maxCount);
bool containsFlower(int value, int num);
bool collectNode(CardNode & one, int value, int num);
OneHand calcPowerByRemoveNode(const CardNode & node);
void checkRocket (const std::string & key, OneHand & hand);
void checkBomb4 (const std::string & key, OneHand & hand, int top);
void checkSerial (const std::string & key, OneHand & hand, int top, int mainNum, int len, int subNum);
void checkSub (const std::string & key, OneHand & hand, int mainNum, int subNum, int poss);
OneHand calcPowerValue_noFlower();
OneHand calcPowerValue_expandAny(int countAny, int cardIndex);
OneHand calcPowerValue(bool checkFlower=false);
//打出牌
void playcards(CardNode cards);
CardNode typeAndValueFind();
public:
void collectAllNodes(std::set<CardNode> &possNodes, CardNode & node, int dup);
void sortByFactorInNodes(std::vector<CardNode> &allNodes, const CardNode & other, bool isDirect);
void getGreaterNodes_expandAny(int countAny, int cardIndex, std::set<CardNode> &possNodes, const CardNode &other);
void getGreaterNodes_possNode(std::set<CardNode> &possNodes, const CardNode &other);
std::vector<CardNode> getNodesGreaterThan(const CardNode & node);
//选择最好的出牌
CardNode getBestCardNode(CardNode simple=CardNode());
void getGreaterNodes_simple(std::set<CardNode> &possNodes, const CardNode &other);
int get_GroupData();
public:
class CardGame * theGame;
//位置ID
int id;
CardNode curretCardNode;
std::vector<int> theCards;
//叫地主的倍(1 2 3)
int multiple=-1;
//一共打了几手牌,用于算“春天”
int playTimes=0;
//权重
int cardWeight;
//排序
void sort();
std::vector<int> m_fillCards[kCard_TableMax];
//kCard_KindMax表示牌的面值大小
//kCard_KindMax
//0数组表示每张牌的数量
//1表示单张序列,顺子 值>4表示顺子
//2表示对子 值>1表示边对
//3三条 值为>1表示飞机
//4炸弹
int cardsTable[kCard_KindMax][kCard_TableMax]; // 保存每牌面值的数目,比如A的牌有几张
};