德州扑克C++实现

游戏介绍

  • 游戏介绍链接
  • 简单介绍:
    从上到下分别是:同花顺、四条、三带二、同花、顺子、三带一、两对、一对、杂牌。A可以当1和14。

德州扑克C++实现_第1张图片

德州扑克C++实现_第2张图片
德州扑克C++实现_第3张图片
德州扑克C++实现_第4张图片

德州扑克C++实现_第5张图片
德州扑克C++实现_第6张图片
德州扑克C++实现_第7张图片
德州扑克C++实现_第8张图片

德州扑克C++实现_第9张图片

编程实现

程序分析
PockerGame.hpp:实现具体游戏流程,对洗牌、发牌、码牌、判断输赢等操作进行控制。

Card.hpp:实现对卡片花色、卡片数值的定义和打印等操作。需要注意,在windows 下需要用chcp 65001切换到UTF-8的CMD输出格式。

Deck.hpp:实现了洗牌算法和发牌操作。

Player.hpp:实现玩家类,记录玩家的手牌、判断玩家的最好手牌,玩家资金、信息管理等操作。

PokerHand.hpp:持有五张牌,实现对这五张排的大小等级的判断,其中需要注意A的两种情况。
编程实现
PokerGame.cpp

#include "Player.hpp"
#include "Deck.hpp"

class PokerGame{
public:
    PokerGame(int playerNumber) : ante(2){
        //init player
        for(int i = 0;i < playerNumber;i++){
            Player player(i+1);
            players.push_back(player);
        }
    }

    //starting game
    void start(){
        //clear buffer
        board.clear();
        for(auto &player:players){
            player.clearHandCard();
        }
        deck.shuffle();

        //get ante and deal
        double allBonus = 0;
        for(auto &player : players){
            //bet down
            player.loss(ante);
            allBonus += ante;
            //dealing
            player.putCard(deck.getCard());
            player.putCard(deck.getCard());
        }
        std::cout<<"Community Cards :";
        for(int i = 0; i < 5; i++){
            board.push_back(deck.getCard());
            std::cout< allBestPokerHand;
        for(auto &player : players){
            //get all best hand
            allBestPokerHand.push_back(player.getBestPokerHand(board));

            //print player message
            player.printPlayerInfo();
            player.printHandCards();
            std::cout< winnerIndex;
        winnerIndex.push_back(0);
        PokerHand *bestHand = &allBestPokerHand[0];
        for(int i = 1; i < players.size(); i++){
            if(*bestHand < allBestPokerHand[i]){
                winnerIndex.clear();
                winnerIndex.push_back(i);
                bestHand = &allBestPokerHand[i];
            } else if (*bestHand == allBestPokerHand[i]){
                winnerIndex.push_back(i);
            }
        }

        //giving bonus
        double bonus  = allBonus / winnerIndex.size();
        for(int index:winnerIndex){
            players[index].earn(bonus);
        }

        //print winner
        if(winnerIndex.size() > 1){
            std::cout<<"Winning hands (tie)"< players;
    std::vector board;
    Deck deck;
    int ante;
};

Card.hpp

#include 
#include 
// Model the Suit of a Poker Card
enum class Suit {
    CLUBS, DIAMONDS, HEARTS, SPADES
};
// TODO: add enum class Rank
enum class Rank {
    //ACE can be one or greater than KING
    DEUCE=2, THREE, FOUR, FIVE, SIX, SEVEN, EIGHT, NINE, TEN, JACK, QUEEN, KING, ACE
};
// TODO: add class Card
class Card{
public:
    Card(Rank rank, Suit suit):c_rank(rank), c_suit(suit){

    }
    std::string toString(){
        std::string mark;
        switch (c_suit){
            case Suit::CLUBS:
                mark = "\xe2\x99\xa3";
                break;
            case Suit::DIAMONDS:
                mark = "\xe2\x99\xa6";
                break;
            case Suit::HEARTS:
                mark = "\xe2\x99\xa5";
                break;
            case Suit::SPADES:
                mark = "\xe2\x99\xa0";
                break;
            default:
                break;
        }
        std::string rankMark;
        if(getValue() <= 10){
            rankMark = std::to_string(getValue());
        } else {
            switch(c_rank){
                case Rank::ACE :
                    rankMark = "A";
                    break;
                case Rank::JACK :
                    rankMark = "J";
                    break;
                case Rank::QUEEN :
                    rankMark = "Q";
                    break;
                case Rank::KING :
                    rankMark = "K";
                default:
                    break;
            }
        }
        return (rankMark + mark);
    }
    Rank getRank(){
        return c_rank;
    }
    Suit getSuit(){
        return c_suit;
    }
    int getValue()const{
        return (int)c_rank;
    }
    //overload  "<"
    bool operator< (const Card other) const {
        return (this->getValue() < other.getValue());
    }
    Card&operator= (const Card& other){
        this->c_rank = other.c_rank;
        this->c_suit = other.c_suit;
        return *this;
    }

    Rank c_rank;
    Suit c_suit;
};

Deck.hpp

#include "Card.hpp"
#include 
#include 
class Deck{
public:
    Deck():countDealCards(0){
        //init all cards
        for(int i = 2; i < 14; i++){
            Rank rank;
            rank = Rank(i);
            for(int j = 0; j < 4; j++){
                Suit suit;
                suit = Suit((j));
                Card singleCard(rank,suit);
                allCards.push_back(singleCard);
            }
        }
    }

    void shuffle(){
        //shuffle algorithm
        srand((unsigned)time(nullptr));
        for(int i = 0; i < allCards.size(); i++){
            int seed = rand()%(allCards.size() - 1);
            Card temp = allCards[seed];
            allCards[seed] = allCards[i];
            allCards[i] = temp;
        }
        //init counter
        countDealCards = 0;
    }

    //get card in the Deck
    Card getCard(){
        return allCards[countDealCards++];
    }
private:
    std::vector allCards;
    int countDealCards;
};

Player.hpp

#include "Card.hpp"
#include "PokerHand.hpp"
#include 

class Player{
public:
    Player(int ID, double money = 100):playerID(ID),money(money){
    }
    // earn bonus
    void earn(double bonus){
        money += bonus;
    }

    //loss money
    void loss(double betMoney){
        money -= betMoney;
    }

    //get card from deck
    void putCard(Card card){
        if(handCards.size() > 2){
            std::cout<<"ERR deal cards error!/n";
        } else{
            handCards.push_back(card);
        }
    }

    //get best pokerHand in 7 cards
    PokerHand getBestPokerHand(std::vector communityCards){
        std::vector allSituations;
        //std::cout<<"Size1:"< MatchIndex;
                for(int j = 0; j < 5; j++){
                    if(j != i){
                        MatchIndex.push_back(j);
                    }
                }
                PokerHand hand(card, communityCards[MatchIndex[0]], communityCards[MatchIndex[1]], communityCards[MatchIndex[2]], communityCards[MatchIndex[3]]);
                allSituations.push_back(hand);
            }
        }

        //another ten situations
        for(int i = 0; i < 4; i++){
            for (int j = i+1; j < 5; j++){
                std::vector MatchIndex;
                for(int k = 0;k < 5;k++){
                    if((k != i) && (k != j)){
                        MatchIndex.push_back(k);
                    }
                }
                PokerHand hand(handCards[0], handCards[1], communityCards[MatchIndex[0]], communityCards[MatchIndex[1]], communityCards[MatchIndex[2]]);
                allSituations.push_back(hand);
            }
        }

        //find the best situation
        std::sort(allSituations.begin(),allSituations.end());
        PokerHand best = allSituations.back();
        //best.printMesg();
        return best;
    }

    //print player message
    void printPlayerInfo(){
        std::cout<<"Player "< handCards;
};

PokerHand.hpp

#include "Card.hpp"
#include 
#include 
enum class Priority{
    isStraightFlush, isFourOfAKind, isFullHouse, isFlush, isStraight, isThreeOfAKind, isTwoPair, isOnePair, isHighCard
};
class PokerHand{
public:
    PokerHand(Card card1, Card card2, Card card3, Card card4, Card card5){
        handCard.push_back(card1);
        handCard.push_back(card2);
        handCard.push_back(card3);
        handCard.push_back(card4);
        handCard.push_back(card5);
        std::sort(handCard.begin(), handCard.end());
        checkHandCard();
    }
    //overload "=="
    bool operator == (const PokerHand& other)const{
        for(int i = 0; i < handCard.size(); i++){
            if(handCard[i].getValue() != other.handCard[i].getValue()){
                return false;
            }
        }
        return true;
    }
    PokerHand& operator = (const PokerHand &other){
        //PokerHand newHand()
        this->handCard = other.handCard;
        this->cardType = other.cardType;
        this->sameCard = other.sameCard;
        return *this;
    }
    //overload "<"
    bool operator <(const PokerHand& other)const {
        //std::sort(handCard.begin(), handCard.end());
        //checkHandCard();
        if(*this == other){
            return false;
        }
        if(cardType > other.cardType){
            return true;
        }else if(((int)this->cardType == (int)other.cardType)){
            bool isLess = true;

            for(int i = this->sameCard.size()-1; i >= 0; i--){

                if(this->sameCard[i][0].getValue() > other.sameCard[i][0].getValue()){
                    isLess =  false;
                    break;
                } else if(this->sameCard[i][0].getValue() < other.sameCard[i][0].getValue()){
                    isLess = true;
                    break;
                }
            }
            return isLess;
        } else{
            return false;
        }
    }
    //print BestHand
    void printMesg(){
        for(auto &card : handCard){
            std::cout< handCard;
    Priority cardType;
    //put same cards into a vector
    std::vector> sameCard;
private:

    //check hand cards rank
    void checkHandCard(){
        sameCard.clear();
        bool isStraight = true;
        bool isFlush = true;
        bool isLowAceStraight = false;
        if(handCard[0].getValue() == 2 && handCard[1].getValue() == 3 && handCard[2].getValue() == 4 && handCard[3].getValue() == 5 && handCard[4].getValue() == 14){
            isLowAceStraight = true;
        }
        //check card property
        for (int i = 0; i < handCard.size(); ++i) {
            //check isStraight
            if((i != handCard.size()-1) && (handCard[i].getValue() != (handCard[i+1].getValue()-1)) && !isLowAceStraight){
                isStraight = false;
            }
            //check isFlush
            if((i != handCard.size()-1) && (handCard[i].getSuit() != handCard[i+1].getSuit())){
                isFlush = false;
            }
            //get same card list
            if(sameCard.empty()){
                std::vector cardList;
                cardList.push_back(handCard[i]);
                sameCard.push_back(cardList);
            } else {
                if(sameCard[sameCard.size()-1].back().getValue() == handCard[i].getValue()){
                    sameCard[sameCard.size()-1].push_back(handCard[i]);
                } else{
                    std::vector cardList;
                    cardList.push_back(handCard[i]);
                    sameCard.push_back(cardList);
                }
            }
        }
        //resort sameCard,improve priority of high size card
        std::vector> multiCard;
        int cardLen = sameCard.size();
        //divide the same kind of cards
        for(int i = 0; i <= 4; i++){
            //loop all sameCard in size == i
            for(int f = 0; f < cardLen; f++){
                if((int)sameCard[f].size() == i){
                    multiCard.push_back(sameCard[f]);
                }
            }
        }
        sameCard = multiCard;
        //low ACE
        if(handCard[0].getValue() == 2 && handCard[1].getValue() == 3 && handCard[2].getValue() == 4 && handCard[3].getValue() == 5 && handCard[4].getValue() == 14){
            Card ace(sameCard.back().back().c_rank,sameCard.back().back().c_suit);
            std::vector first;
            first.push_back(ace);
            sameCard.erase(sameCard.end());
            sameCard.insert(sameCard.begin(),first);
        }
        //get cards type
        if(isStraight && isFlush){
            cardType = Priority::isStraightFlush;
        } else if((sameCard.size() == 2) && (sameCard[1].size() == 4)){
            cardType = Priority::isFourOfAKind;
        } else if((sameCard.size() == 2) && (sameCard[1].size() == 3)){
            cardType = Priority::isFullHouse;
        } else if(isFlush){
            cardType = Priority::isFlush;
        } else if (isStraight){
            cardType = Priority::isStraight;
        } else if ((sameCard.size() == 3) && (sameCard[2].size() == 3)){
            cardType = Priority::isThreeOfAKind;
        } else if ((sameCard.size() == 3) && (sameCard[2].size() == 2)){
            cardType = Priority::isTwoPair;
        } else if ((sameCard.size() == 4) && (sameCard[3].size() == 2)){
            cardType = Priority::isOnePair;
        } else{
            cardType = Priority::isHighCard;
        }
    }
};

游戏效果

德州扑克C++实现_第10张图片

你可能感兴趣的:(小游戏)