Загрузка данных


#include <iostream>
#include <vector>
#include <algorithm>
#include <cstdlib>
#include <ctime>
#include <string>

using namespace std;

// Масти
enum Suit { CLUBS, DIAMONDS, HEARTS, SPADES };
const string suitSymbols[] = { "♣", "♦", "♥", "♠" };
const string suitNames[] = { "Треф", "Бубен", "Черв", "Пик" };

// Достоинства
enum Rank { TWO = 2, THREE, FOUR, FIVE, SIX, SEVEN, EIGHT, NINE, TEN, JACK, QUEEN, KING, ACE };
const string rankNames[] = { "", "", "2", "3", "4", "5", "6", "7", "8", "9", "10", "Валет", "Дама", "Король", "Туз" };

struct Card {
    Rank rank;
    Suit suit;

    string toString() const {
        return rankNames[rank] + suitSymbols[suit];
    }
};

// Колода из 52 карт
class Deck {
private:
    vector<Card> cards;
public:
    Deck() {
        for (int s = 0; s < 4; ++s)
            for (int r = 2; r <= 14; ++r)
                cards.push_back({ static_cast<Rank>(r), static_cast<Suit>(s) });
    }

    void shuffle() {
        random_shuffle(cards.begin(), cards.end());
    }

    Card dealCard() {
        Card c = cards.back();
        cards.pop_back();
        return c;
    }

    bool isEmpty() const {
        return cards.empty();
    }
};

// Рука из 5 карт
class Hand {
private:
    vector<Card> cards;
public:
    Hand() {}

    void addCard(const Card& c) {
        if (cards.size() < 5)
            cards.push_back(c);
    }

    void clear() {
        cards.clear();
    }

    const vector<Card>& getCards() const {
        return cards;
    }

    void show(bool hideFirst = false) const {
        for (size_t i = 0; i < cards.size(); ++i) {
            if (hideFirst && i == 0)
                cout << "[??] ";
            else
                cout << cards[i].toString() << " ";
        }
        cout << endl;
    }

    // Сортировка по рангу
    void sortByRank() {
        sort(cards.begin(), cards.end(), [](const Card& a, const Card& b) {
            return a.rank < b.rank;
        });
    }

    // a) Пара
    bool hasPair(int& rankValue) const {
        int counts[15] = {0};
        for (const auto& c : cards) counts[c.rank]++;
        for (int r = 2; r <= 14; ++r)
            if (counts[r] == 2) { rankValue = r; return true; }
        return false;
    }

    // b) Две пары
    bool hasTwoPairs() const {
        int pairs = 0;
        int counts[15] = {0};
        for (const auto& c : cards) counts[c.rank]++;
        for (int r = 2; r <= 14; ++r)
            if (counts[r] == 2) pairs++;
        return pairs == 2;
    }

    // c) Тройка
    bool hasThreeOfKind(int& rankValue) const {
        int counts[15] = {0};
        for (const auto& c : cards) counts[c.rank]++;
        for (int r = 2; r <= 14; ++r)
            if (counts[r] == 3) { rankValue = r; return true; }
        return false;
    }

    // d) Каре
    bool hasFourOfKind(int& rankValue) const {
        int counts[15] = {0};
        for (const auto& c : cards) counts[c.rank]++;
        for (int r = 2; r <= 14; ++r)
            if (counts[r] == 4) { rankValue = r; return true; }
        return false;
    }

    // e) Флэш
    bool hasFlush() const {
        Suit first = cards[0].suit;
        for (const auto& c : cards)
            if (c.suit != first) return false;
        return true;
    }

    // f) Стрит
    bool hasStraight() const {
        vector<int> ranks;
        for (const auto& c : cards) ranks.push_back(c.rank);
        sort(ranks.begin(), ranks.end());
        
        // Особый случай: A,2,3,4,5
        if (ranks[0] == 2 && ranks[1] == 3 && ranks[2] == 4 && ranks[3] == 5 && ranks[4] == 14)
            return true;
        
        for (int i = 1; i < 5; ++i)
            if (ranks[i] != ranks[i-1] + 1) return false;
        return true;
    }

    // Стрит-флэш
    bool hasStraightFlush() const {
        return hasFlush() && hasStraight();
    }

    // Фулл-хаус
    bool hasFullHouse() const {
        int rankValue;
        bool three = hasThreeOfKind(rankValue);
        if (!three) return false;
        int pairRank;
        return hasPair(pairRank);
    }

    // Оценка руки (число для сравнения)
    int evaluateHand() const {
        Hand copy = *this;
        copy.sortByRank();
        if (copy.hasStraightFlush()) return 8;          // Стрит-флэш
        int kick;
        if (copy.hasFourOfKind(kick)) return 7;         // Каре
        if (copy.hasFullHouse()) return 6;              // Фулл-хаус
        if (copy.hasFlush()) return 5;                  // Флэш
        if (copy.hasStraight()) return 4;               // Стрит
        if (copy.hasThreeOfKind(kick)) return 3;        // Тройка
        if (copy.hasTwoPairs()) return 2;               // Две пары
        if (copy.hasPair(kick)) return 1;               // Пара
        return 0;                                       // Старшая карта
    }

    string handStrengthName() const {
        switch (evaluateHand()) {
            case 0: return "Старшая карта";
            case 1: return "Пара";
            case 2: return "Две пары";
            case 3: return "Тройка";
            case 4: return "Стрит";
            case 5: return "Флэш";
            case 6: return "Фулл-хаус";
            case 7: return "Каре";
            case 8: return "Стрит-флэш";
            default: return "Неизвестно";
        }
    }

    // Замена карт (по индексам)
    void replaceCards(const vector<int>& indexes, Deck& deck) {
        for (int idx : indexes) {
            if (idx >= 0 && idx < (int)cards.size()) {
                cards[idx] = deck.dealCard();
            }
        }
    }
};

// 10.11: одна рука, анализ
void task1011() {
    cout << "\n=== 10.11. Одна рука ===\n";
    Deck deck;
    deck.shuffle();
    Hand hand;
    for (int i = 0; i < 5; ++i)
        hand.addCard(deck.dealCard());
    
    cout << "Сданные карты: ";
    hand.show();
    
    int rankVal;
    cout << "Пара: " << (hand.hasPair(rankVal) ? "да" : "нет") << endl;
    cout << "Две пары: " << (hand.hasTwoPairs() ? "да" : "нет") << endl;
    cout << "Тройка: " << (hand.hasThreeOfKind(rankVal) ? "да" : "нет") << endl;
    cout << "Каре: " << (hand.hasFourOfKind(rankVal) ? "да" : "нет") << endl;
    cout << "Флэш: " << (hand.hasFlush() ? "да" : "нет") << endl;
    cout << "Стрит: " << (hand.hasStraight() ? "да" : "нет") << endl;
    cout << "Комбинация: " << hand.handStrengthName() << endl;
}

// 10.12: две руки, сравнение
void task1012() {
    cout << "\n=== 10.12. Две руки ===\n";
    Deck deck;
    deck.shuffle();
    Hand hand1, hand2;
    for (int i = 0; i < 5; ++i) {
        hand1.addCard(deck.dealCard());
        hand2.addCard(deck.dealCard());
    }
    
    cout << "Рука 1: ";
    hand1.show();
    cout << "Комбинация: " << hand1.handStrengthName() << endl;
    
    cout << "Рука 2: ";
    hand2.show();
    cout << "Комбинация: " << hand2.handStrengthName() << endl;
    
    int score1 = hand1.evaluateHand();
    int score2 = hand2.evaluateHand();
    
    if (score1 > score2)
        cout << "Побеждает Рука 1!" << endl;
    else if (score2 > score1)
        cout << "Побеждает Рука 2!" << endl;
    else
        cout << "Ничья!" << endl;
}

// 10.13: дилер (скрытые карты), замена
void task1013() {
    cout << "\n=== 10.13. Дилер с заменой ===\n";
    Deck deck;
    deck.shuffle();
    Hand dealer;
    for (int i = 0; i < 5; ++i)
        dealer.addCard(deck.dealCard());
    
    cout << "Карты дилера (скрыты): ";
    dealer.show(true);
    cout << "Дилер оценивает руку: " << dealer.handStrengthName() << endl;
    
    // Пример: если нет пары, меняем 3 худшие карты
    int pairRank;
    if (!dealer.hasPair(pairRank)) {
        cout << "Дилер решает заменить 3 карты (кроме самых старших)..." << endl;
        vector<int> toReplace = {2, 3, 4}; // упрощённо
        dealer.replaceCards(toReplace, deck);
        cout << "Новая рука дилера: ";
        dealer.show();
        cout << "Новая комбинация: " << dealer.handStrengthName() << endl;
    } else {
        cout << "У дилера уже есть комбинация, замен нет." << endl;
    }
}

// 10.14: дилер и игрок, оба могут менять карты
void task1014() {
    cout << "\n=== 10.14. Игрок против дилера с заменой ===\n";
    Deck deck;
    deck.shuffle();
    Hand player, dealer;
    for (int i = 0; i < 5; ++i) {
        player.addCard(deck.dealCard());
        dealer.addCard(deck.dealCard());
    }
    
    cout << "Карты игрока: ";
    player.show();
    cout << "Комбинация игрока: " << player.handStrengthName() << endl;
    
    cout << "Карты дилера (скрыты): ";
    dealer.show(true);
    
    // Игрок меняет карты
    int choice;
    cout << "Игрок, сколько карт менять? (0-5): ";
    cin >> choice;
    if (choice > 0) {
        cout << "Введите индексы карт для замены (0-4): ";
        vector<int> idxs;
        for (int i = 0; i < choice; ++i) {
            int idx;
            cin >> idx;
            idxs.push_back(idx);
        }
        player.replaceCards(idxs, deck);
        cout << "Новая рука игрока: ";
        player.show();
        cout << "Новая комбинация: " << player.handStrengthName() << endl;
    }
    
    // Дилер меняет карты, если нет комбинации
    int pairRank;
    if (!dealer.hasPair(pairRank)) {
        cout << "Дилер меняет 3 карты..." << endl;
        vector<int> toReplace = {2, 3, 4};
        dealer.replaceCards(toReplace, deck);
        cout << "Новая рука дилера: ";
        dealer.show();
        cout << "Комбинация дилера: " << dealer.handStrengthName() << endl;
    } else {
        cout << "У дилера уже есть комбинация, замен нет." << endl;
        cout << "Рука дилера: ";
        dealer.show();
        cout << "Комбинация: " << dealer.handStrengthName() << endl;
    }
    
    // Определение победителя
    int playerScore = player.evaluateHand();
    int dealerScore = dealer.evaluateHand();
    
    cout << "\nИТОГ:" << endl;
    if (playerScore > dealerScore)
        cout << "Игрок выиграл!" << endl;
    else if (dealerScore > playerScore)
        cout << "Дилер выиграл!" << endl;
    else
        cout << "Ничья!" << endl;
}

int main() {
    srand(time(0));
    
    task1011();
    task1012();
    task1013();
    task1014();
    
    return 0;
}