m0_74141516 2022-12-18 11:06 采纳率: 81.8%
浏览 13
已结题

c++怎么实现洗牌?

斗地主52张牌,每行十三张,要有花色和牌号,怎么用vs实现?

  • 写回答

2条回答 默认 最新

  • .LAL. C/C++领域新星创作者 2022-12-18 12:28
    关注
    
    //牌型枚举
    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的牌有几张
    };
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

问题事件

  • 系统已结题 8月31日
  • 已采纳回答 8月23日
  • 创建了问题 12月18日

悬赏问题

  • ¥15 两台交换机分别是trunk接口和access接口为何无法通信,通信过程是如何?
  • ¥15 C语言使用vscode编码错误
  • ¥15 用KSV5转成本时,如何不生成那笔中间凭证
  • ¥20 ensp怎么配置让PC1和PC2通讯上
  • ¥50 有没有适合匹配类似图中的运动规律的图像处理算法
  • ¥15 dnat基础问题,本机发出,别人返回的包,不能命中
  • ¥15 请各位帮我看看是哪里出了问题
  • ¥15 vs2019的js智能提示
  • ¥15 关于#开发语言#的问题:FDTD建模问题图中代码没有报错,但是模型却变透明了
  • ¥15 uniapp的h5项目写一个抽奖动画