import pygame
import sys
import random
import time

pygame.init()

# ========= Глобальные настройки по умолчанию =========
CELL_SIZE = 32
PANEL_WIDTH = 200

# Значения по умолчанию для поля и шанса бонусов (меню позволит их изменять)
default_GRID_WIDTH = 30
default_GRID_HEIGHT = 30
default_BONUS_GENERATION_CHANCE = 0.10  # 10%

# ========= Цвета =========
COLOR_BG       = (30, 30, 30)
COLOR_GRID     = (50, 50, 50)
COLOR_FOG      = (20, 20, 20)
COLOR_SELECTED = (255, 0, 0)
COLOR_MOVE     = (0, 255, 0)

COLOR_WHITE_PIECE = (255, 255, 255)
COLOR_BLACK_PIECE = (0, 0, 0)

COLOR_REGEN = (0, 255, 0)
COLOR_HP_UPGRADE = (0, 128, 255)
COLOR_DAMAGE = (255, 0, 0)
COLOR_KING_HP_UPGRADE = (255, 215, 0)
COLOR_ADD_PIECE = (255, 255, 255)
COLOR_ADD_PIECE_PINK = (255, 192, 203)

COLOR_TURN_TEXT = (255, 255, 255)
COLOR_TIMER_NORMAL = (255, 255, 255)
COLOR_TIMER_WARNING = (255, 0, 0)
COLOR_MERCHANT = (139, 69, 19)
COLOR_COIN = (255, 165, 0)

# ========= Шрифты =========
font = pygame.font.SysFont(None, CELL_SIZE // 2)
victory_font = pygame.font.SysFont(None, 60)
turn_font = pygame.font.SysFont(None, 30)
counter_font = pygame.font.SysFont(None, 30)
timer_font = pygame.font.SysFont(None, 25)
shop_font = pygame.font.SysFont(None, 24)

# ========= Меню настроек =========
def main_menu():
    menu_running = True
    menu_width, menu_height = 600, 400
    menu_screen = pygame.display.set_mode((menu_width, menu_height))
    pygame.display.set_caption("Настройки игры")
    
    # Начальные значения из настроек по умолчанию
    grid_width = default_GRID_WIDTH
    grid_height = default_GRID_HEIGHT
    bonus_chance = default_BONUS_GENERATION_CHANCE  # 0.10 = 10%
    
    # Подготавливаем тексты для кнопок
    minus_text = shop_font.render("-", True, (0, 0, 0))
    plus_text  = shop_font.render("+", True, (0, 0, 0))
    
    while menu_running:
        menu_screen.fill((50, 50, 50))
        
        # Заголовок
        title_text = shop_font.render("Настройки игры", True, (255,255,255))
        title_rect = title_text.get_rect(center=(menu_width//2, 40))
        menu_screen.blit(title_text, title_rect)
        
        # Размер поля
        field_text = shop_font.render("Размер поля:", True, (255,255,255))
        menu_screen.blit(field_text, (50, 80))
        
        # Ширина поля
        width_text = shop_font.render(f"Ширина: {grid_width}", True, (255,255,255))
        menu_screen.blit(width_text, (100, 130))
        width_minus_rect = pygame.Rect(50, 130, 40, 30)
        width_plus_rect  = pygame.Rect(250, 130, 40, 30)
        pygame.draw.rect(menu_screen, (200,200,200), width_minus_rect)
        pygame.draw.rect(menu_screen, (200,200,200), width_plus_rect)
        menu_screen.blit(minus_text, minus_text.get_rect(center=width_minus_rect.center))
        menu_screen.blit(plus_text, plus_text.get_rect(center=width_plus_rect.center))
        
        # Высота поля
        height_text = shop_font.render(f"Высота: {grid_height}", True, (255,255,255))
        menu_screen.blit(height_text, (100, 180))
        height_minus_rect = pygame.Rect(50, 180, 40, 30)
        height_plus_rect  = pygame.Rect(250, 180, 40, 30)
        pygame.draw.rect(menu_screen, (200,200,200), height_minus_rect)
        pygame.draw.rect(menu_screen, (200,200,200), height_plus_rect)
        menu_screen.blit(minus_text, minus_text.get_rect(center=height_minus_rect.center))
        menu_screen.blit(plus_text, plus_text.get_rect(center=height_plus_rect.center))
        
        # Шанс бонусов (выводим значение в процентах)
        bonus_label = shop_font.render("Шанс бонусов (%):", True, (255,255,255))
        menu_screen.blit(bonus_label, (100, 230))
        bonus_value = shop_font.render(f"{int(bonus_chance*100)}", True, (255,255,255))
        menu_screen.blit(bonus_value, (300, 230))
        bonus_minus_rect = pygame.Rect(350, 225, 40, 30)
        bonus_plus_rect  = pygame.Rect(450, 225, 40, 30)
        pygame.draw.rect(menu_screen, (200,200,200), bonus_minus_rect)
        pygame.draw.rect(menu_screen, (200,200,200), bonus_plus_rect)
        menu_screen.blit(minus_text, minus_text.get_rect(center=bonus_minus_rect.center))
        menu_screen.blit(plus_text, plus_text.get_rect(center=bonus_plus_rect.center))
        
        # Кнопка "Начать игру"
        start_rect = pygame.Rect(menu_width//2 - 75, 300, 150, 50)
        pygame.draw.rect(menu_screen, (0,255,0), start_rect)
        start_text = shop_font.render("Начать игру", True, (0,0,0))
        menu_screen.blit(start_text, start_text.get_rect(center=start_rect.center))
        
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                sys.exit()
            elif event.type == pygame.MOUSEBUTTONDOWN:
                mx, my = pygame.mouse.get_pos()
                if width_minus_rect.collidepoint(mx, my):
                    grid_width = max(8, grid_width - 1)
                elif width_plus_rect.collidepoint(mx, my):
                    grid_width = min(100, grid_width + 1)
                elif height_minus_rect.collidepoint(mx, my):
                    grid_height = max(8, grid_height - 1)
                elif height_plus_rect.collidepoint(mx, my):
                    grid_height = min(100, grid_height + 1)
                elif bonus_minus_rect.collidepoint(mx, my):
                    bonus_chance = max(0.0, bonus_chance - 0.01)
                elif bonus_plus_rect.collidepoint(mx, my):
                    bonus_chance = min(1.0, bonus_chance + 0.01)
                elif start_rect.collidepoint(mx, my):
                    menu_running = False
        
        pygame.display.flip()
    return grid_width, grid_height, bonus_chance

# ========= Вызываем меню настроек и обновляем глобальные параметры =========
GRID_WIDTH, GRID_HEIGHT, BONUS_GENERATION_CHANCE = main_menu()
WINDOW_WIDTH = CELL_SIZE * GRID_WIDTH + PANEL_WIDTH
WINDOW_HEIGHT = CELL_SIZE * GRID_HEIGHT

# Теперь устанавливаем главное окно игры
screen = pygame.display.set_mode((WINDOW_WIDTH, WINDOW_HEIGHT))
pygame.display.set_caption("Шахматы с Открытым Миром 1.1.1")

# ========= Глобальные переменные =========
global_revealed = set()
bonus_cells = {}
base_bonus_probabilities = {
    'regen': 0.42,
    'hp_upgrade': 0.32,
    'damage': 0.2,
    'king_hp_upgrade': 0.05,
    'add_piece': 0.01
}
bonus_probabilities = base_bonus_probabilities.copy()
piece_symbols = {
    'rook':   'Л',
    'knight': 'К',
    'bishop': 'С',
    'queen':  'Ф',
    'king':   'К',
    'pawn':   'П'
}

# ========= Класс фигур =========
class Piece:
    def __init__(self, name, color, x, y):
        self.name = name
        self.color = color  # 'white' или 'black'
        self.x = x
        self.y = y
        self.selected = False
        self.has_moved = False
        if self.name == 'king':
            self.max_hp = 5
            self.hp = 5
        elif self.name in ['rook', 'knight', 'bishop', 'queen']:
            self.max_hp = 3
            self.hp = 3
        elif self.name == 'pawn':
            self.max_hp = 1
            self.hp = 1

    def get_possible_moves(self, pieces):
        moves = []
        if self.name == 'pawn':
            directions = [(-1,-1), (0,-1), (1,-1),
                          (-1, 0),         (1, 0),
                          (-1, 1), (0, 1), (1, 1)]
            for dx, dy in directions:
                nx = self.x + dx
                ny = self.y + dy
                if 0 <= nx < GRID_WIDTH and 0 <= ny < GRID_HEIGHT:
                    blocking = next((p for p in pieces if p.x == nx and p.y == ny), None)
                    if not blocking or blocking.color != self.color:
                        moves.append((nx, ny))
        elif self.name in ['rook', 'bishop', 'queen']:
            max_steps = getattr(self, 'move_range', 3)
            if self.name == 'rook':
                directions = [(-1,0),(1,0),(0,-1),(0,1)]
            elif self.name == 'bishop':
                directions = [(-1,-1),(1,-1),(1,1),(-1,1)]
            elif self.name == 'queen':
                directions = [(-1,0),(1,0),(0,-1),(0,1),(-1,-1),(1,-1),(1,1),(-1,1)]
            for dx, dy in directions:
                for step in range(1, max_steps + 1):
                    nx = self.x + dx * step
                    ny = self.y + dy * step
                    if 0 <= nx < GRID_WIDTH and 0 <= ny < GRID_HEIGHT:
                        blocking = next((p for p in pieces if p.x == nx and p.y == ny), None)
                        if blocking:
                            if blocking.color != self.color:
                                moves.append((nx, ny))
                            break
                        moves.append((nx, ny))
                    else:
                        break
        elif self.name == 'knight':
            deltas = [(-2,-1),(-1,-2),(1,-2),(2,-1),
                      (2,1),(1,2),(-1,2),(-2,1)]
            for dx, dy in deltas:
                nx, ny = self.x + dx, self.y + dy
                if 0 <= nx < GRID_WIDTH and 0 <= ny < GRID_HEIGHT:
                    blocking = next((p for p in pieces if p.x == nx and p.y == ny), None)
                    if not blocking or blocking.color != self.color:
                        moves.append((nx, ny))
        elif self.name == 'king':
            directions = [(-1,0),(1,0),(0,-1),(0,1),(-1,-1),(1,-1),(1,1),(-1,1)]
            for dx, dy in directions:
                nx, ny = self.x + dx, self.y + dy
                if 0 <= nx < GRID_WIDTH and 0 <= ny < GRID_HEIGHT:
                    blocking = next((p for p in pieces if p.x == nx and p.y == ny), None)
                    if not blocking or blocking.color != self.color:
                        moves.append((nx, ny))
        return moves

# ========= Функция разрешения боя =========
def resolve_combat(attacker, defender):
    a = attacker.hp
    b = defender.hp
    if a < b:
        defender.hp = b - a
        attacker.hp = 0
        return (False, True)
    elif a > b:
        attacker.hp = a - b
        defender.hp = 0
        return (True, False)
    else:
        attacker.hp = 1
        defender.hp = 0
        return (True, False)

# ========= Функция инициализации фигур =========
def initialize_pieces():
    pieces = []
    cx = GRID_WIDTH // 2
    offset = 3  # для базовой линии – 8 фигур
    # Вычисляем вертикальные позиции пропорционально высоте поля:
    black_back_y = max(0, int(GRID_HEIGHT * 0.1))
    black_pawn_y = min(GRID_HEIGHT - 1, black_back_y + 1)
    white_back_y = GRID_HEIGHT - 1 - int(GRID_HEIGHT * 0.1)
    white_pawn_y = max(0, white_back_y - 1)
    
    black_back = ['rook','knight','bishop','king','queen','bishop','knight','rook']
    for i, pname in enumerate(black_back):
        x = cx - offset + i
        if 0 <= x < GRID_WIDTH:
            pieces.append(Piece(pname, 'black', x, black_back_y))
    for i in range(8):
        x = cx - offset + i
        if 0 <= x < GRID_WIDTH:
            pieces.append(Piece('pawn', 'black', x, black_pawn_y))
    
    white_back = ['rook','knight','bishop','king','queen','bishop','knight','rook']
    for i, pname in enumerate(white_back):
        x = cx - offset + i
        if 0 <= x < GRID_WIDTH:
            pieces.append(Piece(pname, 'white', x, white_back_y))
    for i in range(8):
        x = cx - offset + i
        if 0 <= x < GRID_WIDTH:
            pieces.append(Piece('pawn', 'white', x, white_pawn_y))
    return pieces

# ========= Спрайты для фигур =========
piece_sprites = {}
def load_piece_sprites():
    piece_names_map = {
        'king': 'K',
        'queen': 'Q',
        'rook': 'R',
        'bishop': 'B',
        'knight': 'N',
        'pawn': 'P'
    }
    colors = ['white', 'black']
    for color in colors:
        letter = 'w' if color == 'white' else 'b'
        for name in piece_names_map:
            filename = f"sprites/{letter}{piece_names_map[name]}.png"
            try:
                image = pygame.image.load(filename).convert_alpha()
                image = pygame.transform.scale(image, (CELL_SIZE, CELL_SIZE))
                piece_sprites[(color, name)] = image
            except Exception as e:
                print(f"Ошибка загрузки спрайта {filename}: {e}")
                piece_sprites[(color, name)] = None

load_piece_sprites()

# ========= Спрайты для окружающей среды =========
try:
    open_cell_sprite = pygame.image.load("sprites/open_cell.png").convert_alpha()
    open_cell_sprite = pygame.transform.scale(open_cell_sprite, (CELL_SIZE, CELL_SIZE))
except Exception as e:
    print(f"Ошибка загрузки open_cell.png: {e}")
    open_cell_sprite = None

try:
    fog_sprite = pygame.image.load("sprites/fog.png").convert_alpha()
    fog_sprite = pygame.transform.scale(fog_sprite, (CELL_SIZE, CELL_SIZE))
except Exception as e:
    print(f"Ошибка загрузки fog.png: {e}")
    fog_sprite = None

# ========= Механика бонусов =========
def choose_bonus_type():
    rand = random.random()
    cumulative = 0
    for bonus_type, prob in bonus_probabilities.items():
        cumulative += prob
        if rand < cumulative:
            return bonus_type
    return 'regen'

# ========= Торговцы, монеты и магазин =========
merchant_positions = [(0, GRID_HEIGHT // 2), (GRID_WIDTH - 1, GRID_HEIGHT // 2)]
global_revealed.update(merchant_positions)
coin_cells = set()
player_coins = {'white': 0, 'black': 0}
shop_open = False
shop_items = {
    'extend_move': {'name': 'Расширить ход', 'cost': 6},
    'increase_hp': {'name': 'Увеличить HP', 'cost': 6},
    'damage_enemy': {'name': 'Уменьшить HP врага', 'cost': 6},
    'curse': {'name': 'Проклятие', 'cost': 6}
}

# ========= Система ходов =========
current_turn = 'white'
turn_count = 0
moves_remaining = 3

def update_bonus_probabilities():
    global bonus_probabilities
    if turn_count <= 100:
        bonus_probabilities = base_bonus_probabilities.copy()
    else:
        extra_turns = turn_count - 100
        max_extra = 200
        increase_per_turn = (0.50 - base_bonus_probabilities['damage']) / max_extra
        new_damage_prob = min(base_bonus_probabilities['damage'] + increase_per_turn * extra_turns, 0.50)
        remaining_prob = 1 - new_damage_prob
        total_other_probs = sum(base_bonus_probabilities[bt] for bt in base_bonus_probabilities if bt != 'damage')
        bonus_probabilities = {}
        for bt, prob in base_bonus_probabilities.items():
            if bt == 'damage':
                bonus_probabilities[bt] = new_damage_prob
            else:
                bonus_probabilities[bt] = prob / total_other_probs * remaining_prob

# ========= Время на ход =========
TURN_TIME_LIMIT = 120  # секунд
timer_start_time = time.time()
timer_expired = False
player_timeouts = {'white': 0, 'black': 0}

def reset_timer():
    global timer_start_time, timer_expired
    timer_start_time = time.time()
    timer_expired = False

def get_time_left():
    elapsed = time.time() - timer_start_time
    return max(0, TURN_TIME_LIMIT - int(elapsed))

def check_timer():
    global timer_expired, game_over, winner
    time_left = get_time_left()
    if time_left <= 0 and not timer_expired:
        timer_expired = True
        player_timeouts[current_turn] += 1
        if player_timeouts[current_turn] >= 2:
            winner = 'black' if current_turn == 'white' else 'white'
            game_over = True
        else:
            switch_turn()

def switch_turn():
    global current_turn, turn_count, timer_expired, moves_remaining
    current_turn = 'black' if current_turn == 'white' else 'white'
    turn_count += 1
    reset_timer()
    timer_expired = False
    update_bonus_probabilities()
    moves_remaining = 3
    for p in pieces:
        if p.color == current_turn:
            p.has_moved = False

def end_move(moved_piece):
    global moves_remaining
    # Если фигура погибла, этот ход всё равно расходуется
    moves_remaining -= 1
    if moves_remaining <= 0:
        switch_turn()

# ========= Обновление тумана (с удалением монет при старении) =========
cell_counters = {}  # {(x,y): turns_since_last_revealed}
def update_fog():
    global global_revealed, bonus_cells, coin_cells
    previous_revealed = global_revealed.copy()
    new_revealed = set()
    for p in pieces:
        for dx in range(-2, 3):
            for dy in range(-2, 3):
                nx = p.x + dx
                ny = p.y + dy
                if 0 <= nx < GRID_WIDTH and 0 <= ny < GRID_HEIGHT:
                    new_revealed.add((nx, ny))
    for merchant_pos in merchant_positions:
        new_revealed.add(merchant_pos)
    newly_revealed = new_revealed - previous_revealed
    for y in range(GRID_HEIGHT):
        for x in range(GRID_WIDTH):
            pos = (x, y)
            if pos in new_revealed:
                cell_counters[pos] = 0
                global_revealed.add(pos)
            else:
                if pos in cell_counters:
                    cell_counters[pos] += 1
                else:
                    cell_counters[pos] = 1
                if cell_counters[pos] >= 5:
                    if pos in global_revealed:
                        global_revealed.remove(pos)
                    if pos in bonus_cells and bonus_cells[pos]['type'] != 'damage':
                        del bonus_cells[pos]
                    if pos in coin_cells:
                        del coin_cells[pos]
    for pos in newly_revealed:
        if pos not in bonus_cells and pos not in coin_cells and random.random() < BONUS_GENERATION_CHANCE:
            # 95% шанс бонус, 5% монета
            if random.random() < 0.95:
                bonus_type = choose_bonus_type()
                if not any(p.x == pos[0] and p.y == pos[1] for p in pieces):
                    bonus_cells[pos] = {'type': bonus_type}
            else:
                if not any(p.x == pos[0] and p.y == pos[1] for p in pieces):
                    coin_cells.add(pos)

# ========= Функции отрисовки =========
def draw_grid():
    for x in range(0, CELL_SIZE * GRID_WIDTH, CELL_SIZE):
        pygame.draw.line(screen, COLOR_GRID, (x, 0), (x, CELL_SIZE * GRID_HEIGHT))
    for y in range(0, CELL_SIZE * GRID_HEIGHT, CELL_SIZE):
        pygame.draw.line(screen, COLOR_GRID, (0, y), (CELL_SIZE * GRID_WIDTH, y))

def draw_environment():
    for y in range(GRID_HEIGHT):
        for x in range(GRID_WIDTH):
            pos = (x, y)
            rect = pygame.Rect(x * CELL_SIZE, y * CELL_SIZE, CELL_SIZE, CELL_SIZE)
            if pos in global_revealed:
                if open_cell_sprite:
                    screen.blit(open_cell_sprite, rect)
                else:
                    pygame.draw.rect(screen, (30, 30, 30), rect)
                if cell_counters.get(pos, 0) == 4 and (pos not in bonus_cells) and (pos not in coin_cells):
                    if fog_sprite:
                        overlay = fog_sprite.copy()
                        overlay.set_alpha(128)
                        screen.blit(overlay, rect)
                    else:
                        overlay = pygame.Surface((CELL_SIZE, CELL_SIZE))
                        overlay.set_alpha(128)
                        overlay.fill((169, 169, 169))
                        screen.blit(overlay, rect)
            else:
                if fog_sprite:
                    screen.blit(fog_sprite, rect)
                else:
                    pygame.draw.rect(screen, COLOR_FOG, rect)

def draw_bonus_cells():
    for (bx, by), info in bonus_cells.items():
        if info['type'] != 'damage' and (bx, by) not in global_revealed:
            continue
        cx = bx * CELL_SIZE + CELL_SIZE // 2
        cy = by * CELL_SIZE + CELL_SIZE // 2
        bonus_type = info['type']
        if bonus_type == 'regen':
            color = COLOR_REGEN
            pygame.draw.circle(screen, color, (cx, cy), CELL_SIZE // 4)
        elif bonus_type == 'hp_upgrade':
            color = COLOR_HP_UPGRADE
            pygame.draw.circle(screen, color, (cx, cy), CELL_SIZE // 4)
        elif bonus_type == 'damage':
            color = COLOR_DAMAGE
            pygame.draw.circle(screen, color, (cx, cy), CELL_SIZE // 4)
        elif bonus_type == 'king_hp_upgrade':
            color = COLOR_KING_HP_UPGRADE
            pygame.draw.circle(screen, color, (cx, cy), CELL_SIZE // 4)
        elif bonus_type == 'add_piece':
            possible = False
            for dx, dy in [(-1,0),(1,0),(0,-1),(0,1),(-1,-1),(1,-1),(1,1),(-1,1)]:
                nx = bx + dx
                ny = by + dy
                if 0 <= nx < GRID_WIDTH and 0 <= ny < GRID_HEIGHT:
                    if not any(p.x == nx and p.y == ny for p in pieces):
                        possible = True
                        break
            color = COLOR_ADD_PIECE if possible else COLOR_ADD_PIECE_PINK
            pygame.draw.circle(screen, color, (cx, cy), CELL_SIZE // 4)
            pygame.draw.line(screen, (0, 0, 0), (cx - CELL_SIZE // 8, cy), (cx + CELL_SIZE // 8, cy), 2)
            pygame.draw.line(screen, (0, 0, 0), (cx, cy - CELL_SIZE // 8), (cx, cy + CELL_SIZE // 8), 2)

def draw_coin_cells():
    for pos in coin_cells:
        if pos not in global_revealed:
            continue
        x, y = pos
        cx = x * CELL_SIZE + CELL_SIZE // 2
        cy = y * CELL_SIZE + CELL_SIZE // 2
        size = CELL_SIZE // 3
        point1 = (cx, cy - size)
        point2 = (cx - size, cy + size)
        point3 = (cx + size, cy + size)
        pygame.draw.polygon(screen, COLOR_COIN, [point1, point2, point3])
        dollar_text = font.render('$', True, (0, 0, 0))
        text_rect = dollar_text.get_rect(center=(cx, cy))
        screen.blit(dollar_text, text_rect)

def draw_merchants():
    for pos in merchant_positions:
        x, y = pos
        rect = pygame.Rect(x * CELL_SIZE, y * CELL_SIZE, CELL_SIZE, CELL_SIZE)
        pygame.draw.rect(screen, COLOR_MERCHANT, rect)
        points = [
            (x * CELL_SIZE + CELL_SIZE // 2, y * CELL_SIZE + CELL_SIZE // 4),
            (x * CELL_SIZE + CELL_SIZE // 4, y * CELL_SIZE + 3 * CELL_SIZE // 4),
            (x * CELL_SIZE + 3 * CELL_SIZE // 4, y * CELL_SIZE + 3 * CELL_SIZE // 4)
        ]
        pygame.draw.polygon(screen, (255, 255, 255), points)

def draw_pieces(pieces):
    for p in pieces:
        x = p.x * CELL_SIZE
        y = p.y * CELL_SIZE
        sprite = piece_sprites.get((p.color, p.name))
        if sprite:
            screen.blit(sprite, (x, y))
        else:
            rect = pygame.Rect(x, y, CELL_SIZE, CELL_SIZE)
            if p.color == 'white':
                pygame.draw.rect(screen, COLOR_WHITE_PIECE, rect)
            else:
                pygame.draw.rect(screen, COLOR_BLACK_PIECE, rect)
            symbol = piece_symbols.get(p.name, '?')
            text = font.render(symbol, True, (255, 0, 0))
            text_rect = text.get_rect(center=rect.center)
            screen.blit(text, text_rect)
        hp_str = f"{p.hp}/{p.max_hp}"
        if p.color == 'white':
            text_color = (0, 0, 0)
            bg_color = (255, 255, 255)
        else:
            text_color = (255, 255, 255)
            bg_color = (0, 0, 0)
        hp_text = font.render(hp_str, True, text_color)
        text_rect = hp_text.get_rect(topleft=(x + 2, y + 2))
        bg_surf = pygame.Surface(text_rect.size)
        bg_surf.set_alpha(200)
        bg_surf.fill(bg_color)
        screen.blit(bg_surf, text_rect.topleft)
        screen.blit(hp_text, text_rect.topleft)
        if p.selected:
            rect = pygame.Rect(x, y, CELL_SIZE, CELL_SIZE)
            pygame.draw.rect(screen, COLOR_SELECTED, rect, 2)
    for (mx, my) in possible_moves:
        r = pygame.Rect(mx * CELL_SIZE, my * CELL_SIZE, CELL_SIZE, CELL_SIZE)
        pygame.draw.rect(screen, COLOR_MOVE, r, 2)

def draw_statistics_panel():
    panel_rect = pygame.Rect(CELL_SIZE * GRID_WIDTH, 0, PANEL_WIDTH, WINDOW_HEIGHT)
    pygame.draw.rect(screen, (50, 50, 50), panel_rect)
    title_text = shop_font.render("Статистика", True, (255, 255, 255))
    screen.blit(title_text, (CELL_SIZE * GRID_WIDTH + 10, 10))
    turn_text = turn_font.render(f"Ход: {current_turn.capitalize()}", True, COLOR_TURN_TEXT)
    screen.blit(turn_text, (CELL_SIZE * GRID_WIDTH + 10, 50))
    counter_text = counter_font.render(f"Ходов: {turn_count}", True, (255, 255, 255))
    screen.blit(counter_text, (CELL_SIZE * GRID_WIDTH + 10, 80))
    time_left = get_time_left()
    minutes = time_left // 60
    seconds = time_left % 60
    timer_text_str = f"Время: {minutes:02}:{seconds:02}"
    color = COLOR_TIMER_WARNING if timer_expired and player_timeouts[current_turn] >= 1 else COLOR_TIMER_NORMAL
    timer_text = timer_font.render(timer_text_str, True, color)
    screen.blit(timer_text, (CELL_SIZE * GRID_WIDTH + 10, 110))
    coins_text_white = counter_font.render(f"Белые монеты: {player_coins['white']}", True, (255, 255, 0))
    coins_text_black = counter_font.render(f"Чёрные монеты: {player_coins['black']}", True, (255, 255, 0))
    screen.blit(coins_text_white, (CELL_SIZE * GRID_WIDTH + 10, 140))
    screen.blit(coins_text_black, (CELL_SIZE * GRID_WIDTH + 10, 170))
    moves_text = counter_font.render(f"Осталось ходов: {moves_remaining}", True, (255, 255, 255))
    screen.blit(moves_text, (CELL_SIZE * GRID_WIDTH + 10, 200))
    if shop_open:
        draw_shop()

def draw_shop():
    shop_x = CELL_SIZE * GRID_WIDTH + 10
    shop_y = 240
    shop_title = shop_font.render("Магазин", True, (255, 255, 0))
    screen.blit(shop_title, (shop_x, shop_y))
    for idx, (key, item) in enumerate(shop_items.items()):
        item_y = shop_y + 40 + idx * 60
        button_rect = pygame.Rect(shop_x, item_y, PANEL_WIDTH - 20, 50)
        button_color = (0, 255, 0) if player_coins[current_turn] >= item['cost'] else (128, 128, 128)
        pygame.draw.rect(screen, button_color, button_rect)
        item_text = shop_font.render(f"{item['name']} - {item['cost']} мон.", True, (0, 0, 0))
        screen.blit(item_text, (shop_x + 5, item_y + 15))
        shop_items[key]['button_rect'] = button_rect

def draw_victory(winner):
    text = victory_font.render(f"{winner.capitalize()} победил!", True, (255, 255, 255))
    text_rect = text.get_rect(center=(WINDOW_WIDTH // 2, WINDOW_HEIGHT // 2))
    screen.blit(text, text_rect)

# ========= Применение бонуса =========
def apply_bonus(piece, bonus_type, pieces):
    if bonus_type == 'regen':
        if piece.name != 'king':
            amt = random.randint(1, 2)
            piece.hp = min(piece.hp + amt, piece.max_hp)
    elif bonus_type == 'hp_upgrade':
        if piece.name != 'king':
            piece.max_hp += 1
    elif bonus_type == 'king_hp_upgrade':
        if piece.name != 'king':
            king = next((p for p in pieces if p.name == 'king' and p.color == piece.color), None)
            if king:
                if king.hp == king.max_hp:
                    king.max_hp += 1
                    king.hp = king.max_hp
                else:
                    king.hp = min(king.hp + 1, king.max_hp)
    elif bonus_type == 'damage':
        damage = random.randint(1, 5)
        piece.hp -= damage
        print(f"Бонус DAMAGE: Фигура получила {damage} урона, осталось {piece.hp} HP")
        if piece.hp <= 0:
            try:
                pieces.remove(piece)
            except ValueError:
                pass
            return 'dead'
    elif bonus_type == 'add_piece':
        if piece.name != 'king':
            directions = [(-1,0),(1,0),(0,-1),(0,1),(-1,-1),(1,-1),(1,1),(-1,1)]
            random.shuffle(directions)
            for dx, dy in directions:
                nx = piece.x + dx
                ny = piece.y + dy
                if 0 <= nx < GRID_WIDTH and 0 <= ny < GRID_HEIGHT:
                    if not any(p.x == nx and p.y == ny for p in pieces) and (nx, ny) not in bonus_cells and (nx, ny) not in merchant_positions:
                        new_piece = Piece(piece.name, piece.color, nx, ny)
                        pieces.append(new_piece)
                        break

# ========= Инициализация фигур =========
pieces = initialize_pieces()
selected_piece = None
possible_moves = []
game_over = False
winner = None

# ========= Инициализация тумана =========
cell_counters = {}  # {(x,y): turns_since_last_revealed}
update_fog()

# ========= Основной игровой цикл =========
running = True
clock = pygame.time.Clock()

while running:
    clock.tick(30)
    check_timer()
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
        elif event.type == pygame.MOUSEBUTTONDOWN and not game_over:
            mx, my = pygame.mouse.get_pos()
            if mx < CELL_SIZE * GRID_WIDTH and my < CELL_SIZE * GRID_HEIGHT:
                gx = mx // CELL_SIZE
                gy = my // CELL_SIZE
                clicked_piece = next((p for p in pieces if p.x == gx and p.y == gy), None)
                if selected_piece:
                    if (gx, gy) in possible_moves:
                        # Если на клетке есть бонус damage по пути
                        if selected_piece.name in ['rook', 'bishop', 'queen']:
                            # Если фигура двигается на несколько клеток, проверяем промежуточный путь
                            path = []
                            dx = gx - selected_piece.x
                            dy = gy - selected_piece.y
                            if dx != 0:
                                dx //= abs(dx)
                            if dy != 0:
                                dy //= abs(dy)
                            for step in range(1, max(abs(gx - selected_piece.x), abs(gy - selected_piece.y))):
                                path_x = selected_piece.x + dx * step
                                path_y = selected_piece.y + dy * step
                                path.append((path_x, path_y))
                            survived = True
                            for pos in path:
                                if pos in bonus_cells and bonus_cells[pos]['type'] == 'damage':
                                    damage = random.randint(1, 5)
                                    selected_piece.hp = max(selected_piece.hp - damage, 0)
                                    del bonus_cells[pos]
                                    if selected_piece.hp == 0:
                                        # — модификация для обработки смерти на пути:
                                        pieces.remove(selected_piece)
                                        selected_piece = None
                                        possible_moves.clear()
                                        survived = False
                                        # Считаем, что ход потрачен, уменьшаем moves_remaining
                                        moves_remaining -= 1
                                        break
                            if not survived:
                                if moves_remaining <= 0:
                                    switch_turn()
                                continue
                        # Если бонус (damage или другой) находится непосредственно на целевой клетке
                        if (gx, gy) in bonus_cells:
                            bonus_type = bonus_cells[(gx, gy)]['type']
                            result = apply_bonus(selected_piece, bonus_type, pieces)
                            del bonus_cells[(gx, gy)]
                            if result == 'dead':
                                # Если фигура погибла, засчитываем ход, уменьшаем счетчик и остаёмся на том же игроке
                                moves_remaining -= 1
                                if moves_remaining <= 0:
                                    switch_turn()
                                selected_piece = None
                                possible_moves.clear()
                                continue
                        if (gx, gy) in coin_cells:
                            player_coins[current_turn] += 1
                            coin_cells.remove((gx, gy))
                        if (gx, gy) in merchant_positions:
                            shop_open = True
                        defender = next((p for p in pieces if p.x == gx and p.y == gy), None)
                        if defender:
                            attacker = selected_piece
                            attacker_alive, defender_alive = resolve_combat(attacker, defender)
                            if not defender_alive:
                                if defender.name == 'king':
                                    winner = attacker.color
                                    game_over = True
                                pieces.remove(defender)
                            if not attacker_alive:
                                pieces.remove(attacker)
                                selected_piece = None
                                possible_moves.clear()
                                moves_remaining -= 1
                                if moves_remaining <= 0:
                                    switch_turn()
                                continue
                            else:
                                path = []
                                if attacker.name in ['rook', 'bishop', 'queen']:
                                    dx = gx - attacker.x
                                    dy = gy - attacker.y
                                    if dx != 0:
                                        dx //= abs(dx)
                                    if dy != 0:
                                        dy //= abs(dy)
                                    for step in range(1, max(abs(gx - attacker.x), abs(gy - attacker.y))):
                                        path_x = attacker.x + dx * step
                                        path_y = attacker.y + dy * step
                                        path.append((path_x, path_y))
                                survived = True
                                for pos in path:
                                    if pos in bonus_cells and bonus_cells[pos]['type'] == 'damage':
                                        damage = random.randint(1, 5)
                                        attacker.hp = max(attacker.hp - damage, 0)
                                        del bonus_cells[pos]
                                        if attacker.hp == 0:
                                            pieces.remove(attacker)
                                            selected_piece = None
                                            possible_moves.clear()
                                            survived = False
                                            moves_remaining -= 1
                                            break
                                if not survived:
                                    if moves_remaining <= 0:
                                        switch_turn()
                                    continue
                                attacker.x = gx
                                attacker.y = gy
                                attacker.selected = False
                                end_move(attacker)
                                selected_piece = None
                                possible_moves.clear()
                        else:
                            path = []
                            if selected_piece.name in ['rook', 'bishop', 'queen']:
                                dx = gx - selected_piece.x
                                dy = gy - selected_piece.y
                                if dx != 0:
                                    dx //= abs(dx)
                                if dy != 0:
                                    dy //= abs(dy)
                                for step in range(1, max(abs(gx - selected_piece.x), abs(gy - selected_piece.y))):
                                    path_x = selected_piece.x + dx * step
                                    path_y = selected_piece.y + dy * step
                                    path.append((path_x, path_y))
                            survived = True
                            for pos in path:
                                if pos in bonus_cells and bonus_cells[pos]['type'] == 'damage':
                                    damage = random.randint(1, 5)
                                    selected_piece.hp = max(selected_piece.hp - damage, 0)
                                    del bonus_cells[pos]
                                    if selected_piece.hp == 0:
                                        pieces.remove(selected_piece)
                                        selected_piece = None
                                        possible_moves.clear()
                                        survived = False
                                        moves_remaining -= 1
                                        break
                            if not survived:
                                if moves_remaining <= 0:
                                    switch_turn()
                                continue
                            selected_piece.x = gx
                            selected_piece.y = gy
                            selected_piece.selected = False
                            end_move(selected_piece)
                            selected_piece = None
                            possible_moves.clear()
                        update_fog()
                    else:
                        selected_piece.selected = False
                        selected_piece = None
                        possible_moves.clear()
                else:
                    if clicked_piece and (gx, gy) in global_revealed and clicked_piece.color == current_turn and not clicked_piece.has_moved:
                        selected_piece = clicked_piece
                        selected_piece.selected = True
                        possible_moves = selected_piece.get_possible_moves(pieces)
            else:
                if shop_open:
                    for key, item in shop_items.items():
                        if 'button_rect' in item and item['button_rect'].collidepoint(mx, my):
                            if player_coins[current_turn] >= item['cost']:
                                # Здесь можно добавить логику покупки
                                pass
        elif event.type == pygame.KEYDOWN:
            if event.key == pygame.K_ESCAPE:
                shop_open = False
    screen.fill(COLOR_BG)
    draw_environment()
    draw_grid()
    draw_merchants()
    draw_bonus_cells()
    draw_coin_cells()
    draw_pieces(pieces)
    draw_statistics_panel()
    if game_over and winner:
        draw_victory(winner)
    pygame.display.flip()

pygame.quit()
sys.exit()
