#include <bits/stdc++.h>
    #define PLAYERCOUNT 3//三个玩家
    #define CARDSCOUNT 54//牌数
    #define CURRENTPLAYER 0
    #define VALUECOUNT 17//15种牌+空格+末尾结束'\0'
    #define ERROR -1

    using namespace std;
    const char toFigure[] = "34567890JQKA 2YZ";//牌,Y为小王,Z为大王
    //将A和2分隔开,如顺子等出牌类型不允许用2和大小王,同时支持读入空格

    enum COLOR { //枚举花色显示ASCII: 3~6
        HEART = 3, //红桃
        DIAMOND,//方片
        CLUB,   //梅花
        SPADE   //黑桃
    };

    class Card;//单牌参数
    class CardsType;//出牌类型
    class CardGroup;//出牌牌组
    class Player;//玩家手牌
    class Landlords;//地主
    class LastCards;//电脑出牌相关操作
    bool makeChoice(string tip);//玩家决定是否抢地主
    bool cmp(Card *a, Card *b);//比较点牌大小

    class Card {//记录单张牌的类

        public://声明公有成员
            char figure;//发牌的字母
            COLOR color;//定义一个枚举类型color
            int value;//单牌权重
            Card(char _figure, COLOR _color) {//赋值函数,赋值单张牌的大小和花色
                figure = _figure;
                color = _color;
                value = calValue();//记录该牌顺序编号,编号越大权重越大
            }
            int calValue() {
                for (int i = 0; toFigure[i]; i++) {//'\0'结束比较
                    if (toFigure[i] == figure) {//发的牌在15种牌中有
                        return i;//返回该牌顺序编号
                    }
                }
                return ERROR;//找完了15种牌也没有,返回错误
            }
            void print() {//输出该牌
                assert(value != ERROR);//如果未报错,程序正常运行,否则终止程序
                if (figure == 'Z') {
                    cout << "ZZ";
                } else if (figure == 'Y') {
                    cout << "YY";
                } else {
                    cout << figure;//输出牌号
                }
                cout << ' ';
            }
    };

    class CardsType {//记录出牌类型
        public:
            //为了规范查找对应牌的方法
            //统一为3个参数cnt1、isContinuous、cnt2
            int typeId;//出牌类型编号
            string typeStr;//出牌类型中文表示
            int cnt1, cnt2;
                    //几带几,cnt1记录主牌最小单位,如三带一==3,单牌==1.对子==2,王炸例外
            //cnt2记录带的牌最小单位(如四带两张单牌为1,炸弹带对子为2)
            bool isContinuous;
                    //是否为可改变出牌数类型出牌(如顺子、连对、飞机),是为TRUE
            CardsType() {
                typeId = ERROR;
            }
            bool operator ==(const CardsType &other)const {
                return this->typeId == other.typeId;//比较CardsType类中typeId
            }
            void init(char *_typeStr, int _typeId, int _cnt1, bool _isContinuous, int _cnt2) {
                //赋值函数,将出牌的参数一次性赋值
                cnt1 = _cnt1;
                isContinuous = _isContinuous;
                cnt2 = _cnt2;
                typeStr = _typeStr;
                typeId = _typeId;
            }
    };


    class CardGroup {//判断出牌类型等
        public:
            vector<Card *> cards;//定义card类型指针数组cards,用于记录出牌
            CardsType type;//定义CardsType类的type
            void calType() {//判断出牌类型函数
                int i, n = cards.size();//出牌数
                //init(typeStr,typeId,cnt1,isContinuous,cnt2)
                if (n == 0) {//没牌了,不出
                    type.init("不出", 14, 0, 0, 0);//不出为第15种出牌类型(typeId==14)
                    return;
                }
                if (n == 2 && cards[0]->value == 15 && cards[1]->value == 14) {//手上剩两张王
                    type.init("王炸", 0, 0, 0, 0);//王炸为第一种出牌类型(typeId==0)
                    return;
                }
                //统计同点数牌有多少张
                int cntFlag[VALUECOUNT] = {0};//定义17个计数器(15种类型的单牌)
                for (i = 0; i < n; i++) {
                    cntFlag[cards[i]->value]++;//编号为value的牌数量++
                }
                //统计点数最多和最少的牌
                int maxCnt = 0, minCnt = 4;//最多4张同点数牌,如此初始化minCnt计数器
                for (i = 0; i < VALUECOUNT; i++) {
                            //开始遍历数组找出出的牌中同点数牌最多的
                    if (maxCnt < cntFlag[i]) {
                        maxCnt = cntFlag[i];
                    }
                    if (cntFlag[i] && minCnt > cntFlag[i]) {
                        //同点数牌数量不为0,且大于minCnt计数器
                        minCnt = cntFlag[i];
                    }
                }
                if (n == 4 && maxCnt == 4) {//剩4张牌,且为炸弹
                    type.init("炸弹", 1, 4, 0, 0);
                    return;
                }
                if (n == 1) {
                    type.init("单牌", 2, 1, 0, 0);
                    return;
                }
                if (n == 2 && maxCnt == 2) {
                    type.init("对子", 3, 2, 0, 0);
                    //第4种出牌类型,出2+0张牌,不是可改变出牌数类型
                    return;
                }
                if (n == 3 && maxCnt == 3) {
                    type.init("三张 ", 4, 3, 0, 0);
                    return;
                }
                if (n == 4 && maxCnt == 3) {
                    type.init("三带一", 5, 3, 0, 1);
                    return;
                }
                if (n == 5 && maxCnt == 3 && minCnt == 2) {
                    type.init("三带一对", 6, 3, 0, 2);
                    return;
                }
                if (n == 6 && maxCnt == 4) {//出6张牌,其中有四张相同,一定为4带2
                    type.init("四带二", 7, 4, 0, 1);
                    return;
                }
                if (n == 8 && maxCnt == 4 && minCnt == 2) {//炸弹带对子
                    type.init("四带二", 8, 4, 0, 2);
                    return;
                }
                if (n >= 5 && maxCnt == 1 && cards[0]->value == cards[n - 1]->value + n - 1) {
                    //判断为顺子,出牌数==最大一张牌编号-最小张牌编号+1
                    type.init("顺子", 9, 1, 1, 0);
                    return;
                }
                if (n >= 6 && maxCnt == 2 && minCnt == 2 && cards[0]->value == cards[n - 1]->value + n / 2 - 1) {
                    type.init("连对", 10, 2, 1, 0);
                    return;
                }
                //以下单独判断飞机
                int fjCnt;//统计连续且大于三张的牌,附近count
                for (i = 0; i < VALUECOUNT && cntFlag[i] < 3; i++);
                //跳过非三张相同牌
                for (fjCnt = 0; i < VALUECOUNT && cntFlag[i] >= 3; i++, fjCnt++);
                //记录飞机里有几个三连
                if (fjCnt > 1) {//三连牌数大于1才算飞机
                    if (n == fjCnt * 3)//飞机不带
                        type.init("飞机", 11, 3, 1, 0);
                    else if (n == fjCnt * 4)//飞机带单牌,eg.999888777345
                        type.init("飞机", 12, 3, 1, 1);
                    else if (n == fjCnt * 5 && minCnt == 2)//飞机带对子
                        type.init("飞机", 13, 3, 1, 2);
                }
            }


            void init(string inputStr, vector<Card *> &cardsHolded) {
                //玩家输入字符串(出牌),目前手牌(数组记录)
                this->cards.clear();//先释放指针
                if (inputStr == "N") {
                    this->calType();//判断出牌类型
                    return;
                }
                int i, j;
                //输入合法性判断
                for (i = 0; i < inputStr.size(); i++) {//遍历出牌
                    bool find = false;
                    for (j = 0; toFigure[j]; j++) {
                        if (inputStr[i] == toFigure[j]) {//查找有无该牌种
                            find = true;
                            break;
                        }
                    }
                    if (find == false) {
                        //输入字符不在toFigure中
                        return;
                    }
                }
                //查找手中有没有这些牌
                int visitFlag[20] = {0};//记录手牌中存在的出牌(实际为bool类型数组)
                //最多出10连对,即20张牌
                for (i = 0; i < inputStr.size(); i++) {
                    Card *find = NULL;//指针记录出牌对应手牌地址
                    for (j = 0; j < cardsHolded.size(); j++) {//遍历手牌
                        if (!visitFlag[j] && cardsHolded[j]->figure == inputStr[i]) {
                            //如果手牌中存在该牌牌,且该牌未被记录
                            visitFlag[j] = 1;//存在该牌,赋值为TRUE
                            find = cardsHolded[j];//指针赋值
                            break;
                        }
                    }
                    if (find) {//找到不为空指针
                        this->cards.push_back(find);//
                    } else {
                        cout << inputStr[i];//没找到的牌
                        cout << "没有找到\t";
                        this->cards.clear();//释放指针
                        return;
                    }
                }//end for(i=0;i<inputStr.size();i++)
                this->arrange();//整理玩家出牌
            }


            void init(vector<Card *> newCards) {
                this->cards = newCards;
                this->arrange();//整理出牌牌组,见下方
            }


            bool isCanBeat(CardGroup &cardGroup) {//cardGroup为上家出牌
                //判断出牌能否打过上家,能则为TRUE
                if (cardGroup.type.typeStr == "王炸") {
                    return false;//上家出王炸,打不过
                } else if (this->type.typeStr == "王炸") {
                    return true;//我方出王炸,打得过
                } else if (cardGroup.type == this->type && this->type.typeStr == "炸弹") {
                    //都出炸弹
                    return value() > cardGroup.value();//判断谁的炸弹大
                } else if (cardGroup.type.typeStr == "炸弹") {
                    return false;//上家炸弹,我方非王炸/炸弹,打不过
                } else if (this->type.typeStr == "炸弹") {
                    return true;//上家非炸弹,我方炸弹,TRUE
                } else if (cardGroup.type == this->type && this->cards.size() == cardGroup.cards.size()) {
                    //出同类型牌且牌数相同(比如334455和556677)
                    return this->value() > cardGroup.value();
                } else {
                    return false;
                }
            }


            int value() {//计算牌组权值
                int i;
                if (type.typeStr == "三带一" || type.typeStr == "三带一对" || type.typeStr == "飞机") {
                    for (i = 2; i < cards.size(); i++) {
                        if (cards[i]->value == cards[i - 2]->value) {
                            //由于不确定cards中主牌位置,故先判断找出三连牌。如34445,66888
                //三带几出牌类型以主牌权重为牌组权值,飞机以最小三连为主牌权值。
                            return cards[i]->value;//返回主牌编号
                        }
                    }
                }
                if (type.typeStr == "四带二") {
                    for (i = 3; i < cards.size(); i++) {
                        if (cards[i]->value == cards[i - 3]->value) {
                            return cards[i]->value;
                                 //四带二以主牌权重为牌组权重
                        }
                    }
                }
                return cards[0]->value;
            }


            void arrange() {
                //整理工作:排序,然后计算出牌类型
                sort(this->cards.begin(), this->cards.end(), cmp);
                this->calType();
            }
    };

    class LastCards {//电脑出牌相关操作
            static LastCards *lastCards;//定义电脑出牌牌组指针
        public:
            Player *player;
            CardGroup cardGroup;
            static LastCards *inst() {//单例模式
                if (lastCards == NULL) {
                    lastCards = new LastCards();
                }
                return lastCards;
            }

            vector<Card *> findCanBeatFrom(vector<Card *> &cardsHolded) {
                //查找能打得过的牌
                int i, j, k, n = cardsHolded.size(), m = cardGroup.cards.size();
                string typeStr = cardGroup.type.typeStr;
                //强制规定电脑本次出牌类型为上家(玩家/机器人1号)


                vector<Card *> ret;//定义一个空指针便于在打不过时“不出”
                if (typeStr == "王炸" || n < m) {
                    //打不过,返回空数组指针
                    return ret;
                }

                int value = cardGroup.value();//记录上家出牌牌组权值

                //以下统计各点牌出现的次数
                int cntFlag[VALUECOUNT] = {0};//初始化各点牌为0张
                for (i = 0; i < n; i++) {
                    cntFlag[cardsHolded[i]->value]++;//统计各点牌数
                }
                int continuousCount = 1;//便于记录要出几连对/顺/飞机
                if (cardGroup.type.isContinuous) {
                            //如果为可增出牌类型(连对、顺子等)
                    continuousCount = m / (cardGroup.type.cnt1 + cardGroup.type.cnt2);
                }//m为上家出牌总数


                bool findFirstFigure;
                            //是否找到第一张符合出牌类型且大于上家出牌权值的主牌
                //cout<<"continuousCount="<<continuousCount<<endl;
                for (i = value + 1; i < VALUECOUNT; i++) {
                    //从15种牌的上家主牌开始对比寻找
                    findFirstFigure = true;
                    for (j = 0; j < continuousCount; j++) {
                        if (cntFlag[i - j] < cardGroup.type.cnt1) {
                        //如果牌值大于等于上家但是数量不够凑成类型,false
                            findFirstFigure = false;
                            break;
                        }
                    }

                    //记录电脑出牌
                    if (findFirstFigure) {
                        ret.clear();//释放空指针
                        int firstFigure = i;//第一张要出的牌
                        //cout<<"查找"<<cardGroup.type.cnt1<<"个"<<firstFigure+3<<endl;
                        for (k = 0, j = 0; k < cardsHolded.size() && j < continuousCount; k++) {
                            if (cardsHolded[k]->value == firstFigure - j) {//
                                for (int kk = 0; j >= 0 && kk < cardGroup.type.cnt1; kk++) {
                                    ret.push_back(cardsHolded[k + kk]);
                                }
                                j++;
                            }
                        }
                        if (cardGroup.type.cnt2 > 0) {//如果带了牌
                            int SecondFigures[5];
                                                    //记录第二出牌牌组(最多带5种牌)
                            int SecondCount = continuousCount;
                            //初始化默认带的牌数量等于主牌种类数量
                            if (cardGroup.type.typeStr == "四带二")
                                SecondCount = 2;//四带二例外


                            bool findSecondFigure = true;
                                                    //判断能否满足带牌条件,几乎同上
                            for (j = 0, k = -1; j < SecondCount && findSecondFigure; j++) {
                                findSecondFigure = false;
                                for (k++; k < VALUECOUNT; k++) {
                                    SecondFigures[j] = k;
                                    if (cntFlag[k] >= cardGroup.type.cnt2 && cntFlag[k] < cardGroup.type.cnt1) {
                                        findSecondFigure = true;
                                        break;
                                    }
                                }
                            }
                            if (findSecondFigure) {//确认找到能出的副牌
                                //cout<<"查找SecondFigure "<<cardGroup.type.cnt2<<"个"<<SecondFigures[0]+3<<endl;
                                //cout<<"SecondCount= "<<SecondCount<<endl;
                                //for(i=0;i<SecondCount;i++)cout<<"SecondFigures["<<i<<"]="<<SecondFigures[i]<<endl;
                                for (i = 0; i < SecondCount; i++) {
                                    for (j = 0; j < cardsHolded.size();) {
                                        if (cardsHolded[j]->value == SecondFigures[i]) {
                                            for (k = 0; k < cardGroup.type.cnt2; k++) {
                                                //cout<<"添加"<<cardsHolded[j]->value+3<<endl;
                                                ret.push_back(cardsHolded[j + k]);
                                            }
                                            do {
                                                j++;
                                            } while (j < cardsHolded.size() && cardsHolded[j]->value == SecondFigures[i]);
                                        } else {
                                            j++;
                                        }
                                    }
                                }
                                return ret;
                                                            //将做好的出牌牌组返回,否则返回空
                            }//if(findSecondFigure)
                        }//end if(cardGroup.type.cnt2>0)
                        else {
                            return ret;//没带牌则直接返回空
                        }
                    }//end if(findFirstFigure)先有主牌才用找副牌
                }//end for(i=value+1;i<VALUECOUNT;i++)
                ret.clear();//释放牌组养成习惯

                //没牌打得过时查找有没有炸弹
                if (typeStr != "炸弹") {
                    for (i = cardsHolded.size() - 1; i >= 3; i--) {
                        if (cardsHolded[i]->value == cardsHolded[i - 3]->value) {
                            //如果找到炸弹(四连牌)
                            for (j = 0; j < 4; j++) {
                                ret.push_back(cardsHolded[i - j]);
                            }
                            return ret;
                        }
                    }
                }
                //寻找王炸保底
                bool Y=0,Z=0;
                    for(i = cardsHolded.size() - 1; i >=0; i--){
                        if(cardsHolded[i]->value==14){
                            Y=1;
                        }else if(cardsHolded[i]->value==15){
                            Z=1;
                        }
                    }
                    i = cardsHolded.size() - 1;
                    if(Y==1&&Z==1){
                        for(j=0;j<2;j++){
                            ret.push_back(cardsHolded[i-j]);
                        }
                    }
                return ret;
            }//end vector<Card*> findCanBeatFrom()
    };

    LastCards *LastCards::lastCards = NULL;

    class Player {//整理牌组和输出部分
        public:
            string name;
            vector<Card *> cards;
            void arrange() {
                sort(cards.begin(), cards.end(), cmp);
            }
            void print() {//输出手牌
                cout << this->name << ":\t";
                for (int i = 0; i < cards.size(); i++) {
                    cards[i]->print();
                }
                cout << "[" << cards.size() << "]\n";//牌数
            }

            vector<Card *> tip() {
                //提示功能,使自己最小一张连最长
                CardGroup ret;
                string temp;
                int j, k, m = cards.size();
                for (j = 0; j < m; j++) {
                    temp = "";
                    for (k = j; k < m; k++) {
                        temp += cards[k]->figure;
                    }
                    ret.init(temp, cards);
                    if (ret.type.typeId != ERROR) {
                        return ret.cards;
                    }
                }
                ret.cards.clear();
                return ret.cards;
            }

            void chupai(CardGroup &cardGroup) {
                //出牌
                cout << this->name << ":\t";
                cout << cardGroup.type.typeStr << ' ';
                for (int i = 0; i < cardGroup.cards.size(); i++) {
                    cardGroup.cards[i]->print();
                    this->cards.erase(find(this->cards.begin(), this->cards.end(), cardGroup.cards[i]));
                }
                cout << "\t[" << this->cards.size() << "]\n";
                if (cardGroup.type.typeStr != "不出") {
                    //记录到 LastCards 中
                    LastCards::inst()->player = this;
                    LastCards::inst()->cardGroup.init(cardGroup.cards);
                }
            }
    };

    class Landlords {//玩家操作及初始化部分
            Player *player[PLAYERCOUNT];//创建三个玩家class Player
            bool finished, youWin, landlordWin;
            //finished游戏是否结束,landlord地主
            int landlordIndex;
            Card *cards[CARDSCOUNT];//创建54张牌牌组
        public:
            Landlords() {
                int i, j, k;
                for (i = 0; i < PLAYERCOUNT; i++) {
                    this->player[i] = new Player();
                }
                //54张牌初始化
                for (k = i = 0; i < 14; i++) {
                    if (toFigure[i] == ' ') {//遇到中间的空格跳过
                        continue;
                    }
                    for (COLOR color = HEART; color <= SPADE; color = (COLOR)(color + 1)) {
                        this->cards[k++] = new Card(toFigure[i], color);
                                            //赋予花色
                    }
                }
                this->cards[k++] = new Card('Y', SPADE);
                this->cards[k] = new Card('Z', HEART);
            }
            ~Landlords() {
                for (int i = 0; i < PLAYERCOUNT; i++) {
                    delete this->player[i];
                }
                for (int i = 0; i < CARDSCOUNT; i++) {
                    delete this->cards[i];
                }
            }
            void init() {
                player[CURRENTPLAYER]->name = "Bice";
                player[1]->name = "玩家2";
                player[2]->name = "玩家3";
                finished = false;
                youWin = false;
                landlordWin = false;


                //抢地主
                landlordIndex = ERROR;
                while (landlordIndex == ERROR) {
                    srand((int)time(0));//随机函数
                    shuffle();//洗牌发牌
                    landlordIndex = chooseLandlord();//记录地主的玩家编号
                }
                cout << player[landlordIndex]->name << "\t成为地主\n\n";
                this->add3Cards();//地主加三张牌
                LastCards::inst()->player = player[landlordIndex];
                            //地主牌赋给玩家指针
            }


            void startGame() {
                string inputSrt;//记录玩家输入字符串
                CardGroup inputCards;
                for (int iTurns = landlordIndex; !finished; iTurns++) {
                    //iTurns一轮内轮到玩家次数,从地主开始出牌
                    if (iTurns >= PLAYERCOUNT) {//三人走完
                        iTurns = 0;//再次地主出牌
                    }
                    if (iTurns == CURRENTPLAYER) {//轮到玩家
                        cout << endl;
                        player[iTurns]->print();
                        cout << "输入提示:Z=大王 Y=小王 0=10 输入可无序 :=不出 例如:JKQ0A9\n请出牌:\t";
                        do {
                            cin >> inputSrt;//读牌
                            inputCards.init(inputSrt, player[iTurns]->cards);
                        } while (check(&inputCards) == false);//检查输入直到正确出牌
                    } else {
                        if (player[iTurns] == LastCards::inst()->player) {
                            //若是上次出牌的是自己,启用提示功能
                            inputCards.init(player[iTurns]->tip());
                        } else {
                            //查找能打得过上家的牌
                            inputCards.init(LastCards::inst()->findCanBeatFrom(player[iTurns]->cards));
                        }
                    }
                    player[iTurns]->chupai(inputCards);//出牌

                    if (player[iTurns]->cards.size() == 0) {
                        //玩家手中没牌了,游戏结束
                        finished = true;
                        landlordWin = iTurns == landlordIndex;
                        if (landlordWin) {//地主赢了
                            youWin = landlordIndex == CURRENTPLAYER;//'我'是地主,youwin==1 or==0
                        } else {//农民赢了
                            youWin = landlordIndex != CURRENTPLAYER;
                        }
                    }
                }
                cout << "\n_________________________ " << (youWin ? "You Win!" : "You Lose!") << " _________________________\n\n";
            }
            void add3Cards() {
                cout << "地主3张牌:\t";
                for (int i = PLAYERCOUNT * 17; i < CARDSCOUNT; i++) {
                    this->cards[i]->print();//输出地主的三张牌
                    player[landlordIndex]->cards.push_back(cards[i]);
                }
                cout << endl;
                player[landlordIndex]->arrange();
            }

            int chooseLandlord() {//抢地主函数
                cout << "\n_________________________ 抢地主 _________________________\n\n";
                int first = -1, last, cnt = 0, i, j = rand() % PLAYERCOUNT;
                bool decision;
                for (i = 0; i < PLAYERCOUNT; i++, j == 2 ? j = 0 : j++) {
                    if (j == CURRENTPLAYER) {
                        decision = makeChoice("是否抢地主?(Y=抢/N=不抢):");
                    } else {
                        decision = rand() % 2;//随机两个人机是否抢地主
                    }
                    if (decision) {
                        cnt++;
                        last = j;
                        if (first == -1) {
                            first = j;
                        }
                        cout << this->player[j]->name << "\t抢地主\n";
                    } else {
                        cout << this->player[j]->name << "\t没有抢\n";
                    }
                }
                if (cnt == 0) {
                    cout << "没人抢,重新发牌\n";
                    return ERROR;
                }
                if (cnt == 1) {
                    //第一轮只有一人抢地主
                    return first;
                } else {
                    //最后一次争抢
                    if (first == CURRENTPLAYER) {
                        decision = makeChoice("是否抢地主?(Y=抢/N=不抢):");
                    } else {
                        decision = rand() % 2;
                    }
                    if (decision) {
                        cout << this->player[first]->name << "\t抢地主\n";
                        return first;
                    } else {
                        cout << this->player[first]->name << "\t没有抢\n";
                        return last;
                    }
                }
            }
            void shuffle() {
                //洗牌
                int i, j, k;
                for (i = 0; i < CARDSCOUNT; i++) {
                    swap(this->cards[i], this->cards[rand() % CARDSCOUNT]);
                }

                //分牌
                for (k = i = 0; i < PLAYERCOUNT; i++) {
                    this->player[i]->cards.clear();
                    for (j = 0; j < 17; j++) {
                        this->player[i]->cards.push_back(this->cards[k++]);
                    }
                    this->player[i]->arrange();//整理 
                }
                this->player[0]->print();//显示玩家抽到的牌
            }

            bool check(CardGroup *cardGroup) {//出牌错误时反馈
                if (cardGroup->type.typeId == ERROR) {
                    cout << "出牌错误,重新输入\n";
                    return false;
                } else if (cardGroup->type.typeStr == "不出") {
                    return true;
                } else if (LastCards::inst()->player != player[CURRENTPLAYER] && !cardGroup->isCanBeat(LastCards::inst()->cardGroup)) {
                    cout << "打不过,重新输入\n";
                    return false;
                } else {
                    return true;
                }
            }
    };


    bool makeChoice(string tip) {
        cout << tip;
        string input;
        cin >> input;
        return input == "Y" || input == "y";//大小写宽容
    }

    bool cmp(Card *a, Card *b) {
        //比较两张牌大小
        if (a->value == b->value) {
            return a->color > b->color;//同点数按花色排序
        } else {
            return a->value > b->value;
        }
    }

    int main() {
        Landlords *landlords = new Landlords();
        do {
            landlords->init();//发牌、抢地主
            landlords->startGame();//游戏开始
        } while (makeChoice("\n是否继续游戏?(Y=继续/N=结束): "));
        delete landlords;//释放缓存
        return 0;
    }
Last modification:November 17, 2023
我很可爱,请给我钱。