Загрузка данных
#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;
}