程序分析
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;
}
}
};
游戏效果