268 lines
6.9 KiB
C++
268 lines
6.9 KiB
C++
|
#pragma once
|
||
|
#include <vector>
|
||
|
#include "card.hpp"
|
||
|
#include "sort.hpp"
|
||
|
|
||
|
class Score
|
||
|
{
|
||
|
|
||
|
int countByNumber(int number)
|
||
|
{
|
||
|
int result = 0;
|
||
|
for (auto &card : this->cards)
|
||
|
{
|
||
|
if (card.number == number)
|
||
|
result++;
|
||
|
}
|
||
|
return result;
|
||
|
}
|
||
|
bool hasCard(int number)
|
||
|
{
|
||
|
for (auto &card : this->cards)
|
||
|
if (card.number == number)
|
||
|
return true;
|
||
|
return false;
|
||
|
}
|
||
|
bool hasCard(std::string kind, std::string value)
|
||
|
{
|
||
|
for (auto &card : this->cards)
|
||
|
{
|
||
|
if (card.kind == kind && card.value == value)
|
||
|
return true;
|
||
|
}
|
||
|
return false;
|
||
|
}
|
||
|
bool hasCard(std::string kind, int number)
|
||
|
{
|
||
|
for (auto &card : this->cards)
|
||
|
if (card.number == number && card.kind == kind)
|
||
|
return true;
|
||
|
return false;
|
||
|
}
|
||
|
std::vector<Card> getCardsByKind(std::string kind)
|
||
|
{
|
||
|
std::vector<Card> result;
|
||
|
for (auto &card : this->cards)
|
||
|
{
|
||
|
if (card.kind == kind)
|
||
|
result.push_back(card);
|
||
|
}
|
||
|
return result;
|
||
|
}
|
||
|
|
||
|
public:
|
||
|
std::vector<Card> playerCards;
|
||
|
std::vector<Card> communityCards;
|
||
|
std::vector<Card> cards;
|
||
|
std::string name;
|
||
|
double score = 0;
|
||
|
Score()
|
||
|
{
|
||
|
}
|
||
|
void calculate()
|
||
|
{
|
||
|
this->score = this->playerCards[0].worth;
|
||
|
this->score += this->playerCards[1].worth;
|
||
|
if (this->isRoyalFlush())
|
||
|
{
|
||
|
this->name = "RoyalFlush";
|
||
|
this->score += 10;
|
||
|
}
|
||
|
else if (this->isStraightFlush())
|
||
|
{
|
||
|
this->name = "StraightFlush";
|
||
|
this->score += 9;
|
||
|
}
|
||
|
else if (this->isFourOfAKind())
|
||
|
{
|
||
|
this->name = "FourOfAKind";
|
||
|
this->score += 8;
|
||
|
}
|
||
|
else if (this->isFullHouse())
|
||
|
{
|
||
|
this->name = "FullHouse";
|
||
|
this->score += 7;
|
||
|
}
|
||
|
else if (this->isFlush())
|
||
|
{
|
||
|
this->name = "Flush";
|
||
|
this->score += 6;
|
||
|
}
|
||
|
else if (this->isStraight())
|
||
|
{
|
||
|
this->name = "Straight";
|
||
|
this->score += 5;
|
||
|
}
|
||
|
else if (this->isThreeOfAKind())
|
||
|
{
|
||
|
this->name = "ThreeOfAKind";
|
||
|
this->score += 4;
|
||
|
}
|
||
|
else if (this->isTwoPair())
|
||
|
{
|
||
|
this->name = "TwoPair";
|
||
|
this->score += 3;
|
||
|
}
|
||
|
else if (this->isOnePair())
|
||
|
{
|
||
|
this->name = "OnePair";
|
||
|
this->score += 2;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
this->name = "HighCard";
|
||
|
this->score += 1;
|
||
|
Card highCart = this->playerCards[0].worth > this->playerCards[1].worth ? this->playerCards[0] : this->playerCards[1];
|
||
|
this->score += highCart.worth;
|
||
|
}
|
||
|
}
|
||
|
void setPlayerCards(std::vector<Card> cards)
|
||
|
{
|
||
|
for (auto &card : cards)
|
||
|
{
|
||
|
this->playerCards.push_back(card);
|
||
|
sort_card_vector_ascending(this->playerCards);
|
||
|
this->cards.push_back(card);
|
||
|
sort_card_vector_ascending(this->cards);
|
||
|
}
|
||
|
}
|
||
|
void setCommunityCards(std::vector<Card> cards)
|
||
|
{
|
||
|
for (auto &card : cards)
|
||
|
{
|
||
|
if(!this->hasCard(card.kind, card.number)){
|
||
|
this->communityCards.push_back(card);
|
||
|
sort_card_vector_ascending(this->communityCards);
|
||
|
this->cards.push_back(card);
|
||
|
sort_card_vector_ascending(this->cards);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
bool isRoyalFlush()
|
||
|
{
|
||
|
for (auto &card : this->cards)
|
||
|
{
|
||
|
bool isMatch = this->hasCard(card.kind, "A") && this->hasCard(card.kind, "K") && this->hasCard(card.kind, "Q") && this->hasCard(card.kind, "J") && this->hasCard(card.kind, "10");
|
||
|
if (isMatch)
|
||
|
return true;
|
||
|
}
|
||
|
return false;
|
||
|
}
|
||
|
bool isStraightFlush()
|
||
|
{
|
||
|
// Straight Flush: Five cards in sequence, all of the same suit.
|
||
|
for (auto &card : this->cards)
|
||
|
{
|
||
|
bool valid = true;
|
||
|
for (auto &card2 : this->getCardsByKind(card.kind))
|
||
|
{
|
||
|
for (int i = 1; i < 5; i++)
|
||
|
{
|
||
|
int number = card2.number + i;
|
||
|
if (!this->hasCard(card2.kind, number))
|
||
|
valid = false;
|
||
|
}
|
||
|
if (valid)
|
||
|
return true;
|
||
|
}
|
||
|
}
|
||
|
return false;
|
||
|
}
|
||
|
bool isFourOfAKind()
|
||
|
{
|
||
|
// Four of a Kind: Four cards of the same rank.
|
||
|
for (auto &card : this->cards)
|
||
|
{
|
||
|
if (this->countByNumber(card.number) >= 4)
|
||
|
return true;
|
||
|
}
|
||
|
return false;
|
||
|
}
|
||
|
bool isFullHouse()
|
||
|
{
|
||
|
// Full House: Three cards of one rank and two cards of another rank.
|
||
|
int previousNumber = 0;
|
||
|
bool foundTwo = false;
|
||
|
bool foundThree = false;
|
||
|
for (auto &card : this->cards)
|
||
|
{
|
||
|
if (this->countByNumber(card.number) >= 3 && previousNumber != card.number)
|
||
|
{
|
||
|
previousNumber = card.number;
|
||
|
foundThree = true;
|
||
|
}
|
||
|
else if (this->countByNumber(card.number) >= 2 && previousNumber != card.number)
|
||
|
{
|
||
|
previousNumber = card.number;
|
||
|
foundTwo = true;
|
||
|
}
|
||
|
}
|
||
|
return foundTwo && foundThree;
|
||
|
}
|
||
|
bool isFlush()
|
||
|
{
|
||
|
// Flush: Five cards of the same suit, not in sequence.
|
||
|
for (auto &card : this->cards)
|
||
|
{
|
||
|
int count = 0;
|
||
|
for (auto &card2 : this->cards)
|
||
|
if (card.kind == card2.kind)
|
||
|
count++;
|
||
|
if (count == 5)
|
||
|
return true;
|
||
|
}
|
||
|
return false;
|
||
|
}
|
||
|
bool isStraight()
|
||
|
{
|
||
|
for (auto &card : this->cards)
|
||
|
{
|
||
|
bool valid = true;
|
||
|
for (int i = 0; i < 5; i++)
|
||
|
{
|
||
|
int number = card.number + i;
|
||
|
if (!this->hasCard(number))
|
||
|
{
|
||
|
valid = false;
|
||
|
}
|
||
|
}
|
||
|
if (valid)
|
||
|
return true;
|
||
|
}
|
||
|
return false;
|
||
|
}
|
||
|
bool isThreeOfAKind()
|
||
|
{
|
||
|
for (auto &card : this->cards)
|
||
|
{
|
||
|
if (this->countByNumber(card.number) >= 3)
|
||
|
return true;
|
||
|
}
|
||
|
return false;
|
||
|
}
|
||
|
bool isTwoPair()
|
||
|
{
|
||
|
int pairCount = 0;
|
||
|
int lastPairNumber = 0;
|
||
|
for (auto &card : this->cards)
|
||
|
{
|
||
|
if (this->countByNumber(card.number) >= 2 && card.number != lastPairNumber)
|
||
|
{
|
||
|
lastPairNumber = card.number;
|
||
|
pairCount++;
|
||
|
}
|
||
|
}
|
||
|
return pairCount >= 2;
|
||
|
}
|
||
|
bool isOnePair()
|
||
|
{
|
||
|
for (auto &card : this->cards)
|
||
|
{
|
||
|
if (this->countByNumber(card.number) >= 2)
|
||
|
return true;
|
||
|
}
|
||
|
return false;
|
||
|
}
|
||
|
};
|