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


#include "game_logic.h"
#include <algorithm>
#include <random>
#include <iostream>
#include <ctime>

int GameLogic::playerWins = 0;
int GameLogic::computerWins = 0;

GameLogic::GameLogic() {
    newGame();
}

void GameLogic::createDeck() {
    deck.clear();
    std::vector<std::string> suits = {"S", "H", "D", "C"};
    std::vector<std::string> values = {"6", "7", "8", "9", "10", "J", "Q", "K", "A"};
    
    for (std::string s : suits) {
        for (std::string v : values) {
            deck.push_back(Card(s, v));
        }
    }
    
    // Перемешиваем колоду
    std::random_device rd;
    std::mt19937 g(rd());
    std::shuffle(deck.begin(), deck.end(), g);
    
    // Определяем козырь (последняя карта в колоде после тасования)
    trumpSuit = deck.back().suit;
    if (trumpSuit == "S") trumpSymbol = "♠";
    else if (trumpSuit == "H") trumpSymbol = "♥";
    else if (trumpSuit == "D") trumpSymbol = "♦";
    else trumpSymbol = "♣";
    
    std::cout << "[DEBUG] Козырь: " << trumpSuit << trumpSymbol << std::endl;
}

void GameLogic::dealCards() {
    playerHand.clear();
    computerHand.clear();
    
    // Раздаем по 6 карт
    for (int i = 0; i < 6 && !deck.empty(); i++) {
        if (!deck.empty()) {
            playerHand.push_back(deck.back());
            deck.pop_back();
        }
        if (!deck.empty()) {
            computerHand.push_back(deck.back());
            deck.pop_back();
        }
    }
    
    std::cout << "[DEBUG] Игрок получил " << playerHand.size() << " карт" << std::endl;
    std::cout << "[DEBUG] Компьютер получил " << computerHand.size() << " карт" << std::endl;
}

void GameLogic::findFirstAttacker() {
    // ПРИНУДИТЕЛЬНО: игрок атакует первым (для теста)
    attacker = 0;  // 0 - игрок, 1 - компьютер
    waiting = false;
    gameOver = false;
}

void GameLogic::refill() {
    // Добираем карты до 6
    while ((int)playerHand.size() < 6 && !deck.empty()) {
        playerHand.push_back(deck.back());
        deck.pop_back();
    }
    while ((int)computerHand.size() < 6 && !deck.empty()) {
        computerHand.push_back(deck.back());
        deck.pop_back();
    }
    
    std::cout << "[DEBUG] После добора: игрок " << playerHand.size() 
              << ", компьютер " << computerHand.size() 
              << ", колода " << deck.size() << std::endl;
}

void GameLogic::checkWinner() {
    if (playerHand.size() == 0) {
        gameOver = true;
        playerWon = true;
        playerWins++;
        std::cout << "[GAME] ИГРОК ПОБЕДИЛ!" << std::endl;
    } else if (computerHand.size() == 0) {
        gameOver = true;
        playerWon = false;
        computerWins++;
        std::cout << "[GAME] КОМПЬЮТЕР ПОБЕДИЛ!" << std::endl;
    }
}

bool GameLogic::canBeat(const Card& attack, const Card& defend) {
    // Если масти совпадают
    if (defend.suit == attack.suit) {
        return defend.rank > attack.rank;
    }
    // Если защита - козырь
    if (defend.suit == trumpSuit) {
        return attack.suit != trumpSuit;
    }
    return false;
}

bool GameLogic::playerAttack(int idx) {
    if (gameOver) {
        std::cout << "[ERROR] Игра окончена" << std::endl;
        return false;
    }
    if (waiting) {
        std::cout << "[ERROR] Сейчас ожидается защита" << std::endl;
        return false;
    }
    if (attacker != 0) {
        std::cout << "[ERROR] Сейчас не ваш ход для атаки. Атакует: " << attacker << std::endl;
        return false;
    }
    if (idx >= (int)playerHand.size()) {
        std::cout << "[ERROR] Неверный индекс карты" << std::endl;
        return false;
    }
    
    Card c = playerHand[idx];
    playerHand.erase(playerHand.begin() + idx);
    tableCards.push_back(TableCard(c, Card()));
    waiting = true;
    
    std::cout << "[PLAYER] Атака картой: " << c.toString() << std::endl;
    return true;
}

bool GameLogic::playerDefend(int idx) {
    if (gameOver) return false;
    if (!waiting) return false;
    if (attacker != 1) return false; // Защищается только когда атакует компьютер
    if (tableCards.empty()) return false;
    if (idx >= (int)playerHand.size()) return false;
    
    Card attackCard = tableCards.back().attack;
    Card defendCard = playerHand[idx];
    
    if (!canBeat(attackCard, defendCard)) {
        std::cout << "[PLAYER] Не может побить " << attackCard.toString() 
                  << " картой " << defendCard.toString() << std::endl;
        return false;
    }
    
    // Защита успешна
    playerHand.erase(playerHand.begin() + idx);
    tableCards.back().defend = defendCard;
    
    std::cout << "[PLAYER] Отбился " << attackCard.toString() 
              << " картой " << defendCard.toString() << std::endl;
    
    // Проверяем, все ли карты побиты
    bool allBeaten = true;
    for (auto& p : tableCards) {
        if (p.defend.value.empty()) {
            allBeaten = false;
            break;
        }
    }
    
    if (allBeaten) {
        // Отбой - все карты побиты
        std::cout << "[GAME] ОТБОЙ! Все карты побиты" << std::endl;
        tableCards.clear();
        // Меняем атакующего
        attacker = (attacker == 0) ? 1 : 0;
        waiting = false;
        refill();
        checkWinner();
    } else {
        // Не все карты побиты, ждем следующую атаку
        waiting = false;
    }
    return true;
}

void GameLogic::playerTake() {
    if (gameOver) return;
    if (!waiting) return;
    if (attacker != 1) return;
    
    std::cout << "[PLAYER] Берет карты со стола" << std::endl;
    
    // Игрок забирает все карты со стола
    for (auto& p : tableCards) {
        playerHand.push_back(p.attack);
        if (!p.defend.value.empty()) {
            playerHand.push_back(p.defend);
        }
    }
    tableCards.clear();
    // После взятия карт ход переходит к компьютеру
    attacker = 1;
    waiting = false;
    refill();
    checkWinner();
}

void GameLogic::computerTurn() {
    if (gameOver) {
        std::cout << "[COMPUTER] Игра окончена" << std::endl;
        return;
    }
    
    std::cout << "[COMPUTER] Ход. waiting=" << waiting << ", attacker=" << attacker << std::endl;
    
    // Если компьютер защищается (его атакуют)
    if (waiting && attacker == 0) {
        std::cout << "[COMPUTER] Защищается" << std::endl;
        
        if (computerHand.empty()) {
            // Компьютер забирает карты
            std::cout << "[COMPUTER] Нет карт для защиты - берет" << std::endl;
            for (auto& p : tableCards) {
                computerHand.push_back(p.attack);
                if (!p.defend.value.empty()) {
                    computerHand.push_back(p.defend);
                }
            }
            tableCards.clear();
            attacker = 1;
            waiting = false;
            refill();
            checkWinner();
            return;
        }
        
        Card attackCard = tableCards.back().attack;
        int defendIndex = -1;
        
        // Ищем карту для защиты
        for (int i = 0; i < (int)computerHand.size(); i++) {
            if (canBeat(attackCard, computerHand[i])) {
                defendIndex = i;
                break;
            }
        }
        
        if (defendIndex >= 0) {
            // Компьютер бьет карту
            Card defendCard = computerHand[defendIndex];
            computerHand.erase(computerHand.begin() + defendIndex);
            tableCards.back().defend = defendCard;
            
            std::cout << "[COMPUTER] Отбил " << attackCard.toString() 
                      << " картой " << defendCard.toString() << std::endl;
            
            bool allBeaten = true;
            for (auto& p : tableCards) {
                if (p.defend.value.empty()) {
                    allBeaten = false;
                    break;
                }
            }
            
            if (allBeaten) {
                // Отбой - все карты побиты
                std::cout << "[COMPUTER] Отбой!" << std::endl;
                tableCards.clear();
                attacker = 0;
                waiting = false;
                refill();
                checkWinner();
            } else {
                // Не все карты побиты, ждем следующую атаку
                waiting = false;
            }
        } else {
            // Компьютер не может побить - забирает карты
            std::cout << "[COMPUTER] Не может отбиться - берет карты" << std::endl;
            for (auto& p : tableCards) {
                computerHand.push_back(p.attack);
                if (!p.defend.value.empty()) {
                    computerHand.push_back(p.defend);
                }
            }
            tableCards.clear();
            attacker = 1;
            waiting = false;
            refill();
            checkWinner();
        }
    } 
    // Если компьютер атакует
    else if (!waiting && attacker == 1) {
        std::cout << "[COMPUTER] Атакует" << std::endl;
        
        if (computerHand.empty()) {
            checkWinner();
            return;
        }
        // Компьютер атакует первой картой
        Card c = computerHand[0];
        computerHand.erase(computerHand.begin());
        tableCards.push_back(TableCard(c, Card()));
        waiting = true;
        
        std::cout << "[COMPUTER] Атакует картой: " << c.toString() << std::endl;
    } else {
        std::cout << "[COMPUTER] Не может ходить (не его очередь)" << std::endl;
    }
}

void GameLogic::newGame() {
    std::cout << "\n=== НОВАЯ ИГРА ===" << std::endl;
    createDeck();
    dealCards();
    findFirstAttacker();
    tableCards.clear();
    gameOver = false;
    waiting = false;
    
    std::cout << "[GAME] Новая игра началась. Атакует: " 
              << (attacker == 0 ? "ИГРОК" : "КОМПЬЮТЕР") << std::endl;
}