#include #include #include #include #include #include #include #include using namespace std; enum Rank { TWO = 2, THREE, FOUR, FIVE, SIX, SEVEN, EIGHT, NINE, TEN, JACK, QUEEN, KING, ACE }; enum Suit { HEARTS, DIAMONDS, CLUBS, SPADES }; struct Card { Rank rank; Suit suit; friend ostream &operator<<(ostream &os, const Card &card) { const string ranks[] = {"2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K", "A"}; const string suits[] = {"H", "D", "C", "S"}; os << ranks[static_cast(card.rank) - 2] << suits[static_cast(card.suit)]; return os; } }; class Deck { private: vector cards; void shuffle() { random_device rd; mt19937 g(rd()); std::shuffle(cards.begin(), cards.end(), g); } public: Deck() { for (int i = static_cast(Rank::TWO); i <= static_cast(Rank::ACE); i++) { for (int j = static_cast(Suit::HEARTS); j <= static_cast(Suit::SPADES); j++) { cards.push_back(Card{static_cast(i), static_cast(j)}); } } shuffle(); } Card draw() { if (cards.empty()) { throw runtime_error("No more cards in the deck!"); } Card card = cards.back(); cards.pop_back(); return card; } bool empty() const { return cards.empty(); } }; class Player { public: vector hand; map rank_count; void draw_card(Deck &deck) { try { Card card = deck.draw(); hand.push_back(card); rank_count[card.rank]++; } catch (const runtime_error &e) { cout << e.what() << endl; } } bool has_rank(Rank rank) const { return rank_count.count(rank) > 0 && rank_count.at(rank) > 0; } vector remove_rank(Rank rank) { vector removed_cards; for (auto it = hand.begin(); it != hand.end();) { if (it->rank == rank) { removed_cards.push_back(*it); rank_count[it->rank]--; it = hand.erase(it); } else { it++; } } return removed_cards; } bool check_for_set() { for (const auto &pair : rank_count) { if (pair.second == 4) { cout << "Player has a set of " << static_cast(pair.first) << "s" << endl; rank_count[pair.first] = 0; hand.erase(remove_if(hand.begin(), hand.end(), [pair](const Card &card) { return card.rank == pair.first; }), hand.end()); return true; } } return false; } void add_cards(const vector &cards) { for (const Card &card : cards) { hand.push_back(card); rank_count[card.rank]++; } } }; class Game { private: Deck deck; Player human; Player computer; int human_score; int computer_score; void deal_initial_cards() { for (int i = 0; i < 7; i++) { human.draw_card(deck); computer.draw_card(deck); } } void human_turn() { Rank requested_rank = get_human_request(); if (computer.has_rank(requested_rank)) { cout << "Computer has " << static_cast(requested_rank) << "s" << endl; vector cards = computer.remove_rank(requested_rank); human.add_cards(cards); } else { cout << "Computer does not have the rank. Go fish!" << endl; human.draw_card(deck); } if (human.check_for_set()) { human_score++; } } void computer_turn() { cout << "Computer's turn..." << endl; Rank requested_rank = get_computer_request(); if (human.has_rank(requested_rank)) { cout << "Player has " << static_cast(requested_rank) << "s" << endl; vector cards = human.remove_rank(requested_rank); computer.add_cards(cards); } else { cout << "Player does not have the rank. Computer goes fishing!" << endl; computer.draw_card(deck); } if (computer.check_for_set()) { computer_score++; } } Rank get_human_request() { cout << "Your turn. Enter the rank (2-14 where 11=J, 12=Q, 13=K, 14=A): "; int rank; cin >> rank; return static_cast(rank); } Rank get_computer_request() { vector available_ranks; for (const auto &pair : computer.rank_count) { if (pair.second > 0) { available_ranks.push_back(pair.first); } } return available_ranks[rand() % available_ranks.size()]; } void show_hand(const vector &hand) const { for (const Card &card : hand) { cout << card << " "; } cout << endl; } public: Game() : human_score(0), computer_score(0) { deal_initial_cards(); } void play() { while (true) { cout << endl << "Your hand: "; show_hand(human.hand); human_turn(); computer_turn(); if (deck.empty() && human.hand.empty() && computer.hand.empty()) { cout << "Game over!" << endl; cout << "Your score: " << human_score << endl; cout << "Computer score: " << computer_score << endl; if (human_score > computer_score) { cout << "You win!" << endl; } else if (human_score < computer_score) { cout << "Computer wins!" << endl; } else { cout << "It's a tie!" << endl; } break; } } } }; int main(void) { srand(static_cast(time(nullptr))); Game game; game.play(); return 0; }