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


import pygame
import sys
import random
import math
from collections import deque
import json
import os

RECORDS_FILE = "survival_records.json"

def load_records():
    """Загружает рекорды из файла. Если файла нет, возвращает словарь с нулями."""
    if os.path.exists(RECORDS_FILE):
        try:
            with open(RECORDS_FILE, 'r', encoding='utf-8') as f:
                return json.load(f)
        except:
            pass
    # Значения по умолчанию
    return {
        "snakes": 0,
        "spiders": 0,
        "slimes": 0,
        "insects": 0,
        "fish": 0
    }

def save_records(records):
    """Сохраняет рекорды в файл."""
    with open(RECORDS_FILE, 'w', encoding='utf-8') as f:
        json.dump(records, f, ensure_ascii=False, indent=2)

# Загружаем рекорды при старте (глобально или в каждой функции)
survival_records = load_records()

# Инициализация Pygame
pygame.init()

# Константы
GRID_SIZE = 17
CELL_SIZE = 45
WIDTH = GRID_SIZE * CELL_SIZE
HEIGHT = GRID_SIZE * CELL_SIZE
FPS = 30

# Цвета
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
GRAY = (180, 180, 180)
LIGHT_GRAY = (220, 220, 220)
BUTTON_COLOR = (100, 100, 255)
BUTTON_HOVER_COLOR = (150, 150, 255)
TEXT_COLOR = (230, 230, 230)
MENU_BG = (240, 240, 245)

# Цвета змеек
GREEN = (0, 255, 0)
DARK_GREEN = (0, 150, 0)
DARK_GREEN_PURPLE = (0, 100, 0)
PURPLE_SPOT = (128, 0, 128)
BRIGHT_GREEN = (50, 255, 50)
YELLOW_STRIPE = (255, 255, 0)
RED_SNAKE = (255, 0, 0)
DARK_RED_SNAKE = (139, 0, 0)
BLUE = (0, 0, 255)
DARK_BLUE = (0, 0, 139)
DARK_BLUE_PURPLE = (0, 0, 100)
PURPLE_DOT = (138, 43, 226)
LIGHT_BLUE = (100, 100, 255)
CYAN_STRIPE = (0, 255, 255)
BLACK_SNAKE = (20, 20, 20)
DARK_GRAY_BODY = (60, 60, 60)
RED_EYE = (255, 0, 0)

ORANGE_STRIPE = (255, 165, 0)
BRIGHT_ORANGE_STRIPE = (255, 100, 0)
SWAMP_GREEN = (85, 107, 47)
PINK_AZURE = (255, 105, 180)
WHITE_SNAKE = (240, 240, 240)
WHITE_PURPLE_STRIPE = (200, 150, 255)
WHITE_RED_SPOT = (255, 200, 200)

PURPLE_FIRE = (255, 0, 255)

# Цвета для пауков
SPIDER_LIGHT_GRAY = (200, 200, 200)
SPIDER_BROWN_GRAY = (139, 69, 19)
SPIDER_DARK_GRAY = (70, 70, 70)
SPIDER_RED_CROSS = (255, 0, 0)
SPIDER_GREEN_CIRCLE = (0, 255, 0)
SPIDER_DARK_RED = (139, 0, 0)
SPIDER_BIG_DARK_GRAY = (50, 50, 50)
SPIDER_BLACK = (0, 0, 0)
SPIDER_WHITE_PURPLE = (240, 240, 240)

LIGHT_BLUE_CELL = (173, 216, 230)
LIGHT_PINK_CELL = (255, 182, 193)

# Цвета для насекомых и песка
SAND_INSECT_LIGHT = (245, 222, 179)
SAND_INSECT_DARK = (210, 180, 140)
FISH_LIGHT_BLUE = (135, 206, 250)
FISH_DARK_BLUE = (70, 130, 180)

ANT_COLOR = (139, 69, 19)
DUNG_BEETLE_COLOR = (85, 107, 47)
STAG_BEETLE_COLOR = (60, 60, 60)
ANTHILL_COLOR = (101, 67, 33)
POISON_COLOR = (100, 200, 100)

# Цвета для воды (режим рыб)
WATER_DEEP = (30, 80, 140)        # больше не используется, заменён на FISH_*
WATER_SHALLOW = (60, 140, 210)

# Русские названия змей (глобально)
RU_NAMES_SNAKES = {
    "green": "Зелёная",
    "dark_green": "Фиолетовая",
    "bright_green": "Быстрая",
    "stripe_green": "Стреляющая зелёная",
    "swamp_green": "Болотная",
    "blue": "РЎРёРЅСЏСЏ",
    "dark_blue": "Тёмно-синяя",
    "light_blue": "Светло-синяя",
    "stripe_blue": "Полосатая синяя",
    "pink_azure": "Розово-лазурная",
    "white": "Белая",
    "white_purple": "Бело-фиолетовая",
    "white_red": "Бело-красная",
    "red": "Красная",
    "black": "Чёрная",
    "rainbow_snake": "Радужная",
    "white_gray": "Бело-серая"
}

FOG_RADIUS = 7   # радиус видимости в клетках для модификатора "туман"

# Настройка окна
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("Птичка против Врагов")
clock = pygame.time.Clock()
font = pygame.font.Font(None, 36)
small_font = pygame.font.Font(None, 24)
tiny_font = pygame.font.Font(None, 20)
micro_font = pygame.font.Font(None, 18)

fullscreen = False
bird_skin = 0  # 0-серый, 1-синий, 2-красный, 3-жёлтый, 4-чёрный

def draw_half_circle(surface, color, center, radius, direction, border_color=BLACK, border_width=2):
    """
    Рисует полукруг, направленный выпуклой частью по вектору direction.
    direction: кортеж (dx, dy), где dx, dy — целые числа (-1,0,1).
    """
    dx, dy = direction
    # Угол направления движения (в радианах)
    angle = math.atan2(dy, dx)
    # Полукруг от -90° до +90° относительно направления
    start_angle = angle - math.pi / 2
    end_angle = angle + math.pi / 2
    # Количество точек на дуге
    num_points = 20
    points = [center]
    for i in range(num_points + 1):
        t = start_angle + (end_angle - start_angle) * i / num_points
        x = center[0] + radius * math.cos(t)
        y = center[1] + radius * math.sin(t)
        points.append((x, y))
    # Рисуем залитый полигон
    if len(points) > 2:
        pygame.draw.polygon(surface, color, points)
        if border_width > 0:
            pygame.draw.polygon(surface, border_color, points, border_width)


def draw_droplet(surface, color, center, radius, direction, border_color=BLACK, border_width=2):
    """
    Рисует каплю, направленную остриём по вектору direction.
    direction: кортеж (dx, dy) - направление движения.
    """
    dx, dy = direction
    angle = math.atan2(dy, dx)  # угол направления

    # Параметры капли
    head_radius = radius
    tail_length = radius * 1.2  # длина хвоста
    tail_width = radius * 0.6  # ширина хвоста у основания

    # Центр головы капли (смещён немного назад, чтобы хвост был сзади)
    head_center_offset = tail_length * 0.3
    head_cx = center[0] - dx * head_center_offset
    head_cy = center[1] - dy * head_center_offset

    # Точки для полигона капли
    points = []

    # Полукруг спереди (от -90° до +90° относительно направления)
    num_points = 12
    start_angle = angle - math.pi / 2
    end_angle = angle + math.pi / 2
    for i in range(num_points + 1):
        t = start_angle + (end_angle - start_angle) * i / num_points
        x = head_cx + head_radius * math.cos(t)
        y = head_cy + head_radius * math.sin(t)
        points.append((x, y))

    # Хвост: сужающаяся часть сзади
    # Правая точка основания хвоста
    tail_base_rx = head_cx + head_radius * math.cos(angle - math.pi / 2)
    tail_base_ry = head_cy + head_radius * math.sin(angle - math.pi / 2)
    # Левая точка основания хвоста
    tail_base_lx = head_cx + head_radius * math.cos(angle + math.pi / 2)
    tail_base_ly = head_cy + head_radius * math.sin(angle + math.pi / 2)
    # Остриё хвоста
    tail_tip_x = head_cx - dx * tail_length
    tail_tip_y = head_cy - dy * tail_length

    # Добавляем остриё и возвращаемся к началу полукруга (в обратном порядке)
    points.append((tail_tip_x, tail_tip_y))

    # Рисуем залитый полигон
    if len(points) > 2:
        pygame.draw.polygon(surface, color, points)
        if border_width > 0:
            pygame.draw.polygon(surface, border_color, points, border_width)

    # Белая точка в центре головы (как у полукруга)
    dot_radius = radius // 2
    pygame.draw.circle(surface, WHITE, (int(head_cx), int(head_cy)), dot_radius)
    pygame.draw.circle(surface, BLACK, (int(head_cx), int(head_cy)), dot_radius, 1)

def rotate_point(x, y, angle, cx=0, cy=0):
    """Поворачивает точку (x,y) вокруг (cx,cy) на угол angle в радианах."""
    cos_a = math.cos(angle)
    sin_a = math.sin(angle)
    nx = cx + (x - cx) * cos_a - (y - cy) * sin_a
    ny = cy + (x - cx) * sin_a + (y - cy) * cos_a
    return nx, ny

# ---------------------- РљРќРћРџРљРђ ----------------------
class Button:
    def __init__(self, x, y, width, height, text, action=None, color=BUTTON_COLOR, hover_color=BUTTON_HOVER_COLOR,
                 text_color=TEXT_COLOR, font=None):
        self.rect = pygame.Rect(x, y, width, height)
        self.text = text
        self.action = action
        self.color = color
        self.hover_color = hover_color
        self.text_color = text_color
        self.font = font if font else pygame.font.Font(None, 36)

    def draw(self, surface):
        mouse_pos = pygame.mouse.get_pos()
        if self.rect.collidepoint(mouse_pos):
            pygame.draw.rect(surface, self.hover_color, self.rect, border_radius=5)
        else:
            pygame.draw.rect(surface, self.color, self.rect, border_radius=5)
        pygame.draw.rect(surface, BLACK, self.rect, 2, border_radius=5)

        text_surf = self.font.render(self.text, True, self.text_color)
        text_rect = text_surf.get_rect(center=self.rect.center)
        surface.blit(text_surf, text_rect)

    def handle_event(self, event):
        if event.type == pygame.MOUSEBUTTONDOWN:
            if self.rect.collidepoint(event.pos):
                if self.action:
                    self.action()

# ---------------------- ОТРИСОВКА ПТИЧКИ ----------------------
def draw_bird(screen, x, y, visible=True, black_shadow=False):
    if not visible:
        return
    center_x = x * CELL_SIZE + CELL_SIZE // 2
    center_y = y * CELL_SIZE + CELL_SIZE // 2
    radius = CELL_SIZE // 3

    if black_shadow:
        pygame.draw.circle(screen, BLACK, (center_x, center_y), radius)
        return

    if bird_skin == 0:
        body_color = (80, 80, 80)
        wing_color = (60, 60, 60)
        beak_color = (255, 200, 0)
    elif bird_skin == 1:
        body_color = (70, 130, 180)
        wing_color = (50, 100, 150)
        beak_color = (255, 215, 0)
    elif bird_skin == 2:
        body_color = (120, 60, 60)
        wing_color = (90, 40, 40)
        beak_color = (255, 100, 100)
    elif bird_skin == 3:
        body_color = (255, 255, 0)
        wing_color = (200, 200, 0)
        beak_color = (255, 140, 0)
    else:
        body_color = (30, 30, 30)
        wing_color = (10, 10, 10)
        beak_color = (200, 200, 200)

    pygame.draw.circle(screen, body_color, (center_x, center_y), radius)
    pygame.draw.circle(screen, WHITE, (center_x + radius // 3, center_y - radius // 3), radius // 4)
    pygame.draw.circle(screen, BLACK, (center_x + radius // 3, center_y - radius // 3), radius // 8)
    pygame.draw.polygon(screen, beak_color, [
        (center_x + radius // 2, center_y),
        (center_x + radius, center_y - radius // 6),
        (center_x + radius, center_y + radius // 6)
    ])
    pygame.draw.ellipse(screen, wing_color, (center_x - radius, center_y, radius, radius // 2))

# ---------------------- ЗМЕИ ----------------------
SNAKE_INFO_ORDERED = [
    "green", "dark_green", "bright_green", "stripe_green", "swamp_green",
    "blue", "dark_blue", "light_blue", "stripe_blue", "pink_azure",
    "white", "white_purple", "white_red",
    "red", "black", "rainbow_snake", "white_gray"   # добавлена бело-серая
]

TAB_CATEGORIES_SNAKES = {
    "Зелёные": ["green", "dark_green", "bright_green", "stripe_green", "swamp_green"],
    "РЎРёРЅРёРµ": ["blue", "dark_blue", "light_blue", "stripe_blue", "pink_azure"],
    "Белые": ["white", "white_purple", "white_red", "white_gray"],
    "РњРёРЅРёР±РѕСЃСЃС‹": ["red", "black"],
    "Радужные": ["rainbow_snake"]
}
TAB_NAMES_SNAKES = ["Зелёные", "Синие", "Белые", "Минибоссы", "Радужные"]

SNAKE_INFO = {
    "green": {
        "description": "Стандартная змейка. Средняя скорость и длина.",
        "length_range": "4-6", "speed": 1, "special": "Нет",
        "color": GREEN, "head_color": DARK_GREEN, "body_color": GREEN, "width": 1
    },
    "dark_green": {
        "description": "Хитрая змейка, умеет резко менять направление.",
        "length_range": "4-8", "speed": 1, "special": "Повороты: 2",
        "color": DARK_GREEN_PURPLE, "head_color": DARK_GREEN_PURPLE, "body_color": DARK_GREEN_PURPLE, "width": 1
    },
    "bright_green": {
        "description": "Быстрая змейка, движется в два раза быстрее.",
        "length_range": "3-5", "speed": 2, "special": "Нет",
        "color": BRIGHT_GREEN, "head_color": BRIGHT_GREEN, "body_color": BRIGHT_GREEN, "width": 1
    },
    "stripe_green": {
        "description": "Стреляет огненными шарами раз в 5 ходов вправо и влево.",
        "length_range": "2-3", "speed": 1, "special": "Стрельба",
        "color": GREEN, "head_color": DARK_GREEN, "body_color": GREEN, "width": 1
    },
    "swamp_green": {
        "description": "Двигается рывками: 2 хода стоит, затем прыжок на 3 клетки.",
        "length_range": "6-7", "speed": "рывок", "special": "Рывок через ход",
        "color": SWAMP_GREEN, "head_color": SWAMP_GREEN, "body_color": (60, 80, 30), "width": 1
    },
    "blue": {
        "description": "Длинная и медленная змейка, заполняет поле.",
        "length_range": "5-10", "speed": 1, "special": "Нет",
        "color": BLUE, "head_color": DARK_BLUE, "body_color": BLUE, "width": 1
    },
    "dark_blue": {
        "description": "Очень хитрая и длинная, часто меняет направление.",
        "length_range": "4-9", "speed": 1, "special": "Повороты: 5",
        "color": DARK_BLUE_PURPLE, "head_color": DARK_BLUE_PURPLE, "body_color": DARK_BLUE_PURPLE, "width": 1
    },
    "light_blue": {
        "description": "Сверхбыстрая змейка, уворачивается от всего.",
        "length_range": "3-4", "speed": 3, "special": "Нет",
        "color": LIGHT_BLUE, "head_color": LIGHT_BLUE, "body_color": LIGHT_BLUE, "width": 1
    },
    "stripe_blue": {
        "description": "Стреляет огненными шарами раз в 3 хода вправо и влево.",
        "length_range": "2-4", "speed": 1, "special": "Частая стрельба",
        "color": BLUE, "head_color": DARK_BLUE, "body_color": BLUE, "width": 1
    },
    "pink_azure": {
        "description": "Двигается рывками: 2 хода стоит, затем прыжок на 4 клетки.",
        "length_range": "7-8", "speed": "рывок", "special": "Рывок на 4 клетки",
        "color": PINK_AZURE, "head_color": PINK_AZURE, "body_color": (200, 80, 140), "width": 1
    },
    "white": {
        "description": "Белая змея, заменяет синих после 2 чёрных.",
        "length_range": "7-12", "speed": 2, "special": "Повороты: 1",
        "color": WHITE_SNAKE, "head_color": (200, 200, 200), "body_color": WHITE_SNAKE, "width": 1
    },
    "white_purple": {
        "description": "Белая с фиолетовыми полосками, заменяет стреляющих после 3 чёрных.",
        "length_range": "8-13", "speed": 1, "special": "Повороты: 7",
        "color": WHITE_PURPLE_STRIPE, "head_color": (180, 130, 230), "body_color": WHITE_SNAKE, "width": 1
    },
    "white_red": {
        "description": "Белая с красными пятнами, стреляет полосами фиолетового огня (длина 3, скорость 2).",
        "length_range": "4-5", "speed": 1, "special": "Полосы 3 кл., скор. 2",
        "color": WHITE_RED_SPOT, "head_color": (255, 150, 150), "body_color": WHITE_SNAKE, "width": 1
    },
    "white_gray": {
        "description": "Бело-серая змея. Каждый ход создаёт невидимое облако вокруг головы (радиус 2-3, 3 хода).",
        "length_range": "5-7", "speed": 1, "special": "Невидимый газ, 3 поворота", "spawn_condition": "После 5 чёрных",
        "color": (200, 200, 200), "head_color": (160, 160, 160), "body_color": (180, 180, 180), "width": 1
    },
    "red": {
        "description": "Опасная, большая змейка, появляется редко, но метко. Стреляет огненными шарами.",
        "length_range": "14-16", "speed": 1, "special": "Ширина: 2, стрельба",
        "color": RED_SNAKE, "head_color": DARK_RED_SNAKE, "body_color": RED_SNAKE, "width": 2
    },
    "black": {
        "description": "Самая большая и смертоносная, медленно, но верно уничтожает. Стреляет двумя фиолетовыми шарами.",
        "length_range": "30", "speed": 2, "special": "РЁРёСЂРёРЅР°: 3",
        "color": BLACK_SNAKE, "head_color": BLACK_SNAKE, "body_color": DARK_GRAY_BODY, "width": 3
    },
    "rainbow_snake": {
        "description": "Радужная змея. Редчайшая. Раз в 3 хода делает рывок на 4 клетки, может дважды повернуть.",
        "length_range": "17", "speed": 1, "special": "Рывок раз в 3 хода, 2 поворота",
        "color": (255, 0, 255), "head_color": (255, 0, 255), "body_color": (200, 0, 200), "width": 2, "rainbow": True
    }
}

LEVEL_INFO = {
    # Глава 1: Змеи (уровни 1-10)
    1: {"target_type": "kill", "target_kills": 20,
        "initial_enemies": [("snake", "green", 1)],
        "spawn_pool": ["green"], "max_enemies": 10,
        "modifiers": {}, "equipment": []},
    2: {"target_type": "collect_apples", "target_apples": 5,
        "initial_enemies": [("snake", "green", 1), ("snake", "swamp_green", 1)],
        "spawn_pool": ["green", "swamp_green"], "max_enemies": 10,
        "modifiers": {}, "equipment": []},
    3: {"target_type": "survive_turns", "target_turns": 75,
        "initial_enemies": [("snake", "bright_green", 2)],
        "spawn_pool": ["bright_green"], "max_enemies": 8,
        "modifiers": {}, "equipment": []},
    4: {"target_type": "collect_apples", "target_apples": 7,
        "initial_enemies": [("snake", "dark_green", 2)],
        "spawn_pool": ["dark_green"], "max_enemies": 10,
        "modifiers": {}, "equipment": ["Метод скипа"]},
    5: {"target_type": "kill", "target_kills": 50,
        "initial_enemies": [("snake", "stripe_green", 2), ("snake", "bright_green", 2), ("snake", "dark_green", 2)],
        "spawn_pool": ["stripe_green", "bright_green", "dark_green"], "max_enemies": 12,
        "modifiers": {}, "equipment": []},
    6: {"target_type": "collect_apples", "target_apples": 10,
        "initial_enemies": [("snake", "green", 2), ("snake", "swamp_green", 1), ("snake", "stripe_green", 1)],
        "spawn_pool": ["green", "swamp_green", "stripe_green"], "max_enemies": 12,
        "modifiers": {}, "equipment": ["Мощные крылья"]},
    7: {"target_type": "survive_turns", "target_turns": 150,
        "initial_enemies": [("snake", "stripe_green", 3)],
        "spawn_pool": ["stripe_green"], "max_enemies": 10,
        "modifiers": {"god_of_torches": True}, "equipment": ["Айсаир"]},
    8: {"target_type": "collect_apples", "target_apples": 10,
        "initial_enemies": [("snake", "green", 1), ("snake", "swamp_green", 1), ("snake", "bright_green", 1),
                            ("snake", "dark_green", 1), ("snake", "stripe_green", 1)],
        "spawn_pool": ["green", "swamp_green", "bright_green", "dark_green", "stripe_green"], "max_enemies": 12,
        "modifiers": {}, "equipment": []},
    9: {"target_type": "kill", "target_kills": 75,
        "initial_enemies": [("snake", "green", 2), ("snake", "swamp_green", 2), ("snake", "bright_green", 2),
                            ("snake", "dark_green", 2), ("snake", "stripe_green", 2)],
        "spawn_pool": ["green", "swamp_green", "bright_green", "dark_green", "stripe_green"], "max_enemies": 14,
        "modifiers": {}, "equipment": ["Метод скипа", "Мощные крылья", "Айсаир"]},
    10: {"target_type": "kill_and_collect", "target_kills": 15, "target_apples": 5,
         "initial_enemies": [("snake", "red", 2)],
         "spawn_pool": ["red"], "max_enemies": 4,
         "modifiers": {}, "equipment": []},

    # Глава 2: Маленькие пауки (уровни 11-20)
    11: {"enemy_type": "spider", "arena_style": 1,
         "target_type": "kill", "target_kills": 30,
         "initial_enemies": [("spider", "light_gray", 2), ("spider", "brown_gray", 2)],
         "spawn_pool": ["light_gray", "brown_gray"], "max_enemies": 10,
         "modifiers": {}, "equipment": ["Метод скипа"]},
    12: {"enemy_type": "spider", "arena_style": 1,
         "target_type": "visit_borders",
         "initial_enemies": [("spider", "light_gray", 2), ("spider", "brown_gray", 2),
                             ("spider", "dark_gray_green_circle", 1)],
         "spawn_pool": ["light_gray", "brown_gray", "dark_gray_green_circle"], "max_enemies": 10,
         "modifiers": {}, "equipment": []},
    13: {"enemy_type": "spider", "arena_style": 1,
         "target_type": "kill", "target_kills": 25,
         "initial_enemies": [("spider", "dark_gray_green_circle", 3)],
         "spawn_pool": ["dark_gray_green_circle"], "max_enemies": 8,
         "modifiers": {}, "equipment": ["Освежитель"]},
    14: {"enemy_type": "spider", "arena_style": 1,
         "target_type": "survive_turns", "target_turns": 100,
         "initial_enemies": [("spider", "dark_gray_red_cross", 3)],
         "spawn_pool": ["dark_gray_red_cross"], "max_enemies": 8,
         "modifiers": {"walls_are_lava": True}, "equipment": ["Мощные крылья"]},
    15: {"enemy_type": "spider", "arena_style": 1,
         "target_type": "survive_turns", "target_turns": 100,
         "initial_enemies": [("spider", "dark_gray_red_cross", 2), ("spider", "dark_gray_green_circle", 2),
                             ("spider", "brown_gray", 2)],
         "spawn_pool": ["dark_gray_red_cross", "dark_gray_green_circle", "brown_gray"], "max_enemies": 10,
         "modifiers": {"walls_are_lava": True}, "equipment": ["Мощные крылья"]},
    16: {"enemy_type": "spider", "arena_style": 1,
         "target_type": "visit_borders",
         "initial_enemies": [("spider", "white_purple_circle", 2)],
         "spawn_pool": ["white_purple_circle"], "max_enemies": 8,
         "modifiers": {}, "equipment": []},
    17: {"enemy_type": "spider", "arena_style": 1,
         "target_type": "survive_turns", "target_turns": 150,
         "initial_enemies": [("spider", "white_purple_circle", 2), ("spider", "dark_gray_red_cross", 2), ("spider", "brown_gray", 2)],
         "spawn_pool": ["white_purple_circle", "dark_gray_red_cross", "brown_gray"], "max_enemies": 10,
         "modifiers": {"fog": True}, "equipment": []},
    18: {"enemy_type": "spider", "arena_style": 1,
         "target_type": "visit_corners",
         "initial_enemies": [("spider", "light_gray", 2), ("spider", "brown_gray", 2),
                             ("spider", "dark_gray_red_cross", 2), ("spider", "dark_gray_green_circle", 2),
                             ("spider", "white_purple_circle", 2)],
         "spawn_pool": ["light_gray", "brown_gray", "dark_gray_red_cross", "dark_gray_green_circle", "white_purple_circle"],
         "max_enemies": 14,
         "modifiers": {}, "equipment": ["Освежитель", "Мощные крылья", "Метод скипа"]},
    19: {"enemy_type": "spider", "arena_style": 1,
         "target_type": "kill", "target_kills": 75,
         "initial_enemies": [("spider", "light_gray", 2), ("spider", "brown_gray", 2),
                             ("spider", "dark_gray_red_cross", 2), ("spider", "dark_gray_green_circle", 2),
                             ("spider", "white_purple_circle", 2)],
         "spawn_pool": ["light_gray", "brown_gray", "dark_gray_red_cross", "dark_gray_green_circle", "white_purple_circle"],
         "max_enemies": 14,
         "modifiers": {}, "equipment": ["Освежитель", "Мощные крылья", "Метод скипа"]},
    20: {"enemy_type": "spider", "arena_style": 1,
         "target_type": "kill", "target_kills": 17,
         "initial_enemies": [("spider", "dark_red", 2)],
         "spawn_pool": ["dark_red"], "max_enemies": 4,
         "modifiers": {"fog": True, "walls_are_lava": True}, "equipment": []},
}

class Fireball:
    def __init__(self, x, y, dx, dy, speed=1, color=(255, 69, 0)):
        self.x = x
        self.y = y
        self.dx = dx
        self.dy = dy
        self.speed = speed
        self.active = True
        self.color = color
        self.move_timer = 0          # <-- добавлено

    def move(self):
        if self.speed < 1.0:
            self.move_timer += 1
            if self.move_timer >= int(1 / self.speed):
                self.move_timer = 0
                self._move_step()
        else:
            for _ in range(int(self.speed)):
                self._move_step()
                if not self.active:
                    break

    def _move_step(self):
        self.x += self.dx
        self.y += self.dy
        if not (0 <= self.x < GRID_SIZE and 0 <= self.y < GRID_SIZE):
            self.active = False

    def draw(self, screen):
        if self.active:
            rect = pygame.Rect(self.x * CELL_SIZE, self.y * CELL_SIZE, CELL_SIZE, CELL_SIZE)
            center = rect.center
            radius = CELL_SIZE // 3
            draw_droplet(screen, self.color, center, radius, (self.dx, self.dy), border_color=BLACK, border_width=2)

    def get_pos(self):
        return (self.x, self.y)

class Snake:
    def __init__(self, start_x, start_y, length, direction, snake_type='green', width=1):
        self.length = length
        self.body = deque()
        self.direction = direction
        self.snake_type = snake_type
        self.width = width
        self.turns_left = 0
        self.move_speed = 1
        self.rainbow_offset = 0
        self.shoot_cooldown = 0
        self.shoot_delay = 0

        if snake_type == 'dark_green':
            self.turns_left = 2
        elif snake_type == 'dark_blue':
            self.turns_left = 5
        elif snake_type == 'bright_green':
            self.move_speed = 2
        elif snake_type == 'light_blue':
            self.move_speed = 3
        elif snake_type == 'black':
            self.move_speed = 2
        elif snake_type == 'white':
            self.turns_left = 1
            self.move_speed = 2
        elif snake_type == 'white_purple':
            self.turns_left = 7
            self.move_speed = 1
        elif snake_type == 'white_red':
            self.shoot_delay = 3
            self.move_speed = 1
        elif snake_type == 'stripe_green':
            self.shoot_delay = 5
        elif snake_type == 'stripe_blue':
            self.shoot_delay = 3
        elif snake_type == 'swamp_green':
            self.charge = 0
            self.charge_timer = 0
            self.rush_distance = 3
        elif snake_type == 'pink_azure':
            self.charge = 0
            self.charge_timer = 0
            self.rush_distance = 4
        elif snake_type == 'rainbow_snake':
            self.turns_left = 2
            self.move_speed = 1
            self.rush_cooldown = 0
            self.rush_delay = 3
            self.rush_distance = 4
        elif snake_type == 'red':
            self.shoot_delay = 5      # красная стреляет огненными шарами
        elif snake_type == 'white_gray':
            self.turns_left = 3
            self.move_speed = 1
            self.gas_cooldown = 0

        self.create_snake_at_edge(start_x, start_y)

    def create_snake_at_edge(self, start_x, start_y):
        if self.width == 3:
            if self.direction == 'down':
                for i in range(self.length):
                    self.body.append(((start_x, start_y - i), (start_x + 1, start_y - i), (start_x + 2, start_y - i)))
            elif self.direction == 'up':
                for i in range(self.length):
                    self.body.append(((start_x, start_y + i), (start_x + 1, start_y + i), (start_x + 2, start_y + i)))
            elif self.direction == 'right':
                for i in range(self.length):
                    self.body.append(((start_x - i, start_y), (start_x - i, start_y + 1), (start_x - i, start_y + 2)))
            else:
                for i in range(self.length):
                    self.body.append(((start_x + i, start_y), (start_x + i, start_y + 1), (start_x + i, start_y + 2)))
        elif self.width == 2:
            if self.direction == 'down':
                for i in range(self.length):
                    self.body.append(((start_x, start_y - i), (start_x + 1, start_y - i)))
            elif self.direction == 'up':
                for i in range(self.length):
                    self.body.append(((start_x, start_y + i), (start_x + 1, start_y + i)))
            elif self.direction == 'right':
                for i in range(self.length):
                    self.body.append(((start_x - i, start_y), (start_x - i, start_y + 1)))
            else:
                for i in range(self.length):
                    self.body.append(((start_x + i, start_y), (start_x + i, start_y + 1)))
        else:
            if self.direction == 'down':
                for i in range(self.length):
                    self.body.append((start_x, start_y - i))
            elif self.direction == 'up':
                for i in range(self.length):
                    self.body.append((start_x, start_y + i))
            elif self.direction == 'right':
                for i in range(self.length):
                    self.body.append((start_x - i, start_y))
            else:
                for i in range(self.length):
                    self.body.append((start_x + i, start_y))

    def calculate_direction_to_player(self, bird_x, bird_y):
        if not self.body:
            return self.direction
        if self.width == 1:
            head_x, head_y = self.body[0]
        else:
            head_x = self.body[0][0][0]
            head_y = self.body[0][0][1]
        dx = bird_x - head_x
        dy = bird_y - head_y
        if abs(dx) > abs(dy):
            return 'right' if dx > 0 else 'left'
        else:
            return 'down' if dy > 0 else 'up'

    # В методе shoot класса Snake (замените существующий)
    def shoot(self, fireballs):
        # Определяем клетки головы
        if self.width == 1:
            head_cells = [self.body[0]]
        else:
            head_cells = list(self.body[0])  # кортеж клеток для ширины 2 или 3

        # Красная змея: стреляет из каждой клетки головы
        if self.snake_type == 'red':
            color = (255, 69, 0)
            for (hx, hy) in head_cells:
                if self.direction in ('left', 'right'):
                    fireballs.append(Fireball(hx, hy - 1, 0, -1, color=color))
                    fireballs.append(Fireball(hx, hy + 1, 0, 1, color=color))
                else:
                    fireballs.append(Fireball(hx - 1, hy, -1, 0, color=color))
                    fireballs.append(Fireball(hx + 1, hy, 1, 0, color=color))
            return

        # Остальные стреляющие змеи (stripe_green, stripe_blue, white_red, rainbow_snake)
        hx, hy = head_cells[0]
        color = PURPLE_FIRE if self.snake_type in ('white_red', 'rainbow_snake') else (255, 69, 0)
        if self.direction in ('left', 'right'):
            fireballs.append(Fireball(hx, hy - 1, 0, -1, color=color))
            fireballs.append(Fireball(hx, hy + 1, 0, 1, color=color))
        else:
            fireballs.append(Fireball(hx - 1, hy, -1, 0, color=color))
            fireballs.append(Fireball(hx + 1, hy, 1, 0, color=color))

    def shoot_line(self, fireballs):
        if self.width == 1:
            head_x, head_y = self.body[0]
        else:
            head_x = self.body[0][0][0]
            head_y = self.body[0][0][1]
        color = PURPLE_FIRE
        if self.direction in ('left', 'right'):
            for dy in (-1, 0, 1):
                fireballs.append(Fireball(head_x, head_y + dy, 0, -1, speed=2, color=color))
                fireballs.append(Fireball(head_x, head_y + dy, 0, 1, speed=2, color=color))
        else:
            for dx in (-1, 0, 1):
                fireballs.append(Fireball(head_x + dx, head_y, -1, 0, speed=2, color=color))
                fireballs.append(Fireball(head_x + dx, head_y, 1, 0, speed=2, color=color))

    def create_invisible_gas(self, gas_clouds):
        # для бело-серой змеи: создаём невидимый газ радиусом 2-3 вокруг головы
        if self.width == 1:
            head_x, head_y = self.body[0]
        else:
            head_x = self.body[0][0][0]
            head_y = self.body[0][0][1]
        radius = random.randint(2, 3)
        gas_clouds.append(SlimeGasCloud(head_x, head_y, radius, 3, lethal=False, invisible=True))

    def move(self, bird_x=None, bird_y=None, fireballs=None, gas_clouds=None):
        if not self.body:
            return

        # Стрельба для красной и чёрной змей
        if self.snake_type in ('red') and fireballs is not None:
            if self.shoot_cooldown <= 0:
                self.shoot(fireballs)
                self.shoot_cooldown = self.shoot_delay
            else:
                self.shoot_cooldown -= 1

        # Стрельба для остальных стреляющих змей
        if self.snake_type in ['stripe_green', 'stripe_blue'] and fireballs is not None:
            if self.shoot_cooldown <= 0:
                self.shoot(fireballs)
                self.shoot_cooldown = self.shoot_delay
            else:
                self.shoot_cooldown -= 1
        elif self.snake_type == 'white_red' and fireballs is not None:
            if self.shoot_cooldown <= 0:
                self.shoot_line(fireballs)
                self.shoot_cooldown = self.shoot_delay
            else:
                self.shoot_cooldown -= 1

        # Газ для бело-серой змеи
        if self.snake_type == 'white_gray' and gas_clouds is not None:
            if self.gas_cooldown <= 0:
                self.create_invisible_gas(gas_clouds)
                self.gas_cooldown = 1   # каждый ход
            else:
                self.gas_cooldown -= 1

        if self.snake_type == 'rainbow_snake':
            if self.rush_cooldown <= 0:
                for _ in range(self.rush_distance):
                    self._move_one_step()
                self.rush_cooldown = self.rush_delay
            else:
                self.rush_cooldown -= 1
                steps = self.move_speed
                for _ in range(steps):
                    self._move_one_step()
            if self.turns_left > 0 and bird_x is not None:
                if random.random() < 0.3:
                    new_direction = self.calculate_direction_to_player(bird_x, bird_y)
                    opposite = {'up': 'down', 'down': 'up', 'left': 'right', 'right': 'left'}
                    if new_direction != opposite.get(self.direction, ''):
                        self.direction = new_direction
                        self.turns_left -= 1
            return

        if (self.snake_type in ['dark_green', 'dark_blue', 'white',
                                'white_purple', 'white_gray']) and self.turns_left > 0 and bird_x is not None:
            if random.random() < 0.4:
                new_direction = self.calculate_direction_to_player(bird_x, bird_y)
                opposite = {'up': 'down', 'down': 'up', 'left': 'right', 'right': 'left'}
                if new_direction != opposite.get(self.direction, ''):
                    self.direction = new_direction
                    self.turns_left -= 1

        if self.snake_type in ['swamp_green', 'pink_azure']:
            if self.charge == 0:
                self.charge = 1
                self.charge_timer = 0
                return
            elif self.charge == 1:
                self.charge_timer += 1
                if self.charge_timer >= 2:
                    self.charge = 2
                return
            elif self.charge == 2:
                steps = self.rush_distance
                for _ in range(steps):
                    self._move_one_step()
                self.charge = 0
                return

        steps = self.move_speed
        for _ in range(steps):
            self._move_one_step()

    def _move_one_step(self):
        if self.width == 1:
            head_x, head_y = self.body[0]
            if self.direction == 'up':
                new_head = (head_x, head_y - 1)
            elif self.direction == 'down':
                new_head = (head_x, head_y + 1)
            elif self.direction == 'left':
                new_head = (head_x - 1, head_y)
            else:
                new_head = (head_x + 1, head_y)
            self.body.appendleft(new_head)
            self.body.pop()
        else:
            head = self.body[0]
            new_head = []
            for seg in head:
                x, y = seg
                if self.direction == 'up':
                    new_head.append((x, y - 1))
                elif self.direction == 'down':
                    new_head.append((x, y + 1))
                elif self.direction == 'left':
                    new_head.append((x - 1, y))
                else:
                    new_head.append((x + 1, y))
            self.body.appendleft(tuple(new_head))
            self.body.pop()

    def draw(self, screen):
        self.rainbow_offset = (self.rainbow_offset + 1) % 360
        for i, segment in enumerate(self.body):
            if self.width == 1:
                x, y = segment
                if 0 <= x < GRID_SIZE and 0 <= y < GRID_SIZE:
                    rect = pygame.Rect(x * CELL_SIZE, y * CELL_SIZE, CELL_SIZE, CELL_SIZE)
                    self._draw_segment(screen, rect, i, x, y)
            else:
                is_head = (i == 0)
                for j, (x, y) in enumerate(segment):
                    if 0 <= x < GRID_SIZE and 0 <= y < GRID_SIZE:
                        rect = pygame.Rect(x * CELL_SIZE, y * CELL_SIZE, CELL_SIZE, CELL_SIZE)
                        self._draw_segment(screen, rect, i, x, y, is_head, j)

    def _draw_segment(self, screen, rect, i, x, y, is_head=False, part=0):
        if self.snake_type == 'rainbow_snake':
            hue = (self.rainbow_offset + i * 10) % 360
            color = pygame.Color(0)
            color.hsva = (hue, 100, 100)
            head_color = body_color = color
        else:
            if self.snake_type == 'green':
                head_color, body_color = DARK_GREEN, GREEN
            elif self.snake_type == 'dark_green':
                head_color, body_color = DARK_GREEN_PURPLE, DARK_GREEN_PURPLE
            elif self.snake_type == 'bright_green':
                head_color, body_color = BRIGHT_GREEN, BRIGHT_GREEN
            elif self.snake_type == 'blue':
                head_color, body_color = DARK_BLUE, BLUE
            elif self.snake_type == 'dark_blue':
                head_color, body_color = DARK_BLUE_PURPLE, DARK_BLUE_PURPLE
            elif self.snake_type == 'light_blue':
                head_color, body_color = LIGHT_BLUE, LIGHT_BLUE
            elif self.snake_type == 'red':
                head_color, body_color = DARK_RED_SNAKE, RED_SNAKE
            elif self.snake_type == 'black':
                head_color, body_color = BLACK_SNAKE, DARK_GRAY_BODY
            elif self.snake_type == 'stripe_green':
                head_color, body_color = DARK_GREEN, GREEN
            elif self.snake_type == 'stripe_blue':
                head_color, body_color = DARK_BLUE, BLUE
            elif self.snake_type == 'swamp_green':
                head_color, body_color = SWAMP_GREEN, (60, 80, 30)
            elif self.snake_type == 'pink_azure':
                head_color, body_color = PINK_AZURE, (200, 80, 140)
            elif self.snake_type == 'white':
                head_color, body_color = (200, 200, 200), WHITE_SNAKE
            elif self.snake_type == 'white_purple':
                head_color, body_color = (180, 130, 230), WHITE_SNAKE
            elif self.snake_type == 'white_red':
                head_color, body_color = (255, 150, 150), WHITE_SNAKE
            elif self.snake_type == 'white_gray':
                head_color, body_color = (160, 160, 160), (200, 200, 200)
            else:
                head_color, body_color = BLACK_SNAKE, DARK_GRAY_BODY

        if i == 0 and (self.width == 1 or is_head):
            pygame.draw.rect(screen, head_color, rect)
            eye_size = CELL_SIZE // 8
            # Глаза для ширины 2 и 3: симметричные
            if self.width == 1:
                eye_offset = CELL_SIZE // 4
                pygame.draw.circle(screen, WHITE, (x * CELL_SIZE + eye_offset, y * CELL_SIZE + eye_offset), eye_size)
                pygame.draw.circle(screen, WHITE, (x * CELL_SIZE + CELL_SIZE - eye_offset, y * CELL_SIZE + eye_offset),
                                   eye_size)
                pygame.draw.circle(screen, BLACK, (x * CELL_SIZE + eye_offset, y * CELL_SIZE + eye_offset),
                                   eye_size // 2)
                pygame.draw.circle(screen, BLACK, (x * CELL_SIZE + CELL_SIZE - eye_offset, y * CELL_SIZE + eye_offset),
                                   eye_size // 2)
            elif self.width == 2:
                if part == 0:
                    eye_offset = CELL_SIZE // 4
                    pygame.draw.circle(screen, WHITE, (x * CELL_SIZE + eye_offset, y * CELL_SIZE + eye_offset),
                                       eye_size)
                    pygame.draw.circle(screen, BLACK, (x * CELL_SIZE + eye_offset, y * CELL_SIZE + eye_offset),
                                       eye_size // 2)
                else:
                    eye_offset = CELL_SIZE // 4
                    pygame.draw.circle(screen, WHITE,
                                       (x * CELL_SIZE + CELL_SIZE - eye_offset, y * CELL_SIZE + eye_offset), eye_size)
                    pygame.draw.circle(screen, BLACK,
                                       (x * CELL_SIZE + CELL_SIZE - eye_offset, y * CELL_SIZE + eye_offset),
                                       eye_size // 2)
            else:  # width == 3
                if part == 0:
                    eye_offset = CELL_SIZE // 4
                    pygame.draw.circle(screen, RED_EYE, (x * CELL_SIZE + eye_offset, y * CELL_SIZE + eye_offset),
                                       eye_size)
                elif part == 2:
                    eye_offset = CELL_SIZE // 4
                    pygame.draw.circle(screen, RED_EYE,
                                       (x * CELL_SIZE + CELL_SIZE - eye_offset, y * CELL_SIZE + eye_offset), eye_size)
        else:
            pygame.draw.rect(screen, body_color, rect)
            if self.snake_type == 'dark_green':
                for _ in range(8):
                    dot_x = x * CELL_SIZE + random.randint(5, CELL_SIZE - 5)
                    dot_y = y * CELL_SIZE + random.randint(5, CELL_SIZE - 5)
                    pygame.draw.circle(screen, PURPLE_SPOT, (dot_x, dot_y), random.randint(1, 2))
            elif self.snake_type == 'dark_blue':
                for _ in range(8):
                    dot_x = x * CELL_SIZE + random.randint(5, CELL_SIZE - 5)
                    dot_y = y * CELL_SIZE + random.randint(5, CELL_SIZE - 5)
                    pygame.draw.circle(screen, PURPLE_DOT, (dot_x, dot_y), random.randint(1, 2))
            elif self.snake_type == 'bright_green':
                pygame.draw.rect(screen, YELLOW_STRIPE,
                                 (x * CELL_SIZE + 10, y * CELL_SIZE + 10, CELL_SIZE - 20, CELL_SIZE - 20), 2)
            elif self.snake_type == 'light_blue':
                pygame.draw.rect(screen, CYAN_STRIPE,
                                 (x * CELL_SIZE + 10, y * CELL_SIZE + 10, CELL_SIZE - 20, CELL_SIZE - 20), 2)
            elif self.snake_type == 'red':
                pygame.draw.rect(screen, DARK_RED_SNAKE,
                                 (x * CELL_SIZE + 15, y * CELL_SIZE + 15, CELL_SIZE - 30, CELL_SIZE - 30))
            elif self.snake_type == 'stripe_green':
                pygame.draw.rect(screen, ORANGE_STRIPE,
                                 (x * CELL_SIZE + 5, y * CELL_SIZE + 5, CELL_SIZE - 10, CELL_SIZE - 10), 2)
            elif self.snake_type == 'stripe_blue':
                pygame.draw.rect(screen, BRIGHT_ORANGE_STRIPE,
                                 (x * CELL_SIZE + 5, y * CELL_SIZE + 5, CELL_SIZE - 10, CELL_SIZE - 10), 2)
            elif self.snake_type == 'white_purple':
                pygame.draw.rect(screen, (150, 100, 200),
                                 (x * CELL_SIZE + 5, y * CELL_SIZE + 5, CELL_SIZE - 10, CELL_SIZE - 10), 2)
            elif self.snake_type == 'white_red':
                for _ in range(5):
                    dot_x = x * CELL_SIZE + random.randint(5, CELL_SIZE - 5)
                    dot_y = y * CELL_SIZE + random.randint(5, CELL_SIZE - 5)
                    pygame.draw.circle(screen, RED_SNAKE, (dot_x, dot_y), random.randint(2, 4))
            elif self.snake_type == 'rainbow_snake':
                pygame.draw.rect(screen, WHITE, rect, 2)
            elif self.snake_type == 'white_gray':
                pygame.draw.rect(screen, (100, 100, 100), rect, 2)

        pygame.draw.rect(screen, BLACK, rect, 2)

    def get_all_positions(self):
        positions = set()
        if self.width == 1:
            for x, y in self.body:
                positions.add((x, y))
        else:
            for segment in self.body:
                for x, y in segment:
                    positions.add((x, y))
        return positions

    def is_completely_off_grid(self):
        for x, y in self.get_all_positions():
            if 0 <= x < GRID_SIZE and 0 <= y < GRID_SIZE:
                return False
        return True

def create_snake_at_edge(snake_type='green'):
    if snake_type == 'green':
        length = random.choice([4, 5, 6])
        width = 1
    elif snake_type == 'dark_green':
        length = random.choice([4, 5, 6, 7, 8])
        width = 1
    elif snake_type == 'bright_green':
        length = random.choice([3, 4, 5])
        width = 1
    elif snake_type == 'blue':
        length = random.choice([5, 6, 7, 8, 9, 10])
        width = 1
    elif snake_type == 'dark_blue':
        length = random.choice([4, 5, 6, 7, 8, 9])
        width = 1
    elif snake_type == 'light_blue':
        length = random.choice([3, 4])
        width = 1
    elif snake_type == 'red':
        length = random.choice([14, 15, 16])
        width = 2
    elif snake_type == 'black':
        length = 30
        width = 3
    elif snake_type == 'stripe_green':
        length = random.choice([2, 3])
        width = 1
    elif snake_type == 'stripe_blue':
        length = random.choice([2, 3, 4])
        width = 1
    elif snake_type == 'swamp_green':
        length = random.choice([6, 7])
        width = 1
    elif snake_type == 'pink_azure':
        length = random.choice([7, 8])
        width = 1
    elif snake_type == 'white':
        length = random.choice([7, 8, 9, 10, 11, 12])
        width = 1
    elif snake_type == 'white_purple':
        length = random.choice([8, 9, 10, 11, 12, 13])
        width = 1
    elif snake_type == 'white_red':
        length = random.choice([4, 5])
        width = 1
    elif snake_type == 'rainbow_snake':
        length = 17
        width = 2
    elif snake_type == 'white_gray':
        length = random.choice([5, 6, 7])
        width = 1
    else:
        length = 4
        width = 1

    side = random.choice(['top', 'bottom', 'left', 'right'])
    if side == 'top':
        x = random.randint(0, GRID_SIZE - width)
        y = 0
        direction = 'down'
    elif side == 'bottom':
        x = random.randint(0, GRID_SIZE - width)
        y = GRID_SIZE - 1
        direction = 'up'
    elif side == 'left':
        x = 0
        y = random.randint(0, GRID_SIZE - width)
        direction = 'right'
    else:
        x = GRID_SIZE - 1
        y = random.randint(0, GRID_SIZE - width)
        direction = 'left'

    return Snake(x, y, length, direction, snake_type, width)

def check_collision(bird_x, bird_y, snakes, fireballs, invisible_clouds=None):
    bird_pos = (bird_x, bird_y)
    for snake in snakes:
        if bird_pos in snake.get_all_positions():
            return True
    for fb in fireballs:
        if fb.active and fb.get_pos() == bird_pos:
            return True
    if invisible_clouds:
        for ic in invisible_clouds:
            # Только смертельные облака убивают, невидимые – нет
            if ic.lethal and bird_pos in ic.get_affected_cells():
                return True
    return False

def draw_grid():
    for row in range(GRID_SIZE):
        for col in range(GRID_SIZE):
            rect = pygame.Rect(col * CELL_SIZE, row * CELL_SIZE, CELL_SIZE, CELL_SIZE)
            if (row + col) % 2 == 0:
                pygame.draw.rect(screen, GRAY, rect)
            else:
                pygame.draw.rect(screen, LIGHT_GRAY, rect)
            pygame.draw.rect(screen, BLACK, rect, 1)

def is_cell_visible(cx, cy, bird_x, bird_y, fog=False):
    """Если fog=True, клетка видна только в радиусе FOG_RADIUS от птички."""
    if not fog:
        return True
    return abs(cx - bird_x) + abs(cy - bird_y) <= FOG_RADIUS

# ---------------------- ПАУКИ ----------------------
SPIDER_INFO_ORDERED = [
    "light_gray", "brown_gray", "dark_gray_red_cross", "dark_gray_green_circle",
    "dark_red", "big_dark_gray", "big_dark_gray_green_circle", "black_spider", "white_purple_circle",
    "rainbow_spider"
]

SPIDER_INFO = {
    "light_gray": {"size": 1, "fall_time": 3, "sit_time": 5, "color": SPIDER_LIGHT_GRAY, "special": "Нет",
                   "spawn_condition": "Всегда"},
    "brown_gray": {"size": 1, "fall_time": 3, "sit_time": 30, "color": SPIDER_BROWN_GRAY, "special": "Нет",
                   "spawn_condition": "Всегда"},
    "dark_gray_red_cross": {"size": 1, "fall_time": 3, "sit_time": 10, "color": SPIDER_DARK_GRAY,
                            "special": "Стрельба шарами (при падении и каждые 2 хода)", "cross": True,
                            "spawn_condition": "Всегда"},
    "dark_gray_green_circle": {"size": 1, "fall_time": 3, "sit_time": 5, "color": SPIDER_DARK_GRAY,
                               "special": "Облако газа на 4-й ход", "green_circle": True, "spawn_condition": "Всегда"},
    "dark_red": {"size": 2, "fall_time": 5, "sit_time": 20, "color": SPIDER_DARK_RED,
                 "special": "Стена огня 2x1 каждые 3 хода", "spawn_condition": "Редко, после убийств"},
    "big_dark_gray": {"size": 2, "fall_time": 5, "sit_time": 10, "color": SPIDER_BIG_DARK_GRAY, "special": "Нет",
                      "spawn_condition": "После 2 dark_red"},
    "big_dark_gray_green_circle": {"size": 2, "fall_time": 5, "sit_time": 10, "color": SPIDER_BIG_DARK_GRAY,
                                   "special": "Облако газа (радиус 6) на 8-й ход",
                                   "spawn_condition": "После 4 dark_red"},
    "black_spider": {"size": 3, "fall_time": 7, "sit_time": 15, "color": SPIDER_BLACK,
                     "special": "Стреляет линиями из двух шаров во все 8 направлений",
                     "spawn_condition": "После 5 dark_red"},
    "white_purple_circle": {"size": 1, "fall_time": 3, "sit_time": 15, "color": SPIDER_WHITE_PURPLE,
                            "special": "Линия из 2 шаров (скор.2) каждые 2 хода", "spawn_condition": "Всегда"},
    "rainbow_spider": {"size": 1, "fall_time": 3, "sit_time": 15, "color": (255, 0, 255),
                       "special": "Стрельба в 8 направлений разными снарядами",
                       "spawn_condition": "Очень редко, всегда", "rainbow": True}
}

SPIDER_CATEGORIES = {
    "Обычные": ["light_gray", "brown_gray", "dark_gray_red_cross", "dark_gray_green_circle", "white_purple_circle"],
    "Большие": ["dark_red", "big_dark_gray", "big_dark_gray_green_circle", "black_spider"],
    "Радужные": ["rainbow_spider"]
}
TAB_NAMES_SPIDERS = ["Обычные", "Большие", "Радужные"]

class SpiderFireball:
    def __init__(self, x, y, dx, dy, speed=1, length=1, width=1, color=(255, 69, 0)):
        self.x = x
        self.y = y
        self.dx = dx
        self.dy = dy
        self.speed = speed
        self.length = length
        self.width = width
        self.active = True
        self.color = color
        self.move_timer = 0               # <-- добавить

    def move(self):
        if self.speed < 1.0:
            self.move_timer += 1
            if self.move_timer >= int(1 / self.speed):
                self.move_timer = 0
                self._move_step()
        else:
            for _ in range(int(self.speed)):
                self._move_step()
                if not self.active:
                    break

    def _move_step(self):
        self.x += self.dx
        self.y += self.dy
        if not (0 <= self.x < GRID_SIZE and 0 <= self.y < GRID_SIZE):
            self.active = False

    # ... остальные методы без изменений
    def draw(self, screen):
        if not self.active:
            return
        if self.length == 1 and self.width == 1:
            rect = pygame.Rect(self.x * CELL_SIZE, self.y * CELL_SIZE, CELL_SIZE, CELL_SIZE)
            center = rect.center
            radius = CELL_SIZE // 3
            draw_droplet(screen, self.color, center, radius, (self.dx, self.dy), border_color=BLACK, border_width=2)
            # Удаляем или комментируем старую точку
            # pygame.draw.circle(screen, WHITE, center, CELL_SIZE // 5)
        else:
            # ... (стены и линии остаются без изменений)
            if self.dx != 0:
                width_px = CELL_SIZE * self.width
                height_px = CELL_SIZE * self.length
                x = self.x * CELL_SIZE - (self.width // 2) * CELL_SIZE
                y = self.y * CELL_SIZE
            else:
                width_px = CELL_SIZE * self.length
                height_px = CELL_SIZE * self.width
                x = self.x * CELL_SIZE
                y = self.y * CELL_SIZE - (self.width // 2) * CELL_SIZE
            rect = pygame.Rect(x, y, width_px, height_px)
            pygame.draw.rect(screen, self.color, rect)
            pygame.draw.rect(screen, BLACK, rect, 3)

    def get_positions(self):
        pos = set()
        if self.length == 1 and self.width == 1:
            pos.add((self.x, self.y))
        else:
            if self.dx != 0:
                for w in range(self.width):
                    for l in range(self.length):
                        pos.add((self.x + l * self.dx, self.y + w - self.width // 2))
            else:
                for w in range(self.width):
                    for l in range(self.length):
                        pos.add((self.x + w - self.width // 2, self.y + l * self.dy))
        return pos

class GasCloud:
    def __init__(self, x, y, radius, duration):
        self.x = x
        self.y = y
        self.radius = radius
        self.duration = duration
        self.active = True

    def update(self):
        self.duration -= 1
        if self.duration <= 0:
            self.active = False

    def draw(self, screen):
        if not self.active:
            return
        cells = self.get_affected_cells()
        for cx, cy in cells:
            rect = pygame.Rect(cx * CELL_SIZE, cy * CELL_SIZE, CELL_SIZE, CELL_SIZE)
            alpha = 100 + (self.duration * 20)
            alpha = min(180, max(80, alpha))
            cloud_surf = pygame.Surface((CELL_SIZE, CELL_SIZE), pygame.SRCALPHA)
            cloud_surf.fill((100, 200, 100, alpha))
            pygame.draw.ellipse(cloud_surf, (120, 220, 120, alpha), (5, 5, CELL_SIZE - 10, CELL_SIZE - 10))
            screen.blit(cloud_surf, rect)

    def get_affected_cells(self):
        cells = set()
        for dx in range(-self.radius, self.radius + 1):
            for dy in range(-self.radius, self.radius + 1):
                if abs(dx) + abs(dy) <= self.radius:
                    nx, ny = self.x + dx, self.y + dy
                    if 0 <= nx < GRID_SIZE and 0 <= ny < GRID_SIZE:
                        cells.add((nx, ny))
        return cells

class Shadow:
    def __init__(self, x, y, size, fall_time, spider_type):
        self.x = x
        self.y = y
        self.size = size
        self.remaining = fall_time
        self.spider_type = spider_type

    def update(self):
        self.remaining -= 1
        return self.remaining <= 0

    def draw(self, screen):
        alpha = min(150, 50 + (self.remaining * 20))
        surf = pygame.Surface((CELL_SIZE * self.size, CELL_SIZE * self.size), pygame.SRCALPHA)
        surf.fill((0, 0, 0, alpha))
        pygame.draw.rect(surf, (200, 200, 200, alpha), (0, 0, CELL_SIZE * self.size, CELL_SIZE * self.size), 2)
        screen.blit(surf, (self.x * CELL_SIZE, self.y * CELL_SIZE))

class Spider:
    def __init__(self, x, y, spider_type):
        self.x = x
        self.y = y
        self.spider_type = spider_type
        info = SPIDER_INFO[spider_type]
        self.size = info["size"]
        self.sit_time = info["sit_time"]
        self.timer = 0
        self.active = True
        self.shoot_cooldown = 0
        self.gas_triggered = False
        self.gas_radius = 3 if spider_type == "dark_gray_green_circle" else 6 if spider_type == "big_dark_gray_green_circle" else 0
        self.gas_delay = 4 if spider_type == "dark_gray_green_circle" else 8 if spider_type == "big_dark_gray_green_circle" else None
        self.rainbow_offset = 0

    def update(self, fireballs, gas_clouds, bird_x, bird_y):
        self.timer += 1
        self.rainbow_offset = (self.rainbow_offset + 5) % 360
        if self.spider_type == "dark_gray_red_cross":
            if self.timer % 2 == 0:
                direction = random.choice([(1, 0), (-1, 0), (0, 1), (0, -1)])
                dx, dy = direction
                cx, cy = self.x + self.size // 2, self.y + self.size // 2
                fireballs.append(SpiderFireball(cx + dx, cy + dy, dx, dy, speed=1))
        elif self.spider_type == "dark_red":
            if self.timer % 3 == 0 and self.timer > 0:
                self.shoot_wall(fireballs, length=2, speed=1, color=(255, 69, 0))
        elif self.spider_type == "black_spider":
            # Новая стрельба: линии из двух шаров во все 8 направлений
            if self.timer % 3 == 0 and self.timer > 0:
                self.shoot_eight_directions(fireballs, speed=2, color=PURPLE_FIRE)
        elif self.spider_type == "white_purple_circle":
            if self.timer % 2 == 0:
                self.shoot_line_of_two_balls(fireballs, speed=2, color=PURPLE_FIRE)
        elif self.spider_type == "rainbow_spider":
            if self.timer % 2 == 0:
                self.shoot_rainbow(fireballs)

        if self.gas_delay is not None and not self.gas_triggered and self.timer >= self.gas_delay:
            self.gas_triggered = True
            gas_clouds.append(GasCloud(self.x + self.size // 2, self.y + self.size // 2, self.gas_radius,
                                       duration=2 if self.size == 1 else 3))
            gas_clouds.append(GasCloud(self.x + self.size // 2 - 1, self.y + self.size // 2, self.gas_radius,
                                       duration=0 if self.size == 1 else 3))
            gas_clouds.append(GasCloud(self.x + self.size // 2, self.y + self.size // 2 - 1, self.gas_radius,
                                       duration=0 if self.size == 1 else 3))
            gas_clouds.append(GasCloud(self.x + self.size // 2 - 1, self.y + self.size // 2 - 1, self.gas_radius,
                                       duration=0 if self.size == 1 else 3))
        if self.timer >= self.sit_time:
            self.active = False

    def shoot_wall(self, fireballs, length, speed, color):
        direction = random.choice([(1, 0), (-1, 0), (0, 1), (0, -1)])
        dx, dy = direction
        if dx != 0:
            for i in range(self.size):
                start_x = self.x + self.size // 2
                start_y = self.y + i
                fireballs.append(SpiderFireball(start_x, start_y, dx, dy, speed=speed, length=1, color=color))
        else:
            for i in range(self.size):
                start_x = self.x + i
                start_y = self.y + self.size // 2
                fireballs.append(SpiderFireball(start_x, start_y, dx, dy, speed=speed, length=1, color=color))

    def shoot_eight_directions(self, fireballs, speed, color):
        # все 8 направлений
        directions = [(1,0), (-1,0), (0,1), (0,-1), (1,1), (1,-1), (-1,1), (-1,-1)]
        cx = self.x + self.size // 2
        cy = self.y + self.size // 2
        for dx, dy in directions:
            # первый шар
            fireballs.append(SpiderFireball(cx + dx, cy + dy, dx, dy, speed=speed, length=1, color=color))
            # второй шар на следующей клетке
            fireballs.append(SpiderFireball(cx + 2*dx, cy + 2*dy, dx, dy, speed=speed, length=1, color=color))

    def shoot_grid_from_center(self, fireballs, width, length, speed, color):
        direction = random.choice([(1, 0), (-1, 0), (0, 1), (0, -1)])
        dx, dy = direction
        center_x = self.x + self.size / 2.0
        center_y = self.y + self.size / 2.0
        if width % 2 == 0:
            perp_offsets = [i - width / 2.0 + 0.5 for i in range(width)]
        else:
            perp_offsets = [i - width // 2 for i in range(width)]
        if length % 2 == 0:
            along_offsets = [i - length / 2.0 + 0.5 for i in range(length)]
        else:
            along_offsets = [i - length // 2 for i in range(length)]
        for w in range(width):
            for l in range(length):
                if dx != 0:
                    start_x = center_x + along_offsets[l] * dx
                    start_y = center_y + perp_offsets[w]
                else:
                    start_x = center_x + perp_offsets[w]
                    start_y = center_y + along_offsets[l] * dy
                ball_x = int(round(start_x))
                ball_y = int(round(start_y))
                if 0 <= ball_x < GRID_SIZE and 0 <= ball_y < GRID_SIZE:
                    fireballs.append(SpiderFireball(ball_x, ball_y, dx, dy, speed=speed, length=1, color=color))

    def shoot_line_of_two_balls(self, fireballs, speed, color):
        direction = random.choice([(1, 0), (-1, 0), (0, 1), (0, -1)])
        dx, dy = direction
        cx = self.x + self.size // 2
        cy = self.y + self.size // 2
        fireballs.append(SpiderFireball(cx, cy, dx, dy, speed=speed, length=1, color=color))
        fireballs.append(SpiderFireball(cx + dx, cy + dy, dx, dy, speed=speed, length=1, color=color))

    def shoot_rainbow(self, fireballs):
        directions = [(1, 0), (-1, 0), (0, 1), (0, -1), (1, 1), (1, -1), (-1, 1), (-1, -1)]
        types = [
            {"speed": 1, "color": (255, 0, 0)},
            {"speed": 2, "color": PURPLE_FIRE},
            {"speed": 0.5, "color": (0, 255, 0)}
        ]
        cx = self.x + self.size // 2
        cy = self.y + self.size // 2
        for dx, dy in directions:
            t = random.choice(types)
            fireballs.append(SpiderFireball(cx, cy, dx, dy, speed=t["speed"], length=1, color=t["color"]))

    def draw(self, screen):
        size_px = CELL_SIZE * self.size
        x_px = self.x * CELL_SIZE
        y_px = self.y * CELL_SIZE
        if self.spider_type == "rainbow_spider":
            hue = self.rainbow_offset % 360
            color = pygame.Color(0)
            color.hsva = (hue, 100, 100)
        else:
            color = SPIDER_INFO[self.spider_type]["color"]
        for i in range(self.size):
            for j in range(self.size):
                sub_rect = pygame.Rect(x_px + i * CELL_SIZE, y_px + j * CELL_SIZE, CELL_SIZE, CELL_SIZE)
                if self.spider_type == "rainbow_spider":
                    hue2 = (hue + (i + j) * 20) % 360
                    c2 = pygame.Color(0)
                    c2.hsva = (hue2, 100, 100)
                    pygame.draw.rect(screen, c2, sub_rect)
                else:
                    pygame.draw.rect(screen, color, sub_rect)
                pygame.draw.rect(screen, BLACK, sub_rect, 1)
        outline_color = (255, 255, 200) if self.spider_type != "black_spider" else (150, 150, 150)
        pygame.draw.rect(screen, outline_color, (x_px, y_px, size_px, size_px), 2)

        if self.size == 1:
            cx = x_px + CELL_SIZE // 2
            cy = y_px + CELL_SIZE // 2
            leg_color = (0, 0, 0)
            offsets = [(-1, -1), (1, -1), (-1, 1), (1, 1), (-2, 0), (2, 0), (0, -2), (0, 2)]
            for ox, oy in offsets:
                ex = cx + ox * CELL_SIZE // 3
                ey = cy + oy * CELL_SIZE // 3
                pygame.draw.line(screen, leg_color, (cx, cy), (ex, ey), max(2, CELL_SIZE // 10))
            eye_radius = max(2, CELL_SIZE // 8)
            pygame.draw.circle(screen, WHITE, (cx - CELL_SIZE // 5, cy - CELL_SIZE // 5), eye_radius)
            pygame.draw.circle(screen, WHITE, (cx + CELL_SIZE // 5, cy - CELL_SIZE // 5), eye_radius)
            pygame.draw.circle(screen, BLACK, (cx - CELL_SIZE // 5, cy - CELL_SIZE // 5), eye_radius // 2)
            pygame.draw.circle(screen, BLACK, (cx + CELL_SIZE // 5, cy - CELL_SIZE // 5), eye_radius // 2)
            pygame.draw.line(screen, (0, 0, 0), (cx - 5, cy + 2), (cx - 10, cy + 8), 2)
            pygame.draw.line(screen, (0, 0, 0), (cx + 5, cy + 2), (cx + 10, cy + 8), 2)
        elif self.size == 2:
            for i in range(2):
                for j in range(2):
                    sub_rect = pygame.Rect(x_px + i * CELL_SIZE, y_px + j * CELL_SIZE, CELL_SIZE, CELL_SIZE)
                    pygame.draw.rect(screen, color, sub_rect)
                    pygame.draw.rect(screen, outline_color, sub_rect, 1)
            eye_radius = CELL_SIZE // 5
            left_eye_center = (x_px + CELL_SIZE // 2, y_px + CELL_SIZE // 2)
            right_eye_center = (x_px + 3 * CELL_SIZE // 2, y_px + CELL_SIZE // 2)
            pygame.draw.circle(screen, WHITE, left_eye_center, eye_radius)
            pygame.draw.circle(screen, WHITE, right_eye_center, eye_radius)
            pygame.draw.circle(screen, BLACK, left_eye_center, eye_radius // 2)
            pygame.draw.circle(screen, BLACK, right_eye_center, eye_radius // 2)
        else:
            for i in range(3):
                for j in range(3):
                    sub_rect = pygame.Rect(x_px + i * CELL_SIZE, y_px + j * CELL_SIZE, CELL_SIZE, CELL_SIZE)
                    pygame.draw.rect(screen, color, sub_rect)
                    pygame.draw.rect(screen, outline_color, sub_rect, 1)
            eye_radius = CELL_SIZE // 4
            eye1 = (x_px + CELL_SIZE // 2, y_px + CELL_SIZE // 2)
            eye2 = (x_px + 5 * CELL_SIZE // 2, y_px + CELL_SIZE // 2)
            pygame.draw.circle(screen, RED_EYE, eye1, eye_radius)
            pygame.draw.circle(screen, RED_EYE, eye2, eye_radius)
            pygame.draw.circle(screen, BLACK, eye1, eye_radius // 2)
            pygame.draw.circle(screen, BLACK, eye2, eye_radius // 2)

        if self.spider_type == "dark_gray_red_cross":
            cx = x_px + size_px // 2
            cy = y_px + size_px // 2
            pygame.draw.line(screen, SPIDER_RED_CROSS, (cx - size_px // 3, cy), (cx + size_px // 3, cy),
                             max(2, size_px // 10))
            pygame.draw.line(screen, SPIDER_RED_CROSS, (cx, cy - size_px // 3), (cx, cy + size_px // 3),
                             max(2, size_px // 10))
        elif self.spider_type in ("dark_gray_green_circle", "big_dark_gray_green_circle"):
            cx = x_px + size_px // 2
            cy = y_px + size_px // 2
            pygame.draw.circle(screen, SPIDER_GREEN_CIRCLE, (cx, cy), size_px // 3)
            pygame.draw.circle(screen, BLACK, (cx, cy), size_px // 3, 1)
        elif self.spider_type == "white_purple_circle":
            cx = x_px + size_px // 2
            cy = y_px + size_px // 2
            pygame.draw.circle(screen, (128, 0, 128), (cx, cy), size_px // 3)
            pygame.draw.circle(screen, BLACK, (cx, cy), size_px // 3, 1)

    def get_positions(self):
        pos = set()
        for i in range(self.size):
            for j in range(self.size):
                pos.add((self.x + i, self.y + j))
        return pos

def check_collision_spider(bird_x, bird_y, spiders, fireballs, gas_clouds):
    bird_pos = (bird_x, bird_y)
    for spider in spiders:
        if bird_pos in spider.get_positions():
            return True
    for fb in fireballs:
        if bird_pos in fb.get_positions():
            return True
    for gc in gas_clouds:
        if bird_pos in gc.get_affected_cells():
            return True
    return False

# ---------------------- СЛИЗНИ ----------------------
SLIME_INFO_ORDERED = [
    "green_slime_jump1", "green_slime_jump2", "dark_green_slime", "red_slime", "purple_blue_slime",
    "black_slime", "dark_gray_slime", "light_gray_slime", "white_slime", "rainbow_slime",
    "bright_orange_slime", "yellow_slime"
]

SLIME_INFO = {
    "green_slime_jump1": {"jump_length": 2, "jump_freq": 1, "max_jumps": (4, 6), "color": (100, 255, 100, 180),
                          "death_effect": "balls", "death_balls_speed": 0.5,
                          "special": "После смерти выпускает 4 шара (скорость 0.5)"},
    "green_slime_jump2": {"jump_length": 3, "jump_freq": 1, "max_jumps": (3, 5), "color": (120, 220, 120, 180),
                          "death_effect": "invis_gas", "gas_radius": 4, "gas_duration": 5,
                          "special": "После смерти облако невидимости (радиус 4, 5 ходов)"},
    "dark_green_slime": {"jump_length": 4, "jump_freq": 2, "max_jumps": (2, 4), "color": (0, 150, 0, 180),
                         "death_effect": "gas", "gas_radius": 3, "gas_duration": 2,
                         "special": "После смерти ядовитое облако (радиус 3, 2 хода)"},
    "red_slime": {"jump_length": 2, "jump_freq": 1, "max_jumps": (5, 7), "color": (255, 100, 100, 180),
                  "death_effect": "shoot", "shoot_speed": 1,
                  "special": "Каждый ход стреляет 4 шара (скорость 1), при смерти тоже стреляет"},
    "purple_blue_slime": {"jump_length": 3, "jump_freq": 1, "max_jumps": (8, 9), "color": (100, 100, 255, 180),
                          "death_effect": "invis_gas", "gas_radius": 1, "gas_duration": 5,
                          "special": "Случайное направление прыжка, невидимый туман R1 после смерти"},
    "black_slime": {"jump_length": 2, "jump_freq": 1, "max_jumps": (3, 5), "color": (30, 30, 30, 180),
                    "death_effect": "spawn_dark_gray", "special": "При смерти создаёт темно-серых слизней вокруг"},
    "dark_gray_slime": {"jump_length": 2, "jump_freq": 1, "max_jumps": (2, 4), "color": (80, 80, 80, 180),
                        "death_effect": "spawn_light_gray", "special": "При смерти создаёт светло-серых слизней"},
    "light_gray_slime": {"jump_length": 2, "jump_freq": 1, "max_jumps": (1, 3), "color": (150, 150, 150, 180),
                         "death_effect": "spawn_white", "special": "При смерти создаёт белых слизней", "harmless": True},
    "white_slime": {"jump_length": 2, "jump_freq": 1, "max_jumps": (1, 2), "color": (230, 230, 230, 180),
                    "death_effect": "invis_gas", "gas_radius": 1, "gas_duration": 5,
                    "special": "После смерти невидимый газ (радиус 1, 5 ходов)", "harmless": True},
    "rainbow_slime": {"jump_length": (2, 5), "jump_freq": 1, "max_jumps": None, "color": (255, 0, 255, 180),
                      "death_effect": None, "special": "Прыжки 2-5, стрельба 4 снарядами разных типов, облака",
                      "rainbow": True},
    "bright_orange_slime": {"jump_length": 2, "jump_freq": 1, "max_jumps": (4, 6), "color": (255, 165, 0, 180),
                            "death_effect": "lava", "lava_radius": 3, "lava_duration": 10,
                            "special": "Прыгает через 2 клетки, оставляет лаву на клетке приземления. После смерти лава в радиусе 3 (10 ходов)"},
    "yellow_slime": {"jump_length": 2, "jump_freq": 1, "max_jumps": (3, 7), "color": (255, 255, 0, 180),
                     "death_effect": "spawn_two", "special": "При смерти спавнит двух слизней (серо-зелёный или оранжевый)"}
}

SLIME_CATEGORIES = {
    "Обычные": ["green_slime_jump1", "green_slime_jump2", "dark_green_slime", "red_slime", "purple_blue_slime"],
    "Чёрные слизни": ["black_slime", "dark_gray_slime", "light_gray_slime", "white_slime"],
    "РЇСЂРєРёРµ": ["bright_orange_slime", "yellow_slime"],
    "Радужные": ["rainbow_slime"]
}
TAB_NAMES_SLIMES = ["Обычные", "Чёрные слизни", "Яркие", "Радужные"]


class SlimeBall:
    def __init__(self, x, y, dx, dy, speed=1.0, color=(100, 255, 100, 200)):
        self.x = x
        self.y = y
        self.dx = dx
        self.dy = dy
        self.speed = speed
        self.move_timer = 0
        self.active = True
        self.color = color

    def update(self):
        if self.speed < 1.0:
            self.move_timer += 1
            if self.move_timer >= int(1 / self.speed):
                self.move_timer = 0
                self._move()
        else:
            for _ in range(int(self.speed)):
                self._move()
                if not self.active:
                    break

    def _move(self):
        self.x += self.dx
        self.y += self.dy
        if not (0 <= self.x < GRID_SIZE and 0 <= self.y < GRID_SIZE):
            self.active = False

    def draw(self, screen, invisible_clouds=None):
        if not self.active:
            return
        if invisible_clouds:
            for cloud in invisible_clouds:
                if (self.x, self.y) in cloud.get_affected_cells():
                    return
        rect = pygame.Rect(self.x * CELL_SIZE, self.y * CELL_SIZE, CELL_SIZE, CELL_SIZE)
        ball_surf = pygame.Surface((CELL_SIZE, CELL_SIZE), pygame.SRCALPHA)
        center = (CELL_SIZE // 2, CELL_SIZE // 2)
        radius = CELL_SIZE // 3
        # Рисуем каплю на временной поверхности
        draw_droplet(ball_surf, self.color, center, radius, (self.dx, self.dy), border_color=BLACK, border_width=1)
        screen.blit(ball_surf, rect)

    def get_pos(self):
        return (self.x, self.y)

class SlimeGasCloud:
    def __init__(self, x, y, radius, duration, lethal=True, invisible=False):
        self.x = x
        self.y = y
        self.radius = radius
        self.duration = duration
        self.active = True
        self.lethal = lethal
        self.invisible = invisible

    def update(self):
        self.duration -= 1
        if self.duration <= 0:
            self.active = False

    def draw(self, screen):
        if not self.active:
            return
        cells = self.get_affected_cells()
        for cx, cy in cells:
            rect = pygame.Rect(cx * CELL_SIZE, cy * CELL_SIZE, CELL_SIZE, CELL_SIZE)
            if self.lethal:
                alpha = 100 + (self.duration * 20)
                alpha = min(180, max(80, alpha))
                cloud_surf = pygame.Surface((CELL_SIZE, CELL_SIZE), pygame.SRCALPHA)
                cloud_surf.fill((100, 200, 100, alpha))
                pygame.draw.ellipse(cloud_surf, (120, 220, 120, alpha), (5, 5, CELL_SIZE - 10, CELL_SIZE - 10))
                screen.blit(cloud_surf, rect)
            elif self.invisible:
                alpha = 80 + (self.duration * 10)
                alpha = min(150, max(50, alpha))
                cloud_surf = pygame.Surface((CELL_SIZE, CELL_SIZE), pygame.SRCALPHA)
                cloud_surf.fill((150, 150, 150, alpha))
                pygame.draw.ellipse(cloud_surf, (180, 180, 180, alpha), (5, 5, CELL_SIZE - 10, CELL_SIZE - 10))
                screen.blit(cloud_surf, rect)

    def get_affected_cells(self):
        cells = set()
        for dx in range(-self.radius, self.radius + 1):
            for dy in range(-self.radius, self.radius + 1):
                if abs(dx) + abs(dy) <= self.radius:
                    nx, ny = self.x + dx, self.y + dy
                    if 0 <= nx < GRID_SIZE and 0 <= ny < GRID_SIZE:
                        cells.add((nx, ny))
        return cells

class LavaCell:
    def __init__(self, x, y, duration):
        self.x = x
        self.y = y
        self.duration = duration
        self.active = True

    def update(self):
        self.duration -= 1
        if self.duration <= 0:
            self.active = False

    def draw(self, screen):
        if not self.active:
            return
        rect = pygame.Rect(self.x * CELL_SIZE, self.y * CELL_SIZE, CELL_SIZE, CELL_SIZE)
        pygame.draw.rect(screen, (255, 69, 0), rect)
        for _ in range(3):
            px = self.x * CELL_SIZE + random.randint(5, CELL_SIZE-5)
            py = self.y * CELL_SIZE + random.randint(5, CELL_SIZE-5)
            pygame.draw.circle(screen, (255, 140, 0), (px, py), 2)

    def get_pos(self):
        return (self.x, self.y)

class Slime:
    def __init__(self, x, y, slime_type, direction=None, lava_cells_list=None):
        self.x = x
        self.y = y
        self.slime_type = slime_type
        self.lava_cells_ref = lava_cells_list
        info = SLIME_INFO[slime_type]
        self.jump_length = info["jump_length"]
        self.jump_freq = info["jump_freq"]
        if info["max_jumps"] is not None:
            self.max_jumps = random.randint(*info["max_jumps"])
        else:
            self.max_jumps = float('inf')
        self.jumps_done = 0
        self.color = info["color"]
        self.active = True
        self.turn_counter = 0
        if direction is not None:
            self.direction = direction
        else:
            self.direction = self._initial_direction()
        self.shoot_cooldown = 0
        self.rainbow_offset = 0

    def _initial_direction(self):
        if self.x == 0:
            return 'right'
        elif self.x == GRID_SIZE - 1:
            return 'left'
        elif self.y == 0:
            return 'down'
        else:
            return 'up'

    def update(self, slime_balls, gas_clouds, invisible_clouds, new_slimes=None, lava_cells_list=None):
        if new_slimes is None:
            new_slimes = []
        self.turn_counter += 1
        self.rainbow_offset = (self.rainbow_offset + 5) % 360
        if self.jump_freq == 1 or (self.jump_freq == 2 and self.turn_counter % 2 == 1):
            old_x, old_y = self.x, self.y
            self._jump()
            if self.slime_type == "bright_orange_slime" and lava_cells_list is not None:
                lava_cells_list.append(LavaCell(self.x, self.y, duration=10))
            if self.slime_type == "rainbow_slime":
                self._shoot_rainbow(slime_balls)
                if random.random() < 0.3:
                    gas_clouds.append(SlimeGasCloud(self.x, self.y, 2, 3, lethal=True))
                if random.random() < 0.3:
                    invisible_clouds.append(SlimeGasCloud(self.x, self.y, 3, 5, lethal=False, invisible=True))
        if self.slime_type == "red_slime":
            self._shoot(slime_balls)
        if self.jumps_done >= self.max_jumps and self.slime_type != "rainbow_slime":
            self.active = False
            self._on_death(slime_balls, gas_clouds, invisible_clouds, new_slimes, lava_cells_list)
        if self.slime_type == "rainbow_slime":
            if not (0 <= self.x < GRID_SIZE and 0 <= self.y < GRID_SIZE):
                self.active = False

    def _jump(self):
        if self.slime_type in ["purple_blue_slime", "rainbow_slime"]:
            self.direction = random.choice(['up', 'down', 'left', 'right'])
        if self.slime_type == "rainbow_slime":
            jump_dist = random.randint(2, 5)
        else:
            jump_dist = self.jump_length
        dx, dy = 0, 0
        if self.direction == 'up':
            dy = -jump_dist
        elif self.direction == 'down':
            dy = jump_dist
        elif self.direction == 'left':
            dx = -jump_dist
        elif self.direction == 'right':
            dx = jump_dist
        new_x = self.x + dx
        new_y = self.y + dy
        if 0 <= new_x < GRID_SIZE and 0 <= new_y < GRID_SIZE:
            self.x = new_x
            self.y = new_y
        else:
            opposite = {'up': 'down', 'down': 'up', 'left': 'right', 'right': 'left'}
            self.direction = opposite[self.direction]
            new_dx, new_dy = 0, 0
            if self.direction == 'up':
                new_dy = -jump_dist
            elif self.direction == 'down':
                new_dy = jump_dist
            elif self.direction == 'left':
                new_dx = -jump_dist
            elif self.direction == 'right':
                new_dx = jump_dist
            new_x2 = self.x + new_dx
            new_y2 = self.y + new_dy
            if 0 <= new_x2 < GRID_SIZE and 0 <= new_y2 < GRID_SIZE:
                self.x = new_x2
                self.y = new_y2
        self.jumps_done += 1

    def _shoot(self, slime_balls):
        directions = [(0, -1), (0, 1), (-1, 0), (1, 0)]
        ball_color = (255, 69, 0) if self.slime_type == "red_slime" else (100, 255, 100, 200)
        for dx, dy in directions:
            slime_balls.append(
                SlimeBall(self.x + dx, self.y + dy, dx, dy, speed=SLIME_INFO[self.slime_type].get("shoot_speed", 1),
                          color=ball_color))

    def _shoot_rainbow(self, slime_balls):
        directions = [(0, -1), (0, 1), (-1, 0), (1, 0)]
        types = [
            {"speed": 1, "color": (255, 0, 0)},
            {"speed": 2, "color": PURPLE_FIRE},
            {"speed": 1, "color": (0, 255, 0)}
        ]
        for dx, dy in directions:
            t = random.choice(types)
            slime_balls.append(SlimeBall(self.x + dx, self.y + dy, dx, dy, speed=t["speed"], color=t["color"]))

    def _on_death(self, slime_balls, gas_clouds, invisible_clouds, new_slimes, lava_cells_list):
        info = SLIME_INFO[self.slime_type]
        effect = info.get("death_effect")
        if effect == "balls":
            directions = [(0, -1), (0, 1), (-1, 0), (1, 0)]
            for dx, dy in directions:
                slime_balls.append(SlimeBall(self.x + dx, self.y + dy, dx, dy, speed=info["death_balls_speed"],
                                             color=(100, 255, 100, 200)))
        elif effect == "invis_gas":
            invisible_clouds.append(
                SlimeGasCloud(self.x, self.y, info["gas_radius"], info["gas_duration"], lethal=False, invisible=True))
        elif effect == "gas":
            gas_clouds.append(SlimeGasCloud(self.x, self.y, info["gas_radius"], info["gas_duration"], lethal=True))
        elif effect == "shoot":
            ball_color = (255, 69, 0) if self.slime_type == "red_slime" else (100, 255, 100, 200)
            directions = [(0, -1), (0, 1), (-1, 0), (1, 0)]
            for dx, dy in directions:
                slime_balls.append(
                    SlimeBall(self.x + dx, self.y + dy, dx, dy, speed=info.get("shoot_speed", 1), color=ball_color))
        elif effect == "spawn_dark_gray":
            self._spawn_slime_around("dark_gray_slime", new_slimes, lava_cells_list)
        elif effect == "spawn_light_gray":
            self._spawn_slime_around("light_gray_slime", new_slimes, lava_cells_list)
        elif effect == "spawn_white":
            self._spawn_slime_around("white_slime", new_slimes, lava_cells_list)
        elif effect == "lava" and lava_cells_list is not None:
            radius = info.get("lava_radius", 3)
            duration = info.get("lava_duration", 10)
            for dx in range(-radius, radius+1):
                for dy in range(-radius, radius+1):
                    if abs(dx) + abs(dy) <= radius:
                        nx, ny = self.x + dx, self.y + dy
                        if 0 <= nx < GRID_SIZE and 0 <= ny < GRID_SIZE:
                            lava_cells_list.append(LavaCell(nx, ny, duration))
        elif effect == "spawn_two":
            # Спавнит двух слизней: серо-зелёный (dark_green_slime) или оранжевый (bright_orange_slime)
            for _ in range(2):
                new_type = random.choice(["dark_green_slime", "bright_orange_slime"])
                # Ищем соседнюю пустую клетку
                for _ in range(10):
                    dx = random.choice([-1, 0, 1])
                    dy = random.choice([-1, 0, 1])
                    if dx == 0 and dy == 0:
                        continue
                    nx, ny = self.x + dx, self.y + dy
                    if 0 <= nx < GRID_SIZE and 0 <= ny < GRID_SIZE:
                        new_slime = Slime(nx, ny, new_type, None, lava_cells_list)
                        new_slimes.append(new_slime)
                        break

    def _spawn_slime_around(self, slime_type, new_slimes, lava_cells_list):
        directions = [(-1, 0, 'left'), (1, 0, 'right'), (0, -1, 'up'), (0, 1, 'down')]
        for dx, dy, dir_name in directions:
            nx, ny = self.x + dx, self.y + dy
            if 0 <= nx < GRID_SIZE and 0 <= ny < GRID_SIZE:
                new_slime = Slime(nx, ny, slime_type, dir_name, lava_cells_list)
                new_slimes.append(new_slime)

    # В draw для Ant, DungBeetle, StagBeetle, Anthill:
    def draw(self, screen, invisible_clouds=None):
        if invisible_clouds:
            for cloud in invisible_clouds:
                if (self.x, self.y) in cloud.get_affected_cells():
                    return
        # ... остальной код рисования
        rect = pygame.Rect(self.x * CELL_SIZE, self.y * CELL_SIZE, CELL_SIZE, CELL_SIZE)
        slime_surf = pygame.Surface((CELL_SIZE, CELL_SIZE), pygame.SRCALPHA)
        if self.slime_type == "rainbow_slime":
            hue = self.rainbow_offset % 360
            color = pygame.Color(0)
            color.hsva = (hue, 100, 100)
            color.a = 180
        else:
            color = self.color
        pygame.draw.ellipse(slime_surf, color, (5, 5, CELL_SIZE - 10, CELL_SIZE - 10))
        pygame.draw.ellipse(slime_surf, (255, 255, 255, 100), (10, 10, CELL_SIZE - 20, CELL_SIZE - 20), 2)
        eye_color = (0, 0, 0, 200)
        pygame.draw.circle(slime_surf, eye_color, (CELL_SIZE // 3, CELL_SIZE // 3), CELL_SIZE // 10)
        pygame.draw.circle(slime_surf, eye_color, (2 * CELL_SIZE // 3, CELL_SIZE // 3), CELL_SIZE // 10)
        screen.blit(slime_surf, rect)

    def get_pos(self):
        return (self.x, self.y)

def spawn_slime(slime_type, direction=None, lava_cells_list=None):
    side = random.choice(['top', 'bottom', 'left', 'right'])
    if side == 'top':
        x = random.randint(0, GRID_SIZE - 1)
        y = 0
    elif side == 'bottom':
        x = random.randint(0, GRID_SIZE - 1)
        y = GRID_SIZE - 1
    elif side == 'left':
        x = 0
        y = random.randint(0, GRID_SIZE - 1)
    else:
        x = GRID_SIZE - 1
        y = random.randint(0, GRID_SIZE - 1)
    return Slime(x, y, slime_type, direction, lava_cells_list)

def check_collision_slime(bird_x, bird_y, slimes, slime_balls, gas_clouds, invisible_clouds, lava_cells=None):
    bird_pos = (bird_x, bird_y)
    for slime in slimes:
        # Светло-серые и белые слизни не убивают
        if slime.slime_type in ("light_gray_slime", "white_slime"):
            continue
        if slime.get_pos() == bird_pos:
            return True
    for ball in slime_balls:
        if ball.active and ball.get_pos() == bird_pos:
            return True
    for gc in gas_clouds:
        if gc.lethal and bird_pos in gc.get_affected_cells():
            return True
    if lava_cells:
        for lava in lava_cells:
            if lava.active and lava.get_pos() == bird_pos:
                return True
    return False

# ---------------------- НАСЕКОМЫЕ ----------------------
INSECT_INFO_ORDERED = [
    "ant", "dung_beetle", "stag_beetle", "anthill"
]

INSECT_INFO = {
    "ant": {
        "description": "Муравей. Появляется с краёв, движется со скоростью 1, поворачивает раз в 3 хода (вероятность 0.3).",
        "size": 1, "speed": 1, "turn_cooldown": 3, "turn_chance": 0.3, "special": "Повороты",
        "spawn_condition": "Всегда",
        "color": ANT_COLOR
    },
    "dung_beetle": {
        "description": "Навозник. 3 хода стоит, затем пробегает всю линию, оставляя яд (3 хода).",
        "size": 1, "charge_time": 3, "special": "Линейный рывок, ядовитый след",
        "spawn_condition": "Всегда",
        "color": DUNG_BEETLE_COLOR
    },
    "stag_beetle": {
        "description": "Рогач. 3 хода стоит, затем пробегает всю линию, оставляя невидимый газ (5 ходов) на пути и соседних клетках.",
        "size": 1, "charge_time": 3, "special": "Линейный рывок, невидимый газ",
        "spawn_condition": "Всегда",
        "color": STAG_BEETLE_COLOR
    },
    "anthill": {
        "description": "Муравейник. Размер 3x3, падает 5 ходов, стоит 21 ход, спавнит муравьёв раз в 8 ходов. При разрушении спавнит 4 муравья.",
        "size": 3, "fall_time": 5, "sit_time": 21, "spawn_interval": 8, "spawn_ants_on_death": 4,
        "special": "Спавн муравьёв",
        "spawn_condition": "Всегда",
        "color": ANTHILL_COLOR
    }
}

INSECT_CATEGORIES = {
    "Насекомые": ["ant", "dung_beetle", "stag_beetle", "anthill"]
}
TAB_NAMES_INSECTS = ["Насекомые"]

class PoisonCloud:
    def __init__(self, x, y, duration):
        self.x = x
        self.y = y
        self.duration = duration
        self.active = True

    def update(self):
        self.duration -= 1
        if self.duration <= 0:
            self.active = False

    def draw(self, screen):
        if not self.active:
            return
        rect = pygame.Rect(self.x * CELL_SIZE, self.y * CELL_SIZE, CELL_SIZE, CELL_SIZE)
        alpha = 100 + (self.duration * 20)
        alpha = min(180, max(80, alpha))
        cloud_surf = pygame.Surface((CELL_SIZE, CELL_SIZE), pygame.SRCALPHA)
        cloud_surf.fill((100, 200, 100, alpha))
        pygame.draw.ellipse(cloud_surf, (120, 220, 120, alpha), (5, 5, CELL_SIZE - 10, CELL_SIZE - 10))
        screen.blit(cloud_surf, rect)

    def get_pos(self):
        return (self.x, self.y)

class InsectShadow:
    def __init__(self, x, y, size, fall_time, insect_type):
        self.x = x
        self.y = y
        self.size = size
        self.remaining = fall_time
        self.insect_type = insect_type

    def update(self):
        self.remaining -= 1
        return self.remaining <= 0

    def draw(self, screen):
        alpha = min(150, 50 + (self.remaining * 20))
        surf = pygame.Surface((CELL_SIZE * self.size, CELL_SIZE * self.size), pygame.SRCALPHA)
        surf.fill((0, 0, 0, alpha))
        pygame.draw.rect(surf, (200, 200, 200, alpha), (0, 0, CELL_SIZE * self.size, CELL_SIZE * self.size), 2)
        screen.blit(surf, (self.x * CELL_SIZE, self.y * CELL_SIZE))

class Ant:
    def __init__(self, x, y, direction=None):
        self.x = x
        self.y = y
        self.direction = direction if direction else random.choice(['up', 'down', 'left', 'right'])
        self.turn_cooldown = 0
        self.active = True

    def update(self, bird_x, bird_y, poison_clouds, invisible_clouds):
        if self.turn_cooldown <= 0:
            if random.random() < 0.3:
                opposite = {'up': 'down', 'down': 'up', 'left': 'right', 'right': 'left'}
                possible = [d for d in ['up', 'down', 'left', 'right'] if d != opposite.get(self.direction)]
                self.direction = random.choice(possible)
            self.turn_cooldown = 3
        else:
            self.turn_cooldown -= 1

        dx, dy = 0, 0
        if self.direction == 'up':
            dy = -1
        elif self.direction == 'down':
            dy = 1
        elif self.direction == 'left':
            dx = -1
        elif self.direction == 'right':
            dx = 1
        new_x = self.x + dx
        new_y = self.y + dy
        if 0 <= new_x < GRID_SIZE and 0 <= new_y < GRID_SIZE:
            self.x = new_x
            self.y = new_y
        else:
            self.direction = {'up': 'down', 'down': 'up', 'left': 'right', 'right': 'left'}[self.direction]
        if not (0 <= self.x < GRID_SIZE and 0 <= self.y < GRID_SIZE):
            self.active = False

    def draw(self, screen):
        rect = pygame.Rect(self.x * CELL_SIZE, self.y * CELL_SIZE, CELL_SIZE, CELL_SIZE)
        # Улучшенная отрисовка муравья
        pygame.draw.ellipse(screen, ANT_COLOR, rect.inflate(-8, -8))
        pygame.draw.rect(screen, BLACK, rect, 2)
        # Глаза
        eye_size = CELL_SIZE // 10
        eye_offset = CELL_SIZE // 4
        pygame.draw.circle(screen, WHITE, (self.x * CELL_SIZE + eye_offset, self.y * CELL_SIZE + eye_offset), eye_size)
        pygame.draw.circle(screen, WHITE, (self.x * CELL_SIZE + CELL_SIZE - eye_offset, self.y * CELL_SIZE + eye_offset), eye_size)
        pygame.draw.circle(screen, BLACK, (self.x * CELL_SIZE + eye_offset, self.y * CELL_SIZE + eye_offset), eye_size // 2)
        pygame.draw.circle(screen, BLACK, (self.x * CELL_SIZE + CELL_SIZE - eye_offset, self.y * CELL_SIZE + eye_offset), eye_size // 2)
        # РЈСЃРёРєРё
        start = (self.x * CELL_SIZE + CELL_SIZE//2, self.y * CELL_SIZE + CELL_SIZE//4)
        end1 = (self.x * CELL_SIZE + CELL_SIZE//3, self.y * CELL_SIZE)
        end2 = (self.x * CELL_SIZE + 2*CELL_SIZE//3, self.y * CELL_SIZE)
        pygame.draw.line(screen, BLACK, start, end1, 1)
        pygame.draw.line(screen, BLACK, start, end2, 1)

    def get_pos(self):
        return (self.x, self.y)

class DungBeetle:
    def __init__(self, x, y, direction):
        self.x = x
        self.y = y
        self.direction = direction
        self.state = 'charging'
        self.charge_timer = 3
        self.active = True

    def update(self, bird_x, bird_y, poison_clouds):
        if self.state == 'charging':
            self.charge_timer -= 1
            if self.charge_timer <= 0:
                self.state = 'rushing'
        elif self.state == 'rushing':
            dx, dy = 0, 0
            if self.direction == 'up':
                dy = -1
            elif self.direction == 'down':
                dy = 1
            elif self.direction == 'left':
                dx = -1
            elif self.direction == 'right':
                dx = 1
            while 0 <= self.x + dx < GRID_SIZE and 0 <= self.y + dy < GRID_SIZE:
                self.x += dx
                self.y += dy
                poison_clouds.append(PoisonCloud(self.x, self.y, 3))
            self.active = False

    def draw(self, screen):
        rect = pygame.Rect(self.x * CELL_SIZE, self.y * CELL_SIZE, CELL_SIZE, CELL_SIZE)
        pygame.draw.ellipse(screen, DUNG_BEETLE_COLOR, rect.inflate(-8, -8))
        pygame.draw.rect(screen, BLACK, rect, 2)
        # Р РѕР¶РєРё
        cx = self.x * CELL_SIZE + CELL_SIZE//2
        cy = self.y * CELL_SIZE + CELL_SIZE//4
        pygame.draw.line(screen, BLACK, (cx, cy), (cx-5, cy-5), 2)
        pygame.draw.line(screen, BLACK, (cx, cy), (cx+5, cy-5), 2)

    def get_pos(self):
        return (self.x, self.y)

class StagBeetle:
    def __init__(self, x, y, direction):
        self.x = x
        self.y = y
        self.direction = direction
        self.state = 'charging'
        self.charge_timer = 3
        self.active = True

    def update(self, bird_x, bird_y, invisible_clouds):
        if self.state == 'charging':
            self.charge_timer -= 1
            if self.charge_timer <= 0:
                self.state = 'rushing'
        elif self.state == 'rushing':
            dx, dy = 0, 0
            if self.direction == 'up':
                dy = -1
            elif self.direction == 'down':
                dy = 1
            elif self.direction == 'left':
                dx = -1
            elif self.direction == 'right':
                dx = 1
            while 0 <= self.x + dx < GRID_SIZE and 0 <= self.y + dy < GRID_SIZE:
                self.x += dx
                self.y += dy
                for nx in range(self.x-1, self.x+2):
                    for ny in range(self.y-1, self.y+2):
                        if 0 <= nx < GRID_SIZE and 0 <= ny < GRID_SIZE:
                            invisible_clouds.append(SlimeGasCloud(nx, ny, 0, 5, lethal=False, invisible=True))
            self.active = False

    def draw(self, screen):
        rect = pygame.Rect(self.x * CELL_SIZE, self.y * CELL_SIZE, CELL_SIZE, CELL_SIZE)
        pygame.draw.ellipse(screen, STAG_BEETLE_COLOR, rect.inflate(-8, -8))
        pygame.draw.rect(screen, BLACK, rect, 2)
        # Большие рога
        cx = self.x * CELL_SIZE + CELL_SIZE//2
        cy = self.y * CELL_SIZE + CELL_SIZE//4
        pygame.draw.line(screen, BLACK, (cx, cy), (cx-8, cy-8), 3)
        pygame.draw.line(screen, BLACK, (cx, cy), (cx+8, cy-8), 3)

    def get_pos(self):
        return (self.x, self.y)

class Anthill:
    def __init__(self, x, y):
        self.x = x
        self.y = y
        self.size = 3
        self.timer = 0
        self.active = True
        self.spawn_timer = 0

    def update(self, ants_list):
        self.timer += 1
        if self.timer % 8 == 0:   # реже спавним (было 4)
            possible_positions = []
            for dx in range(-1, self.size+1):
                for dy in range(-1, self.size+1):
                    nx = self.x + dx
                    ny = self.y + dy
                    if (dx < 0 or dx >= self.size or dy < 0 or dy >= self.size):
                        if 0 <= nx < GRID_SIZE and 0 <= ny < GRID_SIZE:
                            possible_positions.append((nx, ny))
            if possible_positions:
                sx, sy = random.choice(possible_positions)
                direction = random.choice(['up', 'down', 'left', 'right'])
                ants_list.append(Ant(sx, sy, direction))
        if self.timer >= 21:
            self.active = False
            for _ in range(4):
                dx = random.choice([-1, 1])
                dy = random.choice([-1, 1])
                nx = self.x + self.size//2 + dx
                ny = self.y + self.size//2 + dy
                if 0 <= nx < GRID_SIZE and 0 <= ny < GRID_SIZE:
                    ants_list.append(Ant(nx, ny, random.choice(['up', 'down', 'left', 'right'])))

    def draw(self, screen):
        for i in range(self.size):
            for j in range(self.size):
                rect = pygame.Rect((self.x+i) * CELL_SIZE, (self.y+j) * CELL_SIZE, CELL_SIZE, CELL_SIZE)
                pygame.draw.rect(screen, ANTHILL_COLOR, rect)
                pygame.draw.rect(screen, BLACK, rect, 1)
        # Холмик
        center_x = self.x + 1
        center_y = self.y + 1
        rect_center = pygame.Rect(center_x * CELL_SIZE, center_y * CELL_SIZE, CELL_SIZE, CELL_SIZE)
        pygame.draw.ellipse(screen, (50, 30, 10), rect_center.inflate(-10, -10))
        # Р’С…РѕРґ
        pygame.draw.ellipse(screen, BLACK, rect_center.inflate(-20, -20), 2)

    def get_positions(self):
        pos = set()
        for i in range(self.size):
            for j in range(self.size):
                pos.add((self.x + i, self.y + j))
        return pos

def spawn_insect(insect_type):
    side = random.choice(['top', 'bottom', 'left', 'right'])
    if side == 'top':
        x = random.randint(0, GRID_SIZE - 1)
        y = 0
        direction = 'down'
    elif side == 'bottom':
        x = random.randint(0, GRID_SIZE - 1)
        y = GRID_SIZE - 1
        direction = 'up'
    elif side == 'left':
        x = 0
        y = random.randint(0, GRID_SIZE - 1)
        direction = 'right'
    else:
        x = GRID_SIZE - 1
        y = random.randint(0, GRID_SIZE - 1)
        direction = 'left'

    if insect_type == "ant":
        return Ant(x, y, direction)
    elif insect_type == "dung_beetle":
        return DungBeetle(x, y, direction)
    elif insect_type == "stag_beetle":
        return StagBeetle(x, y, direction)
    elif insect_type == "anthill":
        for _ in range(50):
            tx = random.randint(1, GRID_SIZE - 4)
            ty = random.randint(1, GRID_SIZE - 4)
            return Anthill(tx, ty)
        return Anthill(2, 2)

def check_collision_insect(bird_x, bird_y, ants, beetles, anthills, poison_clouds, invisible_clouds):
    bird_pos = (bird_x, bird_y)
    for ant in ants:
        if ant.active and ant.get_pos() == bird_pos:
            return True
    for beetle in beetles:
        if beetle.active and beetle.get_pos() == bird_pos:
            return True
    for ah in anthills:
        if ah.active and bird_pos in ah.get_positions():
            return True
    for pc in poison_clouds:
        if pc.active and pc.get_pos() == bird_pos:
            return True
    for ic in invisible_clouds:
        if ic.active and ic.lethal and bird_pos in ic.get_affected_cells():
            return True
    return False

# ---------------------- РЫБЫ ----------------------
FISH_INFO_ORDERED = [
    "swallow", "swordfish", "shark", "octopus"
]

FISH_INFO = {
    "swallow": {"size": 1, "color": (100, 200, 255), "description": "Рыба-ласточка. Каждый 3-й ход выпрыгивает на 2 клетки над водой."},
    "swordfish": {"size": 2, "color": (80, 80, 220), "description": "Рыба-меч. Длина 2. После 3 ходов вылетает и летит до конца со скоростью 5."},
    "shark": {"size": 2, "color": (128, 128, 128), "description": "Акула. После 3 ходов выпрыгивает и летит в сторону игрока со скоростью 3."},
    "octopus": {"size": 3, "color": (255, 0, 0), "description": "Осьминог. Сидит 3 хода под водой, затем 10 ходов на поле. Каждый ход появляются 4 новых щупальца."}
}

class Fish:
    def __init__(self, fish_type):
        self.type = fish_type
        self.info = FISH_INFO[fish_type]
        self.size = self.info["size"]
        self.color = self.info["color"]
        self.underwater = True
        self.active = True
        self.timer = 0
        self.direction = None
        self.x = 0
        self.y = 0
        self.spawn_at_edge()
        self.speed = 1

    def spawn_at_edge(self):
        side = random.choice(['top', 'bottom', 'left', 'right'])
        if side == 'top':
            self.x = random.randint(0, GRID_SIZE - self.size)
            self.y = 0
            self.direction = 'down'
        elif side == 'bottom':
            self.x = random.randint(0, GRID_SIZE - self.size)
            self.y = GRID_SIZE - self.size
            self.direction = 'up'
        elif side == 'left':
            self.x = 0
            self.y = random.randint(0, GRID_SIZE - self.size)
            self.direction = 'right'
        else:
            self.x = GRID_SIZE - self.size
            self.y = random.randint(0, GRID_SIZE - self.size)
            self.direction = 'left'

    def get_positions(self):
        pos = set()
        for i in range(self.size):
            for j in range(self.size):
                pos.add((self.x + i, self.y + j))
        return pos

    def move(self, enemies=None):
        if not self.active:
            return
        steps = self.speed
        for _ in range(steps):
            old_positions = self.get_positions()
            dx = dy = 0
            if self.direction == 'up':
                dy = -1
            elif self.direction == 'down':
                dy = 1
            elif self.direction == 'left':
                dx = -1
            elif self.direction == 'right':
                dx = 1
            self.x += dx
            self.y += dy
            if not self.underwater and enemies is not None:
                self.kill_enemies_in_cell(enemies)
            if self.is_off_grid():
                self.active = False
                break

    def kill_enemies_in_cell(self, enemies):
        for enemy in enemies[:]:
            if enemy is self:
                continue
            enemy_positions = set()
            if hasattr(enemy, 'get_all_positions'):
                enemy_positions = enemy.get_all_positions()
            elif hasattr(enemy, 'get_positions'):
                enemy_positions = enemy.get_positions()
            elif hasattr(enemy, 'get_pos'):
                pos = enemy.get_pos()
                if pos:
                    enemy_positions = {pos}
            if enemy_positions & self.get_positions():
                enemy.active = False

    def is_off_grid(self):
        for pos in self.get_positions():
            x, y = pos
            if 0 <= x < GRID_SIZE and 0 <= y < GRID_SIZE:
                return False
        return True

    def update(self, bird_x, bird_y):
        self.timer += 1

class SwallowFish(Fish):
    def __init__(self):
        super().__init__("swallow")
        self.surface_timer = 0
        self.surface_steps = 0
        self.speed = 1

    def update(self, bird_x, bird_y, enemies=None):
        super().update(bird_x, bird_y)
        if self.underwater:
            if self.timer % 3 == 0:
                self.underwater = False
                self.surface_steps = 2
        else:
            self.move(enemies)
            self.surface_steps -= 1
            if self.surface_steps <= 0:
                self.underwater = True
        if self.underwater:
            self.move()
        if self.is_off_grid():
            self.active = False

    def draw(self, screen):
        if not self.active:
            return
        for i in range(self.size):
            for j in range(self.size):
                x = (self.x + i) * CELL_SIZE
                y = (self.y + j) * CELL_SIZE
                rect = pygame.Rect(x, y, CELL_SIZE, CELL_SIZE)
                if self.underwater:
                    s = pygame.Surface((CELL_SIZE, CELL_SIZE), pygame.SRCALPHA)
                    s.fill((0, 0, 0, 120))
                    screen.blit(s, rect)
                else:
                    # Тело
                    body_rect = rect.inflate(-10, -6)
                    pygame.draw.ellipse(screen, self.color, body_rect)
                    # Глаз
                    cx = x + CELL_SIZE // 2
                    cy = y + CELL_SIZE // 2
                    # Определяем угол направления
                    angle_map = {'up': -math.pi/2, 'down': math.pi/2, 'left': math.pi, 'right': 0}
                    angle = angle_map.get(self.direction, 0)
                    eye_offset = (CELL_SIZE//3, -CELL_SIZE//6)
                    eye_x, eye_y = rotate_point(cx + eye_offset[0], cy + eye_offset[1], angle, cx, cy)
                    pygame.draw.circle(screen, WHITE, (int(eye_x), int(eye_y)), 4)
                    pygame.draw.circle(screen, BLACK, (int(eye_x), int(eye_y)), 2)
                    # Хвост (треугольник сзади)
                    tail_points = []
                    if self.direction == 'up':
                        tail_points = [(x+CELL_SIZE//2, y+CELL_SIZE-5), (x+CELL_SIZE//3, y+CELL_SIZE-15), (x+2*CELL_SIZE//3, y+CELL_SIZE-15)]
                    elif self.direction == 'down':
                        tail_points = [(x+CELL_SIZE//2, y+5), (x+CELL_SIZE//3, y+15), (x+2*CELL_SIZE//3, y+15)]
                    elif self.direction == 'left':
                        tail_points = [(x+CELL_SIZE-5, y+CELL_SIZE//2), (x+CELL_SIZE-15, y+CELL_SIZE//3), (x+CELL_SIZE-15, y+2*CELL_SIZE//3)]
                    else: # right
                        tail_points = [(x+5, y+CELL_SIZE//2), (x+15, y+CELL_SIZE//3), (x+15, y+2*CELL_SIZE//3)]
                    pygame.draw.polygon(screen, self.color, tail_points)
                    pygame.draw.polygon(screen, BLACK, tail_points, 1)
                    # Плавник сверху
                    fin_points = []
                    if self.direction in ('up', 'down'):
                        fin_points = [(x+CELL_SIZE//2, y+CELL_SIZE//2-8), (x+CELL_SIZE//2-10, y+CELL_SIZE//2-18), (x+CELL_SIZE//2+10, y+CELL_SIZE//2-18)]
                    else:
                        fin_points = [(x+CELL_SIZE//2-8, y+CELL_SIZE//2), (x+CELL_SIZE//2-18, y+CELL_SIZE//2-10), (x+CELL_SIZE//2-18, y+CELL_SIZE//2+10)]
                    pygame.draw.polygon(screen, (min(255, self.color[0]+30), min(255, self.color[1]+30), min(255, self.color[2]+30)), fin_points)
                    pygame.draw.polygon(screen, BLACK, fin_points, 1)
                    pygame.draw.rect(screen, BLACK, rect, 2)

class Swordfish(Fish):
    def __init__(self):
        super().__init__("swordfish")
        self.length = 2
        self.underwater = True
        self.rush = False
        self.speed = 1

    def update(self, bird_x, bird_y, enemies=None):
        super().update(bird_x, bird_y)
        if self.underwater:
            self.move()
            if self.timer >= 3 and not self.rush:
                self.rush = True
                self.underwater = False
                self.speed = 5
        else:
            self.move(enemies)
            if self.is_off_grid():
                self.active = False

    def get_positions(self):
        pos = set()
        if self.direction in ('up', 'down'):
            for i in range(self.length):
                pos.add((self.x, self.y + i))
        else:
            for i in range(self.length):
                pos.add((self.x + i, self.y))
        return pos

    def draw(self, screen):
        if not self.active:
            return
        # Рисуем два сегмента тела (длина 2)
        positions = list(self.get_positions())
        if len(positions) < 2:
            return
        # Определяем голову (первый сегмент по направлению) и хвост
        head_pos = positions[0] if self.direction in ('right','down') else positions[1]
        tail_pos = positions[1] if self.direction in ('right','down') else positions[0]
        # Рисуем тело
        for pos in positions:
            x, y = pos
            rect = pygame.Rect(x*CELL_SIZE, y*CELL_SIZE, CELL_SIZE, CELL_SIZE)
            if self.underwater:
                s = pygame.Surface((CELL_SIZE, CELL_SIZE), pygame.SRCALPHA)
                s.fill((0,0,0,120))
                screen.blit(s, rect)
            else:
                pygame.draw.ellipse(screen, self.color, rect.inflate(-6, -6))
                pygame.draw.rect(screen, BLACK, rect, 2)
        # Меч (только у головы)
        head_x, head_y = head_pos
        head_rect = pygame.Rect(head_x*CELL_SIZE, head_y*CELL_SIZE, CELL_SIZE, CELL_SIZE)
        cx = head_rect.centerx
        cy = head_rect.centery
        sword_length = CELL_SIZE
        if self.direction == 'right':
            end_x, end_y = cx + sword_length, cy
        elif self.direction == 'left':
            end_x, end_y = cx - sword_length, cy
        elif self.direction == 'down':
            end_x, end_y = cx, cy + sword_length
        else: # up
            end_x, end_y = cx, cy - sword_length
        pygame.draw.line(screen, (200,200,200), (cx, cy), (end_x, end_y), 4)
        # Глаз
        eye_offset = (CELL_SIZE//3, -CELL_SIZE//6)
        angle_map = {'up': -math.pi/2, 'down': math.pi/2, 'left': math.pi, 'right': 0}
        angle = angle_map.get(self.direction, 0)
        ex, ey = rotate_point(cx + eye_offset[0], cy + eye_offset[1], angle, cx, cy)
        pygame.draw.circle(screen, WHITE, (int(ex), int(ey)), 4)
        pygame.draw.circle(screen, BLACK, (int(ex), int(ey)), 2)
        # Плавники
        if self.direction in ('up','down'):
            fin1 = (cx-10, cy)
            fin2 = (cx-20, cy-10)
            fin3 = (cx-20, cy+10)
        else:
            fin1 = (cx, cy-10)
            fin2 = (cx-10, cy-20)
            fin3 = (cx+10, cy-20)
        pygame.draw.polygon(screen, (100,100,200), [fin1, fin2, fin3])
        pygame.draw.polygon(screen, BLACK, [fin1, fin2, fin3], 1)

class Shark(Fish):
    def __init__(self):
        super().__init__("shark")
        self.size = 2
        self.underwater = True
        self.rush = False
        self.speed = 1

    def update(self, bird_x, bird_y, enemies=None):
        super().update(bird_x, bird_y)
        if self.underwater:
            self.move()
            if self.timer >= 3 and not self.rush:
                self.rush = True
                self.underwater = False
                self.speed = 3
                dx = bird_x - (self.x + self.size//2)
                dy = bird_y - (self.y + self.size//2)
                if abs(dx) > abs(dy):
                    self.direction = 'right' if dx > 0 else 'left'
                else:
                    self.direction = 'down' if dy > 0 else 'up'
        else:
            self.move(enemies)
            if self.is_off_grid():
                self.active = False

    def draw(self, screen):
        if not self.active:
            return
        for i in range(self.size):
            for j in range(self.size):
                x = (self.x + i) * CELL_SIZE
                y = (self.y + j) * CELL_SIZE
                rect = pygame.Rect(x, y, CELL_SIZE, CELL_SIZE)
                if self.underwater:
                    s = pygame.Surface((CELL_SIZE, CELL_SIZE), pygame.SRCALPHA)
                    s.fill((0,0,0,120))
                    screen.blit(s, rect)
                else:
                    # Тело акулы (серое)
                    body_rect = rect.inflate(-8, -4)
                    pygame.draw.ellipse(screen, self.color, body_rect)
                    # Брюхо светлее
                    belly_rect = rect.inflate(-12, -8)
                    belly_rect.y += 4
                    pygame.draw.ellipse(screen, (200,200,200), belly_rect)
                    # Глаз
                    cx = x + CELL_SIZE // 2
                    cy = y + CELL_SIZE // 2
                    angle_map = {'up': -math.pi/2, 'down': math.pi/2, 'left': math.pi, 'right': 0}
                    angle = angle_map.get(self.direction, 0)
                    eye_offset = (CELL_SIZE//3, -CELL_SIZE//6)
                    ex, ey = rotate_point(cx + eye_offset[0], cy + eye_offset[1], angle, cx, cy)
                    pygame.draw.circle(screen, WHITE, (int(ex), int(ey)), 5)
                    pygame.draw.circle(screen, BLACK, (int(ex), int(ey)), 2)
                    # Жаберные щели
                    gill_offset = (-CELL_SIZE//4, 0)
                    gx, gy = rotate_point(cx + gill_offset[0], cy + gill_offset[1], angle, cx, cy)
                    for k in range(3):
                        line_start = (gx + k*3, gy - 5)
                        line_end   = (gx + k*3, gy + 5)
                        lsx, lsy = rotate_point(line_start[0], line_start[1], angle, cx, cy)
                        lex, ley = rotate_point(line_end[0], line_end[1], angle, cx, cy)
                        pygame.draw.line(screen, (50,50,50), (lsx, lsy), (lex, ley), 2)
                    # Плавник на спине
                    fin_points = [(cx, cy-12), (cx-12, cy-25), (cx+12, cy-25)]
                    fin_rot = [rotate_point(px, py, angle, cx, cy) for (px,py) in fin_points]
                    pygame.draw.polygon(screen, (80,80,80), fin_rot)
                    pygame.draw.polygon(screen, BLACK, fin_rot, 1)
                    # РҐРІРѕСЃС‚
                    tail_len = 20
                    tail_base = (cx, cy+12) if self.direction in ('up','down') else (cx+12, cy)
                    tail_tip1 = (tail_base[0]-10, tail_base[1]+tail_len) if self.direction in ('up','down') else (tail_base[0]+tail_len, tail_base[1]-10)
                    tail_tip2 = (tail_base[0]+10, tail_base[1]+tail_len) if self.direction in ('up','down') else (tail_base[0]+tail_len, tail_base[1]+10)
                    t1 = rotate_point(tail_tip1[0], tail_tip1[1], angle, cx, cy)
                    t2 = rotate_point(tail_tip2[0], tail_tip2[1], angle, cx, cy)
                    base_rot = rotate_point(tail_base[0], tail_base[1], angle, cx, cy)
                    pygame.draw.polygon(screen, self.color, [base_rot, t1, t2])
                    pygame.draw.polygon(screen, BLACK, [base_rot, t1, t2], 1)
                    pygame.draw.rect(screen, BLACK, rect, 2)
class Octopus(Fish):
    def __init__(self):
        super().__init__("octopus")
        self.size = 3
        self.underwater = True
        self.phase = "underwater"
        self.tentacles = set()
        self.speed = 0
        # Увеличено время жизни на поверхности с 10 до 30 ходов
        self.surface_duration = 30

    def update(self, bird_x, bird_y, enemies=None):
        self.timer += 1
        if self.phase == "underwater":
            if self.timer >= 3:
                self.phase = "surface"
                self.underwater = False
                self.timer = 0
                self.spawn_tentacles(bird_x, bird_y)
        elif self.phase == "surface":
            if self.timer >= self.surface_duration:
                self.active = False
                return
            self.spawn_tentacles(bird_x, bird_y)

    def spawn_tentacles(self, bird_x, bird_y):
        forbidden = set()
        forbidden.add((bird_x, bird_y))
        for dx in [-1, 0, 1]:
            for dy in [-1, 0, 1]:
                nx, ny = bird_x + dx, bird_y + dy
                if 0 <= nx < GRID_SIZE and 0 <= ny < GRID_SIZE:
                    forbidden.add((nx, ny))
        for i in range(self.size):
            for j in range(self.size):
                forbidden.add((self.x + i, self.y + j))
        for _ in range(4):
            attempts = 0
            while attempts < 100:
                tx = random.randint(0, GRID_SIZE - 1)
                ty = random.randint(0, GRID_SIZE - 1)
                if (tx, ty) not in forbidden and (tx, ty) not in self.tentacles:
                    self.tentacles.add((tx, ty))
                    forbidden.add((tx, ty))
                    break
                attempts += 1

    def get_positions(self):
        pos = set()
        for i in range(self.size):
            for j in range(self.size):
                pos.add((self.x + i, self.y + j))
        return pos

    def draw(self, screen):
        if not self.active:
            return
        # Тело 3x3 (улучшенное)
        for i in range(self.size):
            for j in range(self.size):
                x = (self.x + i) * CELL_SIZE
                y = (self.y + j) * CELL_SIZE
                rect = pygame.Rect(x, y, CELL_SIZE, CELL_SIZE)
                if self.underwater:
                    s = pygame.Surface((CELL_SIZE, CELL_SIZE), pygame.SRCALPHA)
                    s.fill((0,0,0,120))
                    screen.blit(s, rect)
                else:
                    # Основное тело
                    body_rect = rect.inflate(-6, -6)
                    pygame.draw.ellipse(screen, self.color, body_rect)
                    # Глаза (два больших)
                    cx = x + CELL_SIZE//2
                    cy = y + CELL_SIZE//2
                    eye_offsets = [(-CELL_SIZE//3, -CELL_SIZE//4), (CELL_SIZE//3, -CELL_SIZE//4)]
                    for ox, oy in eye_offsets:
                        ex, ey = cx + ox, cy + oy
                        pygame.draw.circle(screen, WHITE, (int(ex), int(ey)), 6)
                        pygame.draw.circle(screen, BLACK, (int(ex), int(ey)), 3)
                        pygame.draw.circle(screen, (200,0,0), (int(ex+1), int(ey+1)), 1) # блик
                    # Р РѕС‚
                    mouth_y = cy + CELL_SIZE//4
                    pygame.draw.arc(screen, BLACK, (cx-8, mouth_y-4, 16, 8), 0, math.pi, 2)
                    pygame.draw.rect(screen, BLACK, rect, 2)
        # Щупальца (улучшенные)
        if not self.underwater:
            for tx, ty in self.tentacles:
                tx_rect = pygame.Rect(tx * CELL_SIZE, ty * CELL_SIZE, CELL_SIZE, CELL_SIZE)
                # Рисуем извивающиеся щупальца
                points = []
                cx = tx_rect.centerx
                cy = tx_rect.centery
                for k in range(4):
                    offset_x = math.sin(pygame.time.get_ticks()/200 + k) * 8
                    offset_y = math.cos(pygame.time.get_ticks()/200 + k) * 8
                    points.append((cx + offset_x, cy + offset_y - 10 + k*6))
                if len(points) >= 2:
                    pygame.draw.lines(screen, (200,100,200), False, points, 4)
                # РџСЂРёСЃРѕСЃРєРё
                pygame.draw.circle(screen, (150,50,150), (cx, cy-5), 5)
                pygame.draw.rect(screen, BLACK, tx_rect, 2)

    def check_tentacle_collision(self, bird_x, bird_y):
        return (bird_x, bird_y) in self.tentacles

def spawn_fish(fish_type):
    if fish_type == "swallow":
        return SwallowFish()
    elif fish_type == "swordfish":
        return Swordfish()
    elif fish_type == "shark":
        return Shark()
    elif fish_type == "octopus":
        return Octopus()
    else:
        return None

def check_collision_fish(bird_x, bird_y, fishes):
    bird_pos = (bird_x, bird_y)
    for fish in fishes:
        if not fish.underwater:
            if bird_pos in fish.get_positions():
                return True
            if isinstance(fish, Octopus) and fish.check_tentacle_collision(bird_x, bird_y):
                return True
    return False

# ---------------------- СПОСОБНОСТИ ----------------------
ABILITY_INFO = [
    {"name": "Гэмблинг", "key": 1, "slots": 1, "uses": 10, "cooldown": 1,
     "description": "Телепортирует на случайную пустую клетку."},
    {"name": "Освежитель", "key": 2, "slots": 1, "uses": 5, "cooldown": 3,
     "description": "Удаляет ядовитый и невидимый газ в радиусе 3."},
    {"name": "Айсаир", "key": 3, "slots": 2, "uses": 3, "cooldown": 3,
     "description": "Ослабляет огненные шары в радиусе 3:"},
    {"name": "Мощные крылья", "key": 4, "slots": 2, "uses": 5, "cooldown": 2,
     "description": "Перемещает на 3 клетки в направленииц движения."},
    {"name": "Ремнант", "key": 5, "slots": 3, "uses": 2, "cooldown": 10,
     "description": "Неуязвимость на 4 хода."},
    {"name": "The world", "key": 6, "slots": 3, "uses": 3, "cooldown": 7,
     "description": "Семерной ход."},
    {"name": "Метод скипа", "key": 7, "slots": 1, "uses": 20, "cooldown": 0,
     "description": "Пропускает один ход."}
]

selected_abilities = {}


def show_ability_selection(mode):
    global current_state, selected_abilities
    print(f"[DEBUG] ability_selection called with mode = {mode}")

    # Определяем максимальное количество слотов
    if mode.startswith("level"):
        level_num = int(mode[5:])
        info = LEVEL_INFO[level_num]
        max_slots = info["max_slots"]
    elif mode in ["challenge1", "challenge2"]:
        max_slots = 0
    elif mode == "sandbox":
        max_slots = float('inf')
    else:
        max_slots = 5  # для выживания и обычных режимов

    selected = {i: False for i in range(len(ABILITY_INFO))}

    def start_game_with_abilities():
        nonlocal selected
        global current_state, selected_abilities
        chosen = {}
        total_slots = 0
        for idx, ab_info in enumerate(ABILITY_INFO):
            if selected[idx]:
                total_slots += ab_info["slots"]
        if total_slots <= max_slots or max_slots == float('inf'):
            for idx, ab_info in enumerate(ABILITY_INFO):
                if selected[idx]:
                    chosen[ab_info["name"]] = {
                        "uses": ab_info["uses"],
                        "cooldown": 0,
                        "slots": ab_info["slots"],
                        "key": ab_info["key"],
                        "max_uses": ab_info["uses"],
                        "max_cooldown": ab_info["cooldown"]
                    }
            selected_abilities = chosen
            if mode == "snakes":
                current_state = "game"
            elif mode == "spiders":
                current_state = "spider_game"
            elif mode == "slimes":
                current_state = "slime_game"
            elif mode == "insects":
                current_state = "insect_game"
            elif mode == "fish":
                current_state = "fish_game"
            elif mode == "sandbox":
                current_state = "sandbox_play"
            elif mode.startswith("level"):
                current_state = mode
            else:
                current_state = "menu"
            print(f"[DEBUG] start_game: new current_state = {current_state}")
        else:
            print(f"[DEBUG] Not enough slots! Used {total_slots}, max {max_slots}")

    back_button = Button(WIDTH // 2 - 150, HEIGHT - 70, 300, 50, "Начать игру",
                         action=lambda: start_game_with_abilities())

    # Формируем описание уровня
    level_description = ""
    if mode.startswith("level"):
        level_num = int(mode[5:])
        info = LEVEL_INFO[level_num]
        target = info["target_kills"]
        enemies_list = []
        for enemy_type, sub_type, count in info["initial_enemies"]:
            name = RU_NAMES_SNAKES.get(sub_type, sub_type)
            enemies_list.append(f"{name} (x{count})")
        enemies_str = ", ".join(enemies_list)
        level_description = f"Уровень {level_num}: пережить {target} врагов. Враги: {enemies_str}."
        if info["modifiers"].get("god_of_torches"):
            level_description += " Усложнение: Бог факелов."
        if "special_spawn_limit" in info:
            limit_str = ", ".join(
                [f"{RU_NAMES_SNAKES.get(k, k)} ≤ {v}" for k, v in info["special_spawn_limit"].items()])
            level_description += f" Лимит: {limit_str}."

    while current_state == "ability_selection":
        for event in pygame.event.get():

            if event.type == pygame.QUIT:
                pygame.quit()
                sys.exit()
            elif event.type == pygame.MOUSEBUTTONDOWN:
                if event.button == 1:
                    mouse_x, mouse_y = event.pos
                    for idx, ab_info in enumerate(ABILITY_INFO):
                        rect = pygame.Rect(WIDTH // 2 - 300, 150 + idx * 45, 30, 30)
                        if rect.collidepoint(mouse_x, mouse_y):
                            selected[idx] = not selected[idx]
            back_button.handle_event(event)

        screen.fill(MENU_BG)
        title = font.render("Выберите способности", True, BLACK)
        screen.blit(title, (WIDTH // 2 - title.get_width() // 2, 50))

        # Отображение описания уровня
        if level_description:
            # Разбиваем длинную строку на несколько, если нужно
            words = level_description.split()
            lines = []
            current_line = ""
            for word in words:
                if len(current_line) + len(word) + 1 <= 60:
                    if current_line:
                        current_line += " "
                    current_line += word
                else:
                    lines.append(current_line)
                    current_line = word
            if current_line:
                lines.append(current_line)
            y_desc = 90
            for line in lines:
                desc_surf = small_font.render(line, True, (50, 50, 150))
                screen.blit(desc_surf, (WIDTH // 2 - desc_surf.get_width() // 2, y_desc))
                y_desc += 22
            y_start = y_desc + 10
        else:
            y_start = 150

        total_slots = sum(ABILITY_INFO[idx]["slots"] for idx, sel in selected.items() if sel)
        slot_text = f"Занято ячеек: {total_slots} / {max_slots if max_slots != float('inf') else '∞'}"
        slot_color = BLACK if total_slots <= max_slots else RED_SNAKE
        slot_surf = small_font.render(slot_text, True, slot_color)
        screen.blit(slot_surf, (WIDTH // 2 - slot_surf.get_width() // 2, y_start - 10))

        y = y_start
        for idx, ab_info in enumerate(ABILITY_INFO):
            row_rect = pygame.Rect(WIDTH // 2 - 320, y, 640, 40)
            pygame.draw.rect(screen, (220, 220, 220), row_rect, border_radius=5)
            cb_rect = pygame.Rect(WIDTH // 2 - 300, y + 5, 30, 30)
            pygame.draw.rect(screen, BLACK, cb_rect, 2)
            if selected[idx]:
                pygame.draw.line(screen, BLACK, (cb_rect.left + 4, cb_rect.centery),
                                 (cb_rect.centerx, cb_rect.bottom - 4), 4)
                pygame.draw.line(screen, BLACK, (cb_rect.centerx, cb_rect.bottom - 4),
                                 (cb_rect.right - 4, cb_rect.top + 4), 4)
            name_surf = small_font.render(f"{ab_info['name']} (клавиша {ab_info['key']}) - {ab_info['slots']} яч.",
                                          True, BLACK)
            screen.blit(name_surf, (WIDTH // 2 - 250, y + 10))
            desc_surf = micro_font.render(ab_info["description"], True, (50, 50, 50))
            screen.blit(desc_surf, (WIDTH // 2 - 250, y + 25))
            y += 45

        back_button.draw(screen)
        pygame.display.flip()
        clock.tick(FPS)
# ---------------------- ИГРОВЫЕ РЕЖИМЫ ----------------------
def show_game():
    global current_state, survival_records
    is_survival = game_mode == "snakes"
    record_turns = survival_records.get("snakes", 0) if is_survival else 0

    abilities = selected_abilities.copy()
    for name, data in abilities.items():
        data["cooldown"] = 0
        data["uses"] = data["max_uses"]

    bird_x, bird_y = GRID_SIZE // 2, GRID_SIZE // 2
    last_direction = 'up'
    snakes = []
    fireballs = []
    invisible_clouds = []   # для газа бело-серой змеи
    turn_count = 0
    red_snakes_killed = 0
    black_snakes_killed = 0
    game_over = False
    turn_state = 'player'
    player_moved_this_turn = False
    killed_counts = {key: 0 for key in SNAKE_INFO.keys()}
    invulnerable_timer = 0
    double_turn_active = False
    moves_in_turn = 0

    running_game = True
    while running_game and current_state == "game":
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                current_state = "menu"
                running_game = False
            elif event.type == pygame.KEYDOWN and not game_over:
                if turn_state == 'player' and not player_moved_this_turn:
                    # Способность "Метод скипа" (клавиша 7)
                    if event.key == pygame.K_7 and "Метод скипа" in abilities:
                        data = abilities["Метод скипа"]
                        if data["cooldown"] == 0 and data["uses"] > 0:
                            data["uses"] -= 1
                            data["cooldown"] = data["max_cooldown"]
                            player_moved_this_turn = True
                            # пропускаем ход игрока, сразу переходим к змеям
                    elif event.key == pygame.K_1 and "Гэмблинг" in abilities:
                        data = abilities["Гэмблинг"]
                        if data["cooldown"] == 0 and data["uses"] > 0:
                            occupied = set()
                            for snake in snakes:
                                occupied.update(snake.get_all_positions())
                            for fb in fireballs:
                                if fb.active:
                                    occupied.add((fb.x, fb.y))
                            for ic in invisible_clouds:
                                occupied.update(ic.get_affected_cells())
                            free_cells = [(x, y) for x in range(GRID_SIZE) for y in range(GRID_SIZE) if
                                          (x, y) not in occupied]
                            if free_cells:
                                bird_x, bird_y = random.choice(free_cells)
                                data["uses"] -= 1
                                data["cooldown"] = data["max_cooldown"]
                                player_moved_this_turn = True
                                if check_collision(bird_x, bird_y, snakes, fireballs, invisible_clouds):
                                    game_over = True
                    elif event.key == pygame.K_2 and "Освежитель" in abilities:
                        data = abilities["Освежитель"]
                        if data["cooldown"] == 0 and data["uses"] > 0:
                            for ic in invisible_clouds[:]:
                                if abs(ic.x - bird_x) <= 3 and abs(ic.y - bird_y) <= 3:
                                    invisible_clouds.remove(ic)
                            data["uses"] -= 1
                            data["cooldown"] = data["max_cooldown"]
                    elif event.key == pygame.K_3 and "Айсаир" in abilities:
                        data = abilities["Айсаир"]
                        if data["cooldown"] == 0 and data["uses"] > 0:
                            for fb in fireballs[:]:
                                if abs(fb.x - bird_x) + abs(fb.y - bird_y) <= 3:
                                    if fb.color == PURPLE_FIRE:
                                        fb.color = (255, 69, 0)
                                        fb.speed = 1  # было 2
                                    elif fb.color == (255, 69, 0):
                                        fb.color = (100, 255, 100)
                                        fb.speed = 0.5  # было 1
                                    elif fb.color == (100, 255, 100):
                                        fb.active = False
                            data["uses"] -= 1
                            data["cooldown"] = data["max_cooldown"]
                    elif event.key == pygame.K_4 and "Мощные крылья" in abilities:
                        data = abilities["Мощные крылья"]
                        if data["cooldown"] == 0 and data["uses"] > 0:
                            dx, dy = 0, 0
                            if last_direction == 'up':
                                dy = -3
                            elif last_direction == 'down':
                                dy = 3
                            elif last_direction == 'left':
                                dx = -3
                            elif last_direction == 'right':
                                dx = 3
                            new_x = max(0, min(GRID_SIZE - 1, bird_x + dx))
                            new_y = max(0, min(GRID_SIZE - 1, bird_y + dy))
                            bird_x, bird_y = new_x, new_y
                            data["uses"] -= 1
                            data["cooldown"] = data["max_cooldown"]
                            player_moved_this_turn = True
                            if check_collision(bird_x, bird_y, snakes, fireballs, invisible_clouds):
                                game_over = True
                    elif event.key == pygame.K_5 and "Ремнант" in abilities:
                        data = abilities["Ремнант"]
                        if data["cooldown"] == 0 and data["uses"] > 0:
                            invulnerable_timer = 4
                            data["uses"] -= 1
                            data["cooldown"] = data["max_cooldown"]
                    elif event.key == pygame.K_6 and "The world" in abilities:
                        data = abilities["The world"]
                        if data["cooldown"] == 0 and data["uses"] > 0:
                            double_turn_active = True
                            moves_in_turn = 0
                            data["uses"] -= 1
                            data["cooldown"] = data["max_cooldown"]

                    if not player_moved_this_turn:
                        old_x, old_y = bird_x, bird_y
                        if event.key == pygame.K_w and bird_y > 0:
                            bird_y -= 1
                            last_direction = 'up'
                        elif event.key == pygame.K_s and bird_y < GRID_SIZE - 1:
                            bird_y += 1
                            last_direction = 'down'
                        elif event.key == pygame.K_a and bird_x > 0:
                            bird_x -= 1
                            last_direction = 'left'
                        elif event.key == pygame.K_d and bird_x < GRID_SIZE - 1:
                            bird_x += 1
                            last_direction = 'right'
                        if (bird_x, bird_y) != (old_x, old_y):
                            player_moved_this_turn = True
                            if invulnerable_timer <= 0 and check_collision(bird_x, bird_y, snakes, fireballs, invisible_clouds):
                                game_over = True

                    if double_turn_active and player_moved_this_turn:
                        moves_in_turn += 1
                        if moves_in_turn >= 7:
                            double_turn_active = False
                            turn_state = 'snakes'
                        else:
                            player_moved_this_turn = False
                    elif player_moved_this_turn:
                        turn_state = 'snakes'
            elif event.type == pygame.KEYDOWN and game_over:
                if event.key == pygame.K_r:
                    show_game()
                    return
                elif event.key == pygame.K_q:
                    current_state = "menu"
                    running_game = False

        if not game_over and turn_state == 'snakes':
            for snake in snakes[:]:
                snake.move(bird_x, bird_y, fireballs, invisible_clouds)   # передаём облака для бело-серой

            for fb in fireballs[:]:
                fb.move()
                if not fb.active:
                    fireballs.remove(fb)

            for ic in invisible_clouds[:]:
                ic.update()
                if not ic.active:
                    invisible_clouds.remove(ic)

            snakes_to_remove = []
            for snake in snakes:
                if snake.is_completely_off_grid():
                    snakes_to_remove.append(snake)
                    if snake.snake_type == 'red':
                        red_snakes_killed += 1
                    elif snake.snake_type == 'black':
                        black_snakes_killed += 1
                    killed_counts[snake.snake_type] += 1

            for snake in snakes_to_remove:
                snakes.remove(snake)

            MAX_SNAKES = 12
            if len(snakes) < MAX_SNAKES:
                available_types = []

                if red_snakes_killed == 0:
                    available_types.extend(['green', 'dark_green', 'bright_green', 'stripe_green', 'swamp_green'])
                else:
                    if red_snakes_killed == 1:
                        available_types.extend(['blue', 'dark_green', 'bright_green', 'stripe_green', 'swamp_green'])
                    if red_snakes_killed == 2:
                        available_types.extend(['blue', 'dark_blue', 'bright_green', 'stripe_green', 'swamp_green'])
                    if red_snakes_killed == 3:
                        available_types.extend(['blue', 'dark_blue', 'light_blue', 'stripe_green', 'swamp_green'])
                    if red_snakes_killed == 4:
                        available_types.extend(['blue', 'dark_blue', 'light_blue', 'stripe_blue', 'swamp_green'])
                    if red_snakes_killed == 5:
                        available_types.extend(['blue', 'dark_blue', 'light_blue', 'stripe_blue', 'pink_azure'])

                if black_snakes_killed == 2:
                    available_types.extend(['white', 'stripe_blue', 'pink_azure'])
                if black_snakes_killed == 3:
                    available_types.extend(['white', 'white_purple'])
                if black_snakes_killed >= 4:
                    available_types.extend(['white', 'white_purple', 'white_red'])

                if red_snakes_killed < 5 or black_snakes_killed >= 5:
                    available_types.append('red')
                if red_snakes_killed >= 5:
                    available_types.append('black')
                # Бело-серая змея после 5 чёрных
                if black_snakes_killed >= 5:
                    available_types.append('white_gray')

                if random.random() < 0.005:
                    available_types.append('rainbow_snake')

                available_types = list(dict.fromkeys(available_types))

                if random.random() < 0.35 and available_types:
                    snake_type = random.choice(available_types)
                    if snake_type == 'red':
                        if len([s for s in snakes if s.snake_type == 'red']) < 2 and random.random() < 0.12:
                            new_snake = create_snake_at_edge('red')
                            collision = any(new_snake.get_all_positions() & s.get_all_positions() for s in snakes)
                            if not collision:
                                snakes.append(new_snake)
                    elif snake_type == 'black':
                        if random.random() < 0.08:
                            new_snake = create_snake_at_edge('black')
                            collision = any(new_snake.get_all_positions() & s.get_all_positions() for s in snakes)
                            if not collision:
                                snakes.append(new_snake)
                    elif snake_type == 'white_gray':
                        if random.random() < 0.1:
                            new_snake = create_snake_at_edge('white_gray')
                            collision = any(new_snake.get_all_positions() & s.get_all_positions() for s in snakes)
                            if not collision:
                                snakes.append(new_snake)
                    else:
                        new_snake = create_snake_at_edge(snake_type)
                        collision = any(new_snake.get_all_positions() & s.get_all_positions() for s in snakes)
                        if not collision:
                            snakes.append(new_snake)

            if invulnerable_timer <= 0 and check_collision(bird_x, bird_y, snakes, fireballs, invisible_clouds):
                game_over = True

            for data in abilities.values():
                if data["cooldown"] > 0:
                    data["cooldown"] -= 1
            if invulnerable_timer > 0:
                invulnerable_timer -= 1

            turn_state = 'player'
            player_moved_this_turn = False
            turn_count += 1

        if not game_over and turn_state == 'player' and player_moved_this_turn and not double_turn_active:
            turn_state = 'snakes'

        screen.fill(WHITE)
        draw_grid()

        for snake in snakes:
            snake.draw(screen)
        for fb in fireballs:
            fb.draw(screen)
        for ic in invisible_clouds:
            ic.draw(screen)

        draw_bird(screen, bird_x, bird_y, True)

        y = 10
        ru_names = {
            "green": "Зелёная", "dark_green": "Тёмно-зелёная", "bright_green": "Ярко-зелёная",
            "stripe_green": "Полосатая зелёная", "swamp_green": "Болотная",
            "blue": "Синяя", "dark_blue": "Тёмно-синяя", "light_blue": "Светло-синяя",
            "stripe_blue": "Полосатая синяя", "pink_azure": "Розово-лазурная",
            "white": "Белая", "white_purple": "Бело-фиолетовая", "white_red": "Бело-красная",
            "red": "Красная", "black": "Чёрная", "rainbow_snake": "Радужная", "white_gray": "Бело-серая"
        }
        for snake_type in SNAKE_INFO_ORDERED:
            if killed_counts[snake_type] > 0:
                info = SNAKE_INFO[snake_type]
                name = ru_names.get(snake_type, snake_type)
                text = small_font.render(f"{name}: {killed_counts[snake_type]}", True, info["color"])
                screen.blit(text, (10, y))
                y += 22

        ability_y = 10
        for name, data in abilities.items():
            info = next((a for a in ABILITY_INFO if a["name"] == name), None)
            if info:
                key_str = f"[{info['key']}]"
                status = f"{data['uses']}/{data['max_uses']}"
                if data["cooldown"] > 0:
                    status += f" (РљР” {data['cooldown']})"
                text = micro_font.render(f"{key_str} {name}: {status}", True, BLACK)
                screen.blit(text, (WIDTH - 250, ability_y))
                ability_y += 20
        if invulnerable_timer > 0:
            inv_text = micro_font.render(f"Неуязвимость: {invulnerable_timer}", True, (200, 0, 0))
            screen.blit(inv_text, (WIDTH - 250, ability_y))
            ability_y += 20

        if is_survival:
            record_text = micro_font.render(f"Рекорд ходов: {record_turns}", True, (0, 100, 0))
            screen.blit(record_text, (WIDTH - 250, ability_y))

        if game_over:
            if is_survival and turn_count > survival_records["snakes"]:
                survival_records["snakes"] = turn_count
                save_records(survival_records)

            overlay = pygame.Surface((WIDTH, HEIGHT))
            overlay.set_alpha(200)
            overlay.fill(BLACK)
            screen.blit(overlay, (0, 0))

            texts = [
                font.render("ПОРАЖЕНИЕ!", True, RED_SNAKE),
                small_font.render("R - рестарт | Q - выход", True, GREEN)
            ]
            y_text = HEIGHT // 2 - 40
            for text in texts:
                rect = text.get_rect(center=(WIDTH // 2, y_text))
                screen.blit(text, rect)
                y_text += 40

        pygame.display.flip()
        clock.tick(FPS)

def show_spider_game():
    global current_state, survival_records
    is_survival = game_mode == "spiders"
    record_turns = survival_records.get("spiders", 0) if is_survival else 0

    abilities = selected_abilities.copy()
    for name, data in abilities.items():
        data["cooldown"] = 0
        data["uses"] = data["max_uses"]

    bird_x, bird_y = GRID_SIZE // 2, GRID_SIZE // 2
    last_direction = 'up'
    spiders = []
    shadows = []
    fireballs = []
    gas_clouds = []
    turn_count = 0
    red_spiders_killed = 0
    killed_counts = {key: 0 for key in SPIDER_INFO.keys()}
    game_over = False
    turn_state = 'player'
    player_moved_this_turn = False
    invulnerable_timer = 0
    double_turn_active = False
    moves_in_turn = 0

    def spawn_spider(spider_type):
        info = SPIDER_INFO[spider_type]
        size = info["size"]
        max_attempts = 50
        for _ in range(max_attempts):
            x = random.randint(0, GRID_SIZE - size)
            y = random.randint(0, GRID_SIZE - size)
            occupied = set()
            for s in spiders:
                occupied.update(s.get_positions())
            for sh in shadows:
                for i in range(sh.size):
                    for j in range(sh.size):
                        occupied.add((sh.x + i, sh.y + j))
            collision = False
            for i in range(size):
                for j in range(size):
                    if (x + i, y + j) in occupied:
                        collision = True
                        break
                if collision:
                    break
            if not collision:
                shadows.append(Shadow(x, y, size, info["fall_time"], spider_type))
                return True
        return False

    def update_spawn():
        nonlocal red_spiders_killed
        available = []

        if red_spiders_killed < 2:
            available.extend(["light_gray", "brown_gray", "dark_gray_red_cross", "dark_gray_green_circle"])
        if red_spiders_killed == 2:
            available.extend(["big_dark_gray", "dark_gray_red_cross", "dark_gray_green_circle"])
        if red_spiders_killed > 2 and red_spiders_killed < 4:
            available.extend(["big_dark_gray", "dark_gray_red_cross", "big_dark_gray_green_circle"])
        if red_spiders_killed == 4:
            available.extend(["big_dark_gray", "white_purple_circle", "big_dark_gray_green_circle"])
        if red_spiders_killed >= 5:
            available.extend(["big_dark_gray", "white_purple_circle", "big_dark_gray_green_circle", "black_spider"])

        if red_spiders_killed < 5:
            if random.random() < 0.2:
                available.append("dark_red")
        else:
            if random.random() < 0.05:
                available.append("dark_red")

        if random.random() < 0.005:
            available.append("rainbow_spider")

        available = list(dict.fromkeys(available))

        red_count = sum(1 for s in spiders if s.spider_type == "dark_red")
        if red_count >= 1 and "dark_red" in available:
            available.remove("dark_red")

        if random.random() < 0.25 and len(spiders) + len(shadows) < 8:
            if available:
                spider_type = random.choice(available)
                spawn_spider(spider_type)

    while current_state == "spider_game":
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                current_state = "menu"
                return
            elif event.type == pygame.KEYDOWN and not game_over:
                if turn_state == 'player' and not player_moved_this_turn:
                    if event.key == pygame.K_7 and "Метод скипа" in abilities:
                        data = abilities["Метод скипа"]
                        if data["cooldown"] == 0 and data["uses"] > 0:
                            data["uses"] -= 1
                            data["cooldown"] = data["max_cooldown"]
                            player_moved_this_turn = True
                    elif event.key == pygame.K_1 and "Гэмблинг" in abilities:
                        data = abilities["Гэмблинг"]
                        if data["cooldown"] == 0 and data["uses"] > 0:
                            occupied = set()
                            for spider in spiders:
                                occupied.update(spider.get_positions())
                            for sh in shadows:
                                for i in range(sh.size):
                                    for j in range(sh.size):
                                        occupied.add((sh.x + i, sh.y + j))
                            for fb in fireballs:
                                occupied.update(fb.get_positions())
                            for gc in gas_clouds:
                                occupied.update(gc.get_affected_cells())
                            free_cells = [(x, y) for x in range(GRID_SIZE) for y in range(GRID_SIZE) if
                                          (x, y) not in occupied]
                            if free_cells:
                                bird_x, bird_y = random.choice(free_cells)
                                data["uses"] -= 1
                                data["cooldown"] = data["max_cooldown"]
                                player_moved_this_turn = True
                                if invulnerable_timer <= 0 and check_collision_spider(bird_x, bird_y, spiders,
                                                                                      fireballs, gas_clouds):
                                    game_over = True
                    elif event.key == pygame.K_2 and "Освежитель" in abilities:
                        data = abilities["Освежитель"]
                        if data["cooldown"] == 0 and data["uses"] > 0:
                            for gc in gas_clouds[:]:
                                if abs(gc.x - bird_x) <= 3 and abs(gc.y - bird_y) <= 3:
                                    gas_clouds.remove(gc)
                            data["uses"] -= 1
                            data["cooldown"] = data["max_cooldown"]
                    elif event.key == pygame.K_3 and "Айсаир" in abilities:
                        data = abilities["Айсаир"]
                        if data["cooldown"] == 0 and data["uses"] > 0:
                            for fb in fireballs[:]:
                                if abs(fb.x - bird_x) + abs(fb.y - bird_y) <= 3:
                                    if fb.color == PURPLE_FIRE:
                                        fb.color = (255, 69, 0)
                                        fb.speed = 1  # было 2
                                    elif fb.color == (255, 69, 0):
                                        fb.color = (100, 255, 100)
                                        fb.speed = 0.5  # было 1
                                    elif fb.color == (100, 255, 100):
                                        fb.active = False
                            data["uses"] -= 1
                            data["cooldown"] = data["max_cooldown"]
                    elif event.key == pygame.K_4 and "Мощные крылья" in abilities:
                        data = abilities["Мощные крылья"]
                        if data["cooldown"] == 0 and data["uses"] > 0:
                            dx, dy = 0, 0
                            if last_direction == 'up':
                                dy = -3
                            elif last_direction == 'down':
                                dy = 3
                            elif last_direction == 'left':
                                dx = -3
                            elif last_direction == 'right':
                                dx = 3
                            new_x = max(0, min(GRID_SIZE - 1, bird_x + dx))
                            new_y = max(0, min(GRID_SIZE - 1, bird_y + dy))
                            bird_x, bird_y = new_x, new_y
                            data["uses"] -= 1
                            data["cooldown"] = data["max_cooldown"]
                            player_moved_this_turn = True
                            if invulnerable_timer <= 0 and check_collision_spider(bird_x, bird_y, spiders, fireballs,
                                                                                  gas_clouds):
                                game_over = True
                    elif event.key == pygame.K_5 and "Ремнант" in abilities:
                        data = abilities["Ремнант"]
                        if data["cooldown"] == 0 and data["uses"] > 0:
                            invulnerable_timer = 4
                            data["uses"] -= 1
                            data["cooldown"] = data["max_cooldown"]
                    elif event.key == pygame.K_6 and "The world" in abilities:
                        data = abilities["The world"]
                        if data["cooldown"] == 0 and data["uses"] > 0:
                            double_turn_active = True
                            moves_in_turn = 0
                            data["uses"] -= 1
                            data["cooldown"] = data["max_cooldown"]

                    if not player_moved_this_turn:
                        old_x, old_y = bird_x, bird_y
                        if event.key == pygame.K_w and bird_y > 0:
                            bird_y -= 1
                            last_direction = 'up'
                        elif event.key == pygame.K_s and bird_y < GRID_SIZE - 1:
                            bird_y += 1
                            last_direction = 'down'
                        elif event.key == pygame.K_a and bird_x > 0:
                            bird_x -= 1
                            last_direction = 'left'
                        elif event.key == pygame.K_d and bird_x < GRID_SIZE - 1:
                            bird_x += 1
                            last_direction = 'right'
                        if (bird_x, bird_y) != (old_x, old_y):
                            player_moved_this_turn = True
                            if invulnerable_timer <= 0 and check_collision_spider(bird_x, bird_y, spiders, fireballs,
                                                                                  gas_clouds):
                                game_over = True

                    if double_turn_active and player_moved_this_turn:
                        moves_in_turn += 1
                        if moves_in_turn >= 2:
                            double_turn_active = False
                            turn_state = 'snakes'
                        else:
                            player_moved_this_turn = False
                    elif player_moved_this_turn:
                        turn_state = 'snakes'
            elif event.type == pygame.KEYDOWN and game_over:
                if event.key == pygame.K_r:
                    show_spider_game()
                    return
                elif event.key == pygame.K_q:
                    current_state = "menu"
                    return

        if not game_over and turn_state == 'snakes':
            new_spiders = []
            for shadow in shadows[:]:
                if shadow.update():
                    spider = Spider(shadow.x, shadow.y, shadow.spider_type)
                    if shadow.spider_type == "dark_gray_red_cross":
                        cx, cy = shadow.x, shadow.y
                        for dx, dy in [(1, 0), (-1, 0), (0, 1), (0, -1)]:
                            fireballs.append(SpiderFireball(cx + dx, cy + dy, dx, dy, speed=1))
                    elif shadow.spider_type == "white_purple_circle":
                        cx = shadow.x + shadow.size // 2
                        cy = shadow.y + shadow.size // 2
                        for dx, dy in [(1, 0), (-1, 0), (0, 1), (0, -1)]:
                            fireballs.append(SpiderFireball(cx, cy, dx, dy, speed=2, length=1, color=PURPLE_FIRE))
                            fireballs.append(
                                SpiderFireball(cx + dx, cy + dy, dx, dy, speed=2, length=1, color=PURPLE_FIRE))
                    elif shadow.spider_type == "rainbow_spider":
                        spider.shoot_rainbow(fireballs)
                    new_spiders.append(spider)
                    shadows.remove(shadow)
            spiders.extend(new_spiders)

            for spider in spiders[:]:
                spider.update(fireballs, gas_clouds, bird_x, bird_y)
                if not spider.active:
                    spiders.remove(spider)
                    killed_counts[spider.spider_type] += 1
                    if spider.spider_type == "dark_red":
                        red_spiders_killed += 1

            for fb in fireballs[:]:
                fb.move()
                if not fb.active:
                    fireballs.remove(fb)

            for gc in gas_clouds[:]:
                gc.update()
                if not gc.active:
                    gas_clouds.remove(gc)

            if invulnerable_timer <= 0 and check_collision_spider(bird_x, bird_y, spiders, fireballs, gas_clouds):
                game_over = True

            update_spawn()

            for data in abilities.values():
                if data["cooldown"] > 0:
                    data["cooldown"] -= 1
            if invulnerable_timer > 0:
                invulnerable_timer -= 1

            turn_state = 'player'
            player_moved_this_turn = False
            turn_count += 1

        if not game_over and turn_state == 'player' and player_moved_this_turn and not double_turn_active:
            turn_state = 'snakes'

        for row in range(GRID_SIZE):
            for col in range(GRID_SIZE):
                rect = pygame.Rect(col * CELL_SIZE, row * CELL_SIZE, CELL_SIZE, CELL_SIZE)
                if (row + col) % 2 == 0:
                    pygame.draw.rect(screen, (40, 40, 50), rect)
                else:
                    pygame.draw.rect(screen, (30, 30, 40), rect)
                pygame.draw.rect(screen, (100, 100, 120), rect, 1)

        for shadow in shadows:
            shadow.draw(screen)
        for spider in spiders:
            spider.draw(screen)
        for fb in fireballs:
            fb.draw(screen)
        for gc in gas_clouds:
            gc.draw(screen)

        draw_bird(screen, bird_x, bird_y, True)

        y = 10
        ru_names = {
            "light_gray": "Светло-серый", "brown_gray": "Коричнево-серый",
            "dark_gray_red_cross": "Тёмно-серый с крестом", "dark_gray_green_circle": "Тёмно-серый с кругом",
            "dark_red": "Тёмно-красный", "big_dark_gray": "Большой тёмно-серый",
            "big_dark_gray_green_circle": "Большой с зелёным кругом", "black_spider": "Чёрный",
            "white_purple_circle": "Белый с фиолетовым", "rainbow_spider": "Радужный"
        }
        for spider_type in SPIDER_INFO_ORDERED:
            if killed_counts[spider_type] > 0:
                name = ru_names.get(spider_type, spider_type)
                text = small_font.render(f"{name}: {killed_counts[spider_type]}", True,
                                         SPIDER_INFO[spider_type]["color"])
                screen.blit(text, (10, y))
                y += 22

        ability_y = 10
        for name, data in abilities.items():
            info = next((a for a in ABILITY_INFO if a["name"] == name), None)
            if info:
                key_str = f"[{info['key']}]"
                status = f"{data['uses']}/{data['max_uses']}"
                if data["cooldown"] > 0:
                    status += f" (РљР” {data['cooldown']})"
                text = micro_font.render(f"{key_str} {name}: {status}", True, BLACK)
                screen.blit(text, (WIDTH - 250, ability_y))
                ability_y += 20
        if invulnerable_timer > 0:
            inv_text = micro_font.render(f"Неуязвимость: {invulnerable_timer}", True, (200, 0, 0))
            screen.blit(inv_text, (WIDTH - 250, ability_y))
            ability_y += 20

        if is_survival:
            record_text = micro_font.render(f"Рекорд ходов: {record_turns}", True, (0, 100, 0))
            screen.blit(record_text, (WIDTH - 250, ability_y))

        if game_over:
            if is_survival and turn_count > survival_records["spiders"]:
                survival_records["spiders"] = turn_count
                save_records(survival_records)

            overlay = pygame.Surface((WIDTH, HEIGHT))
            overlay.set_alpha(200)
            overlay.fill(BLACK)
            screen.blit(overlay, (0, 0))
            texts = [
                font.render("ПОРАЖЕНИЕ!", True, RED_SNAKE),
                small_font.render("R - рестарт | Q - выход", True, GREEN)
            ]
            y_text = HEIGHT // 2 - 40
            for text in texts:
                rect = text.get_rect(center=(WIDTH // 2, y_text))
                screen.blit(text, rect)
                y_text += 40

        pygame.display.flip()
        clock.tick(FPS)

def show_slime_game():
    global current_state, survival_records
    is_survival = game_mode == "slimes"
    record_turns = survival_records.get("slimes", 0) if is_survival else 0

    abilities = selected_abilities.copy()
    for name, data in abilities.items():
        data["cooldown"] = 0
        data["uses"] = data["max_uses"]

    bird_x, bird_y = GRID_SIZE // 2, GRID_SIZE // 2
    last_direction = 'up'
    slimes = []
    slime_balls = []
    gas_clouds = []
    invisible_clouds = []
    lava_cells_temp = []
    turn_count = 0
    killed_counts = {key: 0 for key in SLIME_INFO.keys()}
    game_over = False
    turn_state = 'player'
    player_moved_this_turn = False
    invulnerable_timer = 0
    double_turn_active = False
    moves_in_turn = 0
    black_slimes_killed = 0   # для спавна жёлтых

    def update_spawn():
        nonlocal black_slimes_killed
        if len(slimes) < 8 and random.random() < 0.3:
            available_types = [
                "green_slime_jump1", "green_slime_jump2", "dark_green_slime",
                "red_slime", "purple_blue_slime", "black_slime"
            ]
            # Оранжевые – только после убийства хотя бы одного чёрного
            if black_slimes_killed >= 1:
                available_types = [
                    "bright_orange_slime",
                    "red_slime", "black_slime"
                ]
            # Жёлтые – после 2 чёрных
            if black_slimes_killed >= 2:
                available_types = [
                    "yellow_slime", "bright_orange_slime",
                    "red_slime", "black_slime"
                ]
            if random.random() < 0.005:
                slime_type = "rainbow_slime"
            else:
                slime_type = random.choice(available_types)
            new_slime = spawn_slime(slime_type, lava_cells_list=lava_cells_temp)
            occupied = {s.get_pos() for s in slimes}
            if new_slime.get_pos() not in occupied:
                slimes.append(new_slime)

    while current_state == "slime_game":
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                current_state = "menu"
                return
            elif event.type == pygame.KEYDOWN and not game_over:
                if turn_state == 'player' and not player_moved_this_turn:
                    if event.key == pygame.K_7 and "Метод скипа" in abilities:
                        data = abilities["Метод скипа"]
                        if data["cooldown"] == 0 and data["uses"] > 0:
                            data["uses"] -= 1
                            data["cooldown"] = data["max_cooldown"]
                            player_moved_this_turn = True
                    elif event.key == pygame.K_1 and "Гэмблинг" in abilities:
                        data = abilities["Гэмблинг"]
                        if data["cooldown"] == 0 and data["uses"] > 0:
                            occupied = set()
                            for slime in slimes:
                                occupied.add(slime.get_pos())
                            for ball in slime_balls:
                                if ball.active:
                                    occupied.add((ball.x, ball.y))
                            for gc in gas_clouds:
                                occupied.update(gc.get_affected_cells())
                            for ic in invisible_clouds:
                                occupied.update(ic.get_affected_cells())
                            for lava in lava_cells_temp:
                                if lava.active:
                                    occupied.add((lava.x, lava.y))
                            free_cells = [(x, y) for x in range(GRID_SIZE) for y in range(GRID_SIZE) if
                                          (x, y) not in occupied]
                            if free_cells:
                                bird_x, bird_y = random.choice(free_cells)
                                data["uses"] -= 1
                                data["cooldown"] = data["max_cooldown"]
                                player_moved_this_turn = True
                                if invulnerable_timer <= 0 and check_collision_slime(bird_x, bird_y, slimes,
                                                                                     slime_balls, gas_clouds,
                                                                                     invisible_clouds, lava_cells_temp):
                                    game_over = True
                    elif event.key == pygame.K_2 and "Освежитель" in abilities:
                        data = abilities["Освежитель"]
                        if data["cooldown"] == 0 and data["uses"] > 0:
                            for gc in gas_clouds[:]:
                                if abs(gc.x - bird_x) <= 3 and abs(gc.y - bird_y) <= 3:
                                    gas_clouds.remove(gc)
                            for ic in invisible_clouds[:]:
                                if abs(ic.x - bird_x) <= 3 and abs(ic.y - bird_y) <= 3:
                                    invisible_clouds.remove(ic)
                            data["uses"] -= 1
                            data["cooldown"] = data["max_cooldown"]


                    elif event.key == pygame.K_3 and "Айсаир" in abilities:
                        data = abilities["Айсаир"]
                        if data["cooldown"] == 0 and data["uses"] > 0:
                            for fb in fireballs[:]:
                                if abs(fb.x - bird_x) + abs(fb.y - bird_y) <= 3:
                                    if fb.color == PURPLE_FIRE:
                                        fb.color = (255, 69, 0)
                                        fb.speed = 1  # было 2
                                    elif fb.color == (255, 69, 0):
                                        fb.color = (100, 255, 100)
                                        fb.speed = 0.5  # было 1
                                    elif fb.color == (100, 255, 100):
                                        fb.active = False
                            data["uses"] -= 1
                            data["cooldown"] = data["max_cooldown"]
                    elif event.key == pygame.K_4 and "Мощные крылья" in abilities:
                        data = abilities["Мощные крылья"]
                        if data["cooldown"] == 0 and data["uses"] > 0:
                            dx, dy = 0, 0
                            if last_direction == 'up':
                                dy = -3
                            elif last_direction == 'down':
                                dy = 3
                            elif last_direction == 'left':
                                dx = -3
                            elif last_direction == 'right':
                                dx = 3
                            new_x = max(0, min(GRID_SIZE - 1, bird_x + dx))
                            new_y = max(0, min(GRID_SIZE - 1, bird_y + dy))
                            bird_x, bird_y = new_x, new_y
                            data["uses"] -= 1
                            data["cooldown"] = data["max_cooldown"]
                            player_moved_this_turn = True
                            if invulnerable_timer <= 0 and check_collision_slime(bird_x, bird_y, slimes, slime_balls,
                                                                                 gas_clouds, invisible_clouds, lava_cells_temp):
                                game_over = True
                    elif event.key == pygame.K_5 and "Ремнант" in abilities:
                        data = abilities["Ремнант"]
                        if data["cooldown"] == 0 and data["uses"] > 0:
                            invulnerable_timer = 4
                            data["uses"] -= 1
                            data["cooldown"] = data["max_cooldown"]
                    elif event.key == pygame.K_6 and "The world" in abilities:
                        data = abilities["The world"]
                        if data["cooldown"] == 0 and data["uses"] > 0:
                            double_turn_active = True
                            moves_in_turn = 0
                            data["uses"] -= 1
                            data["cooldown"] = data["max_cooldown"]

                    if not player_moved_this_turn:
                        old_x, old_y = bird_x, bird_y
                        if event.key == pygame.K_w and bird_y > 0:
                            bird_y -= 1
                            last_direction = 'up'
                        elif event.key == pygame.K_s and bird_y < GRID_SIZE - 1:
                            bird_y += 1
                            last_direction = 'down'
                        elif event.key == pygame.K_a and bird_x > 0:
                            bird_x -= 1
                            last_direction = 'left'
                        elif event.key == pygame.K_d and bird_x < GRID_SIZE - 1:
                            bird_x += 1
                            last_direction = 'right'
                        if (bird_x, bird_y) != (old_x, old_y):
                            player_moved_this_turn = True
                            if invulnerable_timer <= 0 and check_collision_slime(bird_x, bird_y, slimes, slime_balls,
                                                                                 gas_clouds, invisible_clouds, lava_cells_temp):
                                game_over = True

                    if double_turn_active and player_moved_this_turn:
                        moves_in_turn += 1
                        if moves_in_turn >= 2:
                            double_turn_active = False
                            turn_state = 'snakes'
                        else:
                            player_moved_this_turn = False
                    elif player_moved_this_turn:
                        turn_state = 'snakes'
            elif event.type == pygame.KEYDOWN and game_over:
                if event.key == pygame.K_r:
                    show_slime_game()
                    return
                elif event.key == pygame.K_q:
                    current_state = "menu"
                    return

        if not game_over and turn_state == 'snakes':
            new_slimes = []
            for slime in slimes[:]:
                slime.update(slime_balls, gas_clouds, invisible_clouds, new_slimes, lava_cells_temp)
                if not slime.active:
                    slimes.remove(slime)
                    killed_counts[slime.slime_type] += 1
                    if slime.slime_type == "black_slime":
                        black_slimes_killed += 1
            slimes.extend(new_slimes)

            for ball in slime_balls[:]:
                ball.update()
                if not ball.active:
                    slime_balls.remove(ball)

            for gc in gas_clouds[:]:
                gc.update()
                if not gc.active:
                    gas_clouds.remove(gc)
            for ic in invisible_clouds[:]:
                ic.update()
                if not ic.active:
                    invisible_clouds.remove(ic)
            for lava in lava_cells_temp[:]:
                lava.update()
                if not lava.active:
                    lava_cells_temp.remove(lava)

            if invulnerable_timer <= 0 and check_collision_slime(bird_x, bird_y, slimes, slime_balls, gas_clouds,
                                                                 invisible_clouds, lava_cells_temp):
                game_over = True

            update_spawn()

            for data in abilities.values():
                if data["cooldown"] > 0:
                    data["cooldown"] -= 1
            if invulnerable_timer > 0:
                invulnerable_timer -= 1

            turn_state = 'player'
            player_moved_this_turn = False
            turn_count += 1

        if not game_over and turn_state == 'player' and player_moved_this_turn and not double_turn_active:
            turn_state = 'snakes'

        for row in range(GRID_SIZE):
            for col in range(GRID_SIZE):
                rect = pygame.Rect(col * CELL_SIZE, row * CELL_SIZE, CELL_SIZE, CELL_SIZE)
                if (row + col) % 2 == 0:
                    pygame.draw.rect(screen, LIGHT_BLUE_CELL, rect)
                else:
                    pygame.draw.rect(screen, LIGHT_PINK_CELL, rect)
                pygame.draw.rect(screen, BLACK, rect, 1)

        for lava in lava_cells_temp:
            if lava.active:
                lava.draw(screen)

        for ic in invisible_clouds:
            ic.draw(screen)
        for gc in gas_clouds:
            gc.draw(screen)

        for slime in slimes:
            slime.draw(screen, invisible_clouds)
        for ball in slime_balls:
            ball.draw(screen, invisible_clouds)

        bird_visible = True
        for ic in invisible_clouds:
            if (bird_x, bird_y) in ic.get_affected_cells():
                bird_visible = False
                break
        draw_bird(screen, bird_x, bird_y, bird_visible)

        y = 10
        ru_names = {
            "green_slime_jump1": "Зелёный прыгун 1", "green_slime_jump2": "Зелёный прыгун 2",
            "dark_green_slime": "Тёмно-зелёный", "red_slime": "Красный",
            "purple_blue_slime": "Фиолетово-синий",
            "black_slime": "Чёрный", "dark_gray_slime": "Тёмно-серый", "light_gray_slime": "Светло-серый",
            "white_slime": "Белый", "rainbow_slime": "Радужный",
            "bright_orange_slime": "Ярко-оранжевый", "yellow_slime": "Жёлтый"
        }
        for slime_type in SLIME_INFO_ORDERED:
            if killed_counts[slime_type] > 0:
                name = ru_names.get(slime_type, slime_type)
                text = small_font.render(f"{name}: {killed_counts[slime_type]}", True, (0, 0, 0))
                screen.blit(text, (10, y))
                y += 22

        ability_y = 10
        for name, data in abilities.items():
            info = next((a for a in ABILITY_INFO if a["name"] == name), None)
            if info:
                key_str = f"[{info['key']}]"
                status = f"{data['uses']}/{data['max_uses']}"
                if data["cooldown"] > 0:
                    status += f" (РљР” {data['cooldown']})"
                text = micro_font.render(f"{key_str} {name}: {status}", True, BLACK)
                screen.blit(text, (WIDTH - 250, ability_y))
                ability_y += 20
        if invulnerable_timer > 0:
            inv_text = micro_font.render(f"Неуязвимость: {invulnerable_timer}", True, (200, 0, 0))
            screen.blit(inv_text, (WIDTH - 250, ability_y))
            ability_y += 20

        if is_survival:
            record_text = micro_font.render(f"Рекорд ходов: {record_turns}", True, (0, 100, 0))
            screen.blit(record_text, (WIDTH - 250, ability_y))

        if game_over:
            if is_survival and turn_count > survival_records["slimes"]:
                survival_records["slimes"] = turn_count
                save_records(survival_records)

            overlay = pygame.Surface((WIDTH, HEIGHT))
            overlay.set_alpha(200)
            overlay.fill(BLACK)
            screen.blit(overlay, (0, 0))
            texts = [
                font.render("ПОРАЖЕНИЕ!", True, RED_SNAKE),
                small_font.render("R - рестарт | Q - выход", True, GREEN)
            ]
            y_text = HEIGHT // 2 - 40
            for text in texts:
                rect = text.get_rect(center=(WIDTH // 2, y_text))
                screen.blit(text, rect)
                y_text += 40

        pygame.display.flip()
        clock.tick(FPS)

def show_insect_game():
    global current_state, survival_records
    is_survival = game_mode == "insects"
    record_turns = survival_records.get("insects", 0) if is_survival else 0

    abilities = selected_abilities.copy()
    for name, data in abilities.items():
        data["cooldown"] = 0
        data["uses"] = data["max_uses"]

    bird_x, bird_y = GRID_SIZE // 2, GRID_SIZE // 2
    last_direction = 'up'
    ants = []
    beetles = []
    anthills = []
    shadows = []
    poison_clouds = []
    invisible_clouds = []
    turn_count = 0
    killed_counts = {key: 0 for key in INSECT_INFO.keys()}
    game_over = False
    turn_state = 'player'
    player_moved_this_turn = False
    invulnerable_timer = 0
    double_turn_active = False
    moves_in_turn = 0

    def spawn_insect_wrapper(insect_type):
        if insect_type == "anthill":
            for _ in range(50):
                tx = random.randint(1, GRID_SIZE - 4)
                ty = random.randint(1, GRID_SIZE - 4)
                new_ah = Anthill(tx, ty)
                collision = False
                for ah in anthills:
                    if new_ah.get_positions() & ah.get_positions():
                        collision = True
                        break
                for sh in shadows:
                    for i in range(sh.size):
                        for j in range(sh.size):
                            if (sh.x + i, sh.y + j) in new_ah.get_positions():
                                collision = True
                                break
                if not collision:
                    shadows.append(InsectShadow(tx, ty, 3, 5, "anthill"))
                    return True
            return False
        else:
            obj = spawn_insect(insect_type)
            if insect_type == "ant":
                ants.append(obj)
            else:
                beetles.append(obj)
            return True

    def update_spawn():
        if len(ants) + len(beetles) + len(anthills) + len(shadows) < 10 and random.random() < 0.3:
            insect_type = random.choice(["ant", "dung_beetle", "stag_beetle"])
            if insect_type == "ant":
                ants.append(spawn_insect("ant"))
            else:
                beetles.append(spawn_insect(insect_type))
        if random.random() < 0.02 and len(anthills) + len([sh for sh in shadows if sh.insect_type == "anthill"]) < 2:
            spawn_insect_wrapper("anthill")

    while current_state == "insect_game":
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                current_state = "menu"
                return
            elif event.type == pygame.KEYDOWN and not game_over:
                if turn_state == 'player' and not player_moved_this_turn:
                    if event.key == pygame.K_7 and "Метод скипа" in abilities:
                        data = abilities["Метод скипа"]
                        if data["cooldown"] == 0 and data["uses"] > 0:
                            data["uses"] -= 1
                            data["cooldown"] = data["max_cooldown"]
                            player_moved_this_turn = True
                    elif event.key == pygame.K_1 and "Гэмблинг" in abilities:
                        data = abilities["Гэмблинг"]
                        if data["cooldown"] == 0 and data["uses"] > 0:
                            occupied = set()
                            for ant in ants:
                                occupied.add(ant.get_pos())
                            for beetle in beetles:
                                occupied.add(beetle.get_pos())
                            for ah in anthills:
                                occupied.update(ah.get_positions())
                            for sh in shadows:
                                for i in range(sh.size):
                                    for j in range(sh.size):
                                        occupied.add((sh.x + i, sh.y + j))
                            for pc in poison_clouds:
                                occupied.add(pc.get_pos())
                            for ic in invisible_clouds:
                                occupied.update(ic.get_affected_cells())
                            free_cells = [(x, y) for x in range(GRID_SIZE) for y in range(GRID_SIZE) if
                                          (x, y) not in occupied]
                            if free_cells:
                                bird_x, bird_y = random.choice(free_cells)
                                data["uses"] -= 1
                                data["cooldown"] = data["max_cooldown"]
                                player_moved_this_turn = True
                                if invulnerable_timer <= 0 and check_collision_insect(bird_x, bird_y, ants, beetles, anthills, poison_clouds, invisible_clouds):
                                    game_over = True
                    elif event.key == pygame.K_2 and "Освежитель" in abilities:
                        data = abilities["Освежитель"]
                        if data["cooldown"] == 0 and data["uses"] > 0:
                            for pc in poison_clouds[:]:
                                if abs(pc.x - bird_x) <= 3 and abs(pc.y - bird_y) <= 3:
                                    poison_clouds.remove(pc)
                            for ic in invisible_clouds[:]:
                                if abs(ic.x - bird_x) <= 3 and abs(ic.y - bird_y) <= 3:
                                    invisible_clouds.remove(ic)
                            data["uses"] -= 1
                            data["cooldown"] = data["max_cooldown"]
                    elif event.key == pygame.K_3 and "Айсаир" in abilities:
                        data = abilities["Айсаир"]
                        if data["cooldown"] == 0 and data["uses"] > 0:
                            data["uses"] -= 1
                            data["cooldown"] = data["max_cooldown"]
                    elif event.key == pygame.K_4 and "Мощные крылья" in abilities:
                        data = abilities["Мощные крылья"]
                        if data["cooldown"] == 0 and data["uses"] > 0:
                            dx, dy = 0, 0
                            if last_direction == 'up':
                                dy = -3
                            elif last_direction == 'down':
                                dy = 3
                            elif last_direction == 'left':
                                dx = -3
                            elif last_direction == 'right':
                                dx = 3
                            new_x = max(0, min(GRID_SIZE - 1, bird_x + dx))
                            new_y = max(0, min(GRID_SIZE - 1, bird_y + dy))
                            bird_x, bird_y = new_x, new_y
                            data["uses"] -= 1
                            data["cooldown"] = data["max_cooldown"]
                            player_moved_this_turn = True
                            if invulnerable_timer <= 0 and check_collision_insect(bird_x, bird_y, ants, beetles, anthills, poison_clouds, invisible_clouds):
                                game_over = True
                    elif event.key == pygame.K_5 and "Ремнант" in abilities:
                        data = abilities["Ремнант"]
                        if data["cooldown"] == 0 and data["uses"] > 0:
                            invulnerable_timer = 4
                            data["uses"] -= 1
                            data["cooldown"] = data["max_cooldown"]
                    elif event.key == pygame.K_6 and "The world" in abilities:
                        data = abilities["The world"]
                        if data["cooldown"] == 0 and data["uses"] > 0:
                            double_turn_active = True
                            moves_in_turn = 0
                            data["uses"] -= 1
                            data["cooldown"] = data["max_cooldown"]

                    if not player_moved_this_turn:
                        old_x, old_y = bird_x, bird_y
                        if event.key == pygame.K_w and bird_y > 0:
                            bird_y -= 1
                            last_direction = 'up'
                        elif event.key == pygame.K_s and bird_y < GRID_SIZE - 1:
                            bird_y += 1
                            last_direction = 'down'
                        elif event.key == pygame.K_a and bird_x > 0:
                            bird_x -= 1
                            last_direction = 'left'
                        elif event.key == pygame.K_d and bird_x < GRID_SIZE - 1:
                            bird_x += 1
                            last_direction = 'right'
                        if (bird_x, bird_y) != (old_x, old_y):
                            player_moved_this_turn = True
                            if invulnerable_timer <= 0 and check_collision_insect(bird_x, bird_y, ants, beetles, anthills, poison_clouds, invisible_clouds):
                                game_over = True

                    if double_turn_active and player_moved_this_turn:
                        moves_in_turn += 1
                        if moves_in_turn >= 2:
                            double_turn_active = False
                            turn_state = 'enemies'
                        else:
                            player_moved_this_turn = False
                    elif player_moved_this_turn:
                        turn_state = 'enemies'
            elif event.type == pygame.KEYDOWN and game_over:
                if event.key == pygame.K_r:
                    show_insect_game()
                    return
                elif event.key == pygame.K_q:
                    current_state = "menu"
                    return

        if not game_over and turn_state == 'enemies':
            new_anthills = []
            for shadow in shadows[:]:
                if shadow.update():
                    if shadow.insect_type == "anthill":
                        ah = Anthill(shadow.x, shadow.y)
                        new_anthills.append(ah)
                    shadows.remove(shadow)
            anthills.extend(new_anthills)

            for ant in ants[:]:
                ant.update(bird_x, bird_y, poison_clouds, invisible_clouds)
                if not ant.active:
                    ants.remove(ant)
                    killed_counts["ant"] += 1

            for beetle in beetles[:]:
                if isinstance(beetle, DungBeetle):
                    beetle.update(bird_x, bird_y, poison_clouds)
                elif isinstance(beetle, StagBeetle):
                    beetle.update(bird_x, bird_y, invisible_clouds)
                if not beetle.active:
                    beetles.remove(beetle)
                    if isinstance(beetle, DungBeetle):
                        killed_counts["dung_beetle"] += 1
                    else:
                        killed_counts["stag_beetle"] += 1

            for ah in anthills[:]:
                ah.update(ants)
                if not ah.active:
                    anthills.remove(ah)
                    killed_counts["anthill"] += 1

            for pc in poison_clouds[:]:
                pc.update()
                if not pc.active:
                    poison_clouds.remove(pc)
            for ic in invisible_clouds[:]:
                ic.update()
                if not ic.active:
                    invisible_clouds.remove(ic)

            if invulnerable_timer <= 0 and check_collision_insect(bird_x, bird_y, ants, beetles, anthills, poison_clouds, invisible_clouds):
                game_over = True

            update_spawn()

            for data in abilities.values():
                if data["cooldown"] > 0:
                    data["cooldown"] -= 1
            if invulnerable_timer > 0:
                invulnerable_timer -= 1

            turn_state = 'player'
            player_moved_this_turn = False
            turn_count += 1

        if not game_over and turn_state == 'player' and player_moved_this_turn and not double_turn_active:
            turn_state = 'enemies'

        for row in range(GRID_SIZE):
            for col in range(GRID_SIZE):
                rect = pygame.Rect(col * CELL_SIZE, row * CELL_SIZE, CELL_SIZE, CELL_SIZE)
                if (row + col) % 2 == 0:
                    pygame.draw.rect(screen, SAND_INSECT_LIGHT, rect)
                else:
                    pygame.draw.rect(screen, SAND_INSECT_DARK, rect)
                pygame.draw.rect(screen, BLACK, rect, 1)

        for shadow in shadows:
            shadow.draw(screen)
        for pc in poison_clouds:
            pc.draw(screen)
        for ic in invisible_clouds:
            ic.draw(screen)
        for ah in anthills:
            ah.draw(screen)
        for beetle in beetles:
            beetle.draw(screen)
        for ant in ants:
            ant.draw(screen)

        draw_bird(screen, bird_x, bird_y, True)

        y = 10
        ru_names = {
            "ant": "Муравей",
            "dung_beetle": "Навозник",
            "stag_beetle": "Рогач",
            "anthill": "Муравейник"
        }
        for insect_type in INSECT_INFO_ORDERED:
            if killed_counts[insect_type] > 0:
                name = ru_names.get(insect_type, insect_type)
                text = small_font.render(f"{name}: {killed_counts[insect_type]}", True, INSECT_INFO[insect_type]["color"])
                screen.blit(text, (10, y))
                y += 22

        ability_y = 10
        for name, data in abilities.items():
            info = next((a for a in ABILITY_INFO if a["name"] == name), None)
            if info:
                key_str = f"[{info['key']}]"
                status = f"{data['uses']}/{data['max_uses']}"
                if data["cooldown"] > 0:
                    status += f" (РљР” {data['cooldown']})"
                text = micro_font.render(f"{key_str} {name}: {status}", True, BLACK)
                screen.blit(text, (WIDTH - 250, ability_y))
                ability_y += 20
        if invulnerable_timer > 0:
            inv_text = micro_font.render(f"Неуязвимость: {invulnerable_timer}", True, (200, 0, 0))
            screen.blit(inv_text, (WIDTH - 250, ability_y))
            ability_y += 20

        if is_survival:
            record_text = micro_font.render(f"Рекорд ходов: {record_turns}", True, (0, 100, 0))
            screen.blit(record_text, (WIDTH - 250, ability_y))

        if game_over:
            if is_survival and turn_count > survival_records["insects"]:
                survival_records["insects"] = turn_count
                save_records(survival_records)

            overlay = pygame.Surface((WIDTH, HEIGHT))
            overlay.set_alpha(200)
            overlay.fill(BLACK)
            screen.blit(overlay, (0, 0))
            texts = [
                font.render("ПОРАЖЕНИЕ!", True, RED_SNAKE),
                small_font.render("R - рестарт | Q - выход", True, GREEN)
            ]
            y_text = HEIGHT // 2 - 40
            for text in texts:
                rect = text.get_rect(center=(WIDTH // 2, y_text))
                screen.blit(text, rect)
                y_text += 40

        pygame.display.flip()
        clock.tick(FPS)

def show_fish_game():
    global current_state, survival_records
    is_survival = game_mode == "fish"
    record_turns = survival_records.get("fish", 0) if is_survival else 0

    abilities = selected_abilities.copy()
    for name, data in abilities.items():
        data["cooldown"] = 0
        data["uses"] = data["max_uses"]

    bird_x, bird_y = GRID_SIZE // 2, GRID_SIZE // 2
    last_direction = 'up'
    fishes = []
    turn_count = 0
    killed_counts = {key: 0 for key in FISH_INFO.keys()}
    game_over = False
    turn_state = 'player'
    player_moved_this_turn = False
    invulnerable_timer = 0
    double_turn_active = False
    moves_in_turn = 0

    def update_spawn():
        if len(fishes) < 6 and random.random() < 0.3:
            octopus_count = sum(1 for f in fishes if isinstance(f, Octopus))
            available = ["swallow", "swordfish", "shark"]
            if octopus_count == 0:
                available.append("octopus")
            fish_type = random.choice(available)
            new_fish = spawn_fish(fish_type)
            fishes.append(new_fish)

    while current_state == "fish_game":
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                current_state = "menu"
                return
            elif event.type == pygame.KEYDOWN and not game_over:
                if turn_state == 'player' and not player_moved_this_turn:
                    if event.key == pygame.K_7 and "Метод скипа" in abilities:
                        data = abilities["Метод скипа"]
                        if data["cooldown"] == 0 and data["uses"] > 0:
                            data["uses"] -= 1
                            data["cooldown"] = data["max_cooldown"]
                            player_moved_this_turn = True
                    elif event.key == pygame.K_1 and "Гэмблинг" in abilities:
                        data = abilities["Гэмблинг"]
                        if data["cooldown"] == 0 and data["uses"] > 0:
                            occupied = set()
                            for fish in fishes:
                                if not fish.underwater:
                                    occupied.update(fish.get_positions())
                                if isinstance(fish, Octopus) and not fish.underwater:
                                    occupied.update(fish.tentacles)
                            free_cells = [(x, y) for x in range(GRID_SIZE) for y in range(GRID_SIZE) if
                                          (x, y) not in occupied]
                            if free_cells:
                                bird_x, bird_y = random.choice(free_cells)
                                data["uses"] -= 1
                                data["cooldown"] = data["max_cooldown"]
                                player_moved_this_turn = True
                                if invulnerable_timer <= 0 and check_collision_fish(bird_x, bird_y, fishes):
                                    game_over = True
                    elif event.key == pygame.K_2 and "Освежитель" in abilities:
                        data = abilities["Освежитель"]
                        if data["cooldown"] == 0 and data["uses"] > 0:
                            data["uses"] -= 1
                            data["cooldown"] = data["max_cooldown"]
                    elif event.key == pygame.K_3 and "Айсаир" in abilities:
                        data = abilities["Айсаир"]
                        if data["cooldown"] == 0 and data["uses"] > 0:
                            data["uses"] -= 1


                            data["cooldown"] = data["max_cooldown"]
                    elif event.key == pygame.K_4 and "Мощные крылья" in abilities:
                        data = abilities["Мощные крылья"]
                        if data["cooldown"] == 0 and data["uses"] > 0:
                            dx, dy = 0, 0
                            if last_direction == 'up':
                                dy = -3
                            elif last_direction == 'down':
                                dy = 3
                            elif last_direction == 'left':
                                dx = -3
                            elif last_direction == 'right':
                                dx = 3
                            new_x = max(0, min(GRID_SIZE - 1, bird_x + dx))
                            new_y = max(0, min(GRID_SIZE - 1, bird_y + dy))
                            bird_x, bird_y = new_x, new_y
                            data["uses"] -= 1
                            data["cooldown"] = data["max_cooldown"]
                            player_moved_this_turn = True
                            if invulnerable_timer <= 0 and check_collision_fish(bird_x, bird_y, fishes):
                                game_over = True
                    elif event.key == pygame.K_5 and "Ремнант" in abilities:
                        data = abilities["Ремнант"]
                        if data["cooldown"] == 0 and data["uses"] > 0:
                            invulnerable_timer = 4
                            data["uses"] -= 1
                            data["cooldown"] = data["max_cooldown"]
                    elif event.key == pygame.K_6 and "The world" in abilities:
                        data = abilities["The world"]
                        if data["cooldown"] == 0 and data["uses"] > 0:
                            double_turn_active = True
                            moves_in_turn = 0
                            data["uses"] -= 1
                            data["cooldown"] = data["max_cooldown"]

                    if not player_moved_this_turn:
                        old_x, old_y = bird_x, bird_y
                        if event.key == pygame.K_w and bird_y > 0:
                            bird_y -= 1
                            last_direction = 'up'
                        elif event.key == pygame.K_s and bird_y < GRID_SIZE - 1:
                            bird_y += 1
                            last_direction = 'down'
                        elif event.key == pygame.K_a and bird_x > 0:
                            bird_x -= 1
                            last_direction = 'left'
                        elif event.key == pygame.K_d and bird_x < GRID_SIZE - 1:
                            bird_x += 1
                            last_direction = 'right'
                        if (bird_x, bird_y) != (old_x, old_y):
                            player_moved_this_turn = True
                            if invulnerable_timer <= 0 and check_collision_fish(bird_x, bird_y, fishes):
                                game_over = True

                    if double_turn_active and player_moved_this_turn:
                        moves_in_turn += 1
                        if moves_in_turn >= 2:
                            double_turn_active = False
                            turn_state = 'enemies'
                        else:
                            player_moved_this_turn = False
                    elif player_moved_this_turn:
                        turn_state = 'enemies'
            elif event.type == pygame.KEYDOWN and game_over:
                if event.key == pygame.K_r:
                    show_fish_game()
                    return
                elif event.key == pygame.K_q:
                    current_state = "menu"
                    return

        if not game_over and turn_state == 'enemies':
            for fish in fishes[:]:
                fish.update(bird_x, bird_y, fishes)
                if not fish.active:
                    fishes.remove(fish)
                    killed_counts[fish.type] += 1

            if invulnerable_timer <= 0 and check_collision_fish(bird_x, bird_y, fishes):
                game_over = True

            update_spawn()

            for data in abilities.values():
                if data["cooldown"] > 0:
                    data["cooldown"] -= 1
            if invulnerable_timer > 0:
                invulnerable_timer -= 1

            turn_state = 'player'
            player_moved_this_turn = False
            turn_count += 1

        if not game_over and turn_state == 'player' and player_moved_this_turn and not double_turn_active:
            turn_state = 'enemies'

        for row in range(GRID_SIZE):
            for col in range(GRID_SIZE):
                rect = pygame.Rect(col * CELL_SIZE, row * CELL_SIZE, CELL_SIZE, CELL_SIZE)
                if (row + col) % 2 == 0:
                    pygame.draw.rect(screen, FISH_LIGHT_BLUE, rect)
                else:
                    pygame.draw.rect(screen, FISH_DARK_BLUE, rect)
                pygame.draw.rect(screen, BLACK, rect, 1)

        for fish in fishes:
            fish.draw(screen)

        draw_bird(screen, bird_x, bird_y, True)

        y = 10
        ru_names = {
            "swallow": "Ласточка",
            "swordfish": "Меч",
            "shark": "Акула",
            "octopus": "РћСЃСЊРјРёРЅРѕРі"
        }
        for fish_type in FISH_INFO_ORDERED:
            if killed_counts[fish_type] > 0:
                name = ru_names.get(fish_type, fish_type)
                text = small_font.render(f"{name}: {killed_counts[fish_type]}", True, FISH_INFO[fish_type]["color"])
                screen.blit(text, (10, y))
                y += 22

        ability_y = 10
        for name, data in abilities.items():
            info = next((a for a in ABILITY_INFO if a["name"] == name), None)
            if info:
                key_str = f"[{info['key']}]"
                status = f"{data['uses']}/{data['max_uses']}"
                if data["cooldown"] > 0:
                    status += f" (РљР” {data['cooldown']})"
                text = micro_font.render(f"{key_str} {name}: {status}", True, BLACK)
                screen.blit(text, (WIDTH - 250, ability_y))
                ability_y += 20
        if invulnerable_timer > 0:
            inv_text = micro_font.render(f"Неуязвимость: {invulnerable_timer}", True, (200, 0, 0))
            screen.blit(inv_text, (WIDTH - 250, ability_y))
            ability_y += 20

        if is_survival:
            record_text = micro_font.render(f"Рекорд ходов: {record_turns}", True, (0, 100, 0))
            screen.blit(record_text, (WIDTH - 250, ability_y))

        if game_over:
            if is_survival and turn_count > survival_records["fish"]:
                survival_records["fish"] = turn_count
                save_records(survival_records)

            overlay = pygame.Surface((WIDTH, HEIGHT))
            overlay.set_alpha(200)
            overlay.fill(BLACK)
            screen.blit(overlay, (0, 0))
            texts = [
                font.render("ПОРАЖЕНИЕ!", True, RED_SNAKE),
                small_font.render("R - рестарт | Q - выход", True, GREEN)
            ]
            y_text = HEIGHT // 2 - 40
            for text in texts:
                rect = text.get_rect(center=(WIDTH // 2, y_text))
                screen.blit(text, rect)
                y_text += 40

        pygame.display.flip()
        clock.tick(FPS)

# ---------------------- ПЕСОЧНИЦА ----------------------
sandbox_settings = {
    "style": 0,
    "enemies": {
        "snakes": {name: {"enabled": False} for name in SNAKE_INFO_ORDERED},
        "spiders": {name: {"enabled": False} for name in SPIDER_INFO_ORDERED},
        "slimes": {name: {"enabled": False} for name in SLIME_INFO_ORDERED},
        "insects": {name: {"enabled": False} for name in INSECT_INFO_ORDERED},
        "fish": {name: {"enabled": False} for name in FISH_INFO_ORDERED}
    }
}

sandbox_modifiers = {
    "paranoia": False,
    "mirages": False,
    "walls_are_lava": False,
    "god_of_torches": False,
    "sociophobia": False,
    "xenos": False
}

MODIFIERS_INFO = {
    "paranoia": "Паранойя: каждый ход на месте прошлого положения героя появляется чёрная птица.",
    "mirages": "Миражи: иногда появляются копии игрока, повторяющие его движение 5-10 ходов.",
    "walls_are_lava": "Стены — это лава: по краям поля в начале появляются клетки лавы (длина 3 от каждой стены)",
    "god_of_torches": "Бог факелов: из краёв карты вылетают красные шары.",
    "sociophobia": "Социофобия: врагов спавнится значительно больше.",
    "xenos": "Ксеносы: в начале игры в каждом углу карты появляются бессмертные муравейники, спавнящие муравьёв в 2 раза медленнее."
}

def show_sandbox_modifiers():
    global current_state, sandbox_modifiers
    selected = sandbox_modifiers.copy()

    def save_and_return():
        nonlocal selected
        global current_state
        sandbox_modifiers.update(selected)
        current_state = "sandbox_menu"

    back_button = Button(WIDTH // 2 - 100, HEIGHT - 70, 200, 50, "Назад", action=save_and_return)

    while current_state == "sandbox_modifiers":
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                sys.exit()
            elif event.type == pygame.MOUSEBUTTONDOWN:
                if event.button == 1:
                    mouse_x, mouse_y = event.pos
                    for i, (key, _) in enumerate(MODIFIERS_INFO.items()):
                        rect = pygame.Rect(WIDTH // 2 - 300, 150 + i * 50, 30, 30)
                        if rect.collidepoint(mouse_x, mouse_y):
                            selected[key] = not selected[key]
            back_button.handle_event(event)

        screen.fill(MENU_BG)
        title = font.render("Выберите усложнения", True, BLACK)
        screen.blit(title, (WIDTH // 2 - title.get_width() // 2, 50))

        y = 150
        for i, (key, desc) in enumerate(MODIFIERS_INFO.items()):
            row_rect = pygame.Rect(WIDTH // 2 - 320, y, 640, 45)
            pygame.draw.rect(screen, (220, 220, 220), row_rect, border_radius=5)
            cb_rect = pygame.Rect(WIDTH // 2 - 300, y + 8, 30, 30)
            pygame.draw.rect(screen, BLACK, cb_rect, 2)
            if selected[key]:
                pygame.draw.line(screen, BLACK, (cb_rect.left + 4, cb_rect.centery),
                                 (cb_rect.centerx, cb_rect.bottom - 4), 4)
                pygame.draw.line(screen, BLACK, (cb_rect.centerx, cb_rect.bottom - 4),
                                 (cb_rect.right - 4, cb_rect.top + 4), 4)
            name_surf = small_font.render(key.replace('_', ' ').capitalize(), True, BLACK)
            screen.blit(name_surf, (WIDTH // 2 - 250, y + 12))
            desc_surf = micro_font.render(desc, True, (50, 50, 50))
            screen.blit(desc_surf, (WIDTH // 2 - 250, y + 30))
            y += 50

        back_button.draw(screen)
        pygame.display.flip()
        clock.tick(FPS)

def show_sandbox_arena_selection():
    global current_state, sandbox_settings
    style = sandbox_settings["style"]
    back_button = Button(WIDTH // 2 - 100, HEIGHT - 70, 200, 50, "Назад", action=lambda: go_to_sandbox_menu())
    styles = ["Змеи", "Пауки", "Слизни", "Насекомые", "Рыбы"]
    style_buttons = []
    for i, name in enumerate(styles):
        btn = Button(WIDTH // 2 - 100, 150 + i * 60, 200, 50, name,
                     action=lambda idx=i: set_style(idx))
        style_buttons.append(btn)

    def set_style(idx):
        nonlocal style
        style = idx
        sandbox_settings["style"] = style

    while current_state == "sandbox_arena":
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                sys.exit()
            back_button.handle_event(event)
            for btn in style_buttons:
                btn.handle_event(event)

        screen.fill(MENU_BG)
        title = font.render("Выберите арену", True, BLACK)
        screen.blit(title, (WIDTH // 2 - title.get_width() // 2, 50))
        for btn in style_buttons:
            btn.draw(screen)
        back_button.draw(screen)
        pygame.display.flip()

def show_sandbox_menu():
    global current_state
    back_button = Button(WIDTH // 2 - 100, HEIGHT - 70, 200, 50, "Назад", action=go_to_mode_select)
    settings_button = Button(WIDTH // 2 - 100, 150, 200, 50, "Настройки врагов",
                             action=lambda: go_to_sandbox_settings())
    modifiers_button = Button(WIDTH // 2 - 100, 220, 200, 50, "Усложнения",
                              action=lambda: go_to_sandbox_modifiers())
    arena_button = Button(WIDTH // 2 - 100, 290, 200, 50, "Выбор арены",
                          action=lambda: go_to_sandbox_arena())
    play_button = Button(WIDTH // 2 - 100, HEIGHT - 190, 200, 50, "Играть",
                         action=lambda: start_sandbox_play(sandbox_settings["style"]))

    while current_state == "sandbox_menu":
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                sys.exit()
            back_button.handle_event(event)
            settings_button.handle_event(event)
            modifiers_button.handle_event(event)
            arena_button.handle_event(event)
            play_button.handle_event(event)

        screen.fill(MENU_BG)
        settings_button.draw(screen)
        modifiers_button.draw(screen)
        arena_button.draw(screen)
        play_button.draw(screen)
        back_button.draw(screen)
        pygame.display.flip()

def go_to_sandbox_settings():
    global current_state
    current_state = "sandbox_settings"

def go_to_sandbox_modifiers():
    global current_state
    current_state = "sandbox_modifiers"

def go_to_sandbox_arena():
    global current_state
    current_state = "sandbox_arena"

def show_sandbox_settings():
    global current_state
    back_button = Button(WIDTH // 2 - 100, HEIGHT - 70, 200, 50, "Назад", action=lambda: go_to_sandbox_menu())

    def randomize_enemies():
        for cat_key in sandbox_settings["enemies"]:
            for name in sandbox_settings["enemies"][cat_key]:
                sandbox_settings["enemies"][cat_key][name]["enabled"] = random.choice([True, False])

    random_button = Button(WIDTH - 250, HEIGHT - 70, 200, 50, "Случайные враги", action=randomize_enemies)

    categories = {
        "Змеи": ("snakes", SNAKE_INFO_ORDERED),
        "Паук": ("spiders", SPIDER_INFO_ORDERED),
        "Слизни": ("slimes", SLIME_INFO_ORDERED),
        "Насекомые": ("insects", INSECT_INFO_ORDERED),
        "Рыбы": ("fish", FISH_INFO_ORDERED)
    }

    y_offset = 100
    item_height = 35
    scroll_offset = 0

    enemy_list = []
    for cat_name, (cat_key, enemies) in categories.items():
        enemy_list.append(("cat", cat_name))
        for enemy in enemies:
            enemy_list.append(("enemy", cat_key, enemy))

    total_height = len(enemy_list) * item_height
    max_scroll = max(0, total_height - (HEIGHT - 200))

    while current_state == "sandbox_settings":
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                sys.exit()
            elif event.type == pygame.MOUSEBUTTONDOWN:
                if event.button == 1:
                    mouse_x, mouse_y = event.pos
                    adjusted_y = mouse_y - y_offset + scroll_offset
                    idx = adjusted_y // item_height
                    if 0 <= idx < len(enemy_list):
                        item = enemy_list[idx]
                        if item[0] == "enemy":
                            cat_key, name = item[1], item[2]
                            item_rect = pygame.Rect(50, y_offset + idx * item_height - scroll_offset, WIDTH - 100,
                                                    item_height)
                            if 100 <= mouse_x <= 130 and item_rect.top <= mouse_y <= item_rect.bottom:
                                current_val = sandbox_settings["enemies"][cat_key][name]["enabled"]
                                sandbox_settings["enemies"][cat_key][name]["enabled"] = not current_val
                elif event.button == 4:
                    scroll_offset = max(0, scroll_offset - 20)
                elif event.button == 5:
                    scroll_offset = min(max_scroll, scroll_offset + 20)
            elif event.type == pygame.KEYDOWN:
                if event.key == pygame.K_ESCAPE:
                    current_state = "sandbox_menu"
                    return
            back_button.handle_event(event)
            random_button.handle_event(event)

        screen.fill(MENU_BG)
        title = font.render("Выберите врагов для песочницы", True, BLACK)
        screen.blit(title, (WIDTH // 2 - title.get_width() // 2, 30))

        current_y = y_offset - scroll_offset
        for item in enemy_list:
            if item[0] == "cat":
                pygame.draw.rect(screen, (200, 200, 200), (50, current_y, WIDTH - 100, item_height))
                cat_text = font.render(item[1], True, BLACK)
                screen.blit(cat_text, (70, current_y + 5))
            else:
                cat_key, name = item[1], item[2]
                enabled = sandbox_settings["enemies"][cat_key][name]["enabled"]
                row_color = (240, 240, 240) if enabled else (220, 220, 220)
                pygame.draw.rect(screen, row_color, (50, current_y, WIDTH - 100, item_height))

                ru_names = {
                    "green": "Зелёная", "dark_green": "Тёмно-зелёная", "bright_green": "Ярко-зелёная",
                    "stripe_green": "Полосатая зелёная", "swamp_green": "Болотная",
                    "blue": "Синяя", "dark_blue": "Тёмно-синяя", "light_blue": "Светло-синяя",
                    "stripe_blue": "Полосатая синяя", "pink_azure": "Розово-лазурная",
                    "white": "Белая", "white_purple": "Бело-фиолетовая", "white_red": "Бело-красная",
                    "red": "Красная", "black": "Чёрная", "rainbow_snake": "Радужная", "white_gray": "Бело-серая",
                    "light_gray": "Светло-серый паук", "brown_gray": "Коричнево-серый паук",
                    "dark_gray_red_cross": "Тёмно-серый с крестом", "dark_gray_green_circle": "Тёмно-серый с кругом",
                    "dark_red": "Тёмно-красный", "big_dark_gray": "Большой тёмно-серый",
                    "big_dark_gray_green_circle": "Большой с зелёным кругом", "black_spider": "Чёрный паук",
                    "white_purple_circle": "Белый с фиолетовым", "rainbow_spider": "Радужный паук",
                    "green_slime_jump1": "Зелёный прыгун 1", "green_slime_jump2": "Зелёный прыгун 2",
                    "dark_green_slime": "Тёмно-зелёный слизень", "red_slime": "Красный слизень",
                    "purple_blue_slime": "Фиолетово-синий",
                    "black_slime": "Чёрный слизень", "dark_gray_slime": "Тёмно-серый слизень",
                    "light_gray_slime": "Светло-серый слизень", "white_slime": "Белый слизень",
                    "rainbow_slime": "Радужный слизень", "bright_orange_slime": "Ярко-оранжевый слизень",
                    "yellow_slime": "Жёлтый слизень",
                    "ant": "Муравей", "dung_beetle": "Навозник", "stag_beetle": "Рогач", "anthill": "Муравейник",
                    "swallow": "Рыба-ласточка", "swordfish": "Рыба-меч", "shark": "Акула", "octopus": "Осьминог"
                }
                display_name = ru_names.get(name, name.replace('_', ' ').capitalize())
                name_surf = small_font.render(display_name, True, BLACK)
                screen.blit(name_surf, (150, current_y + 5))

                checkbox_rect = pygame.Rect(100, current_y + 5, 20, 20)
                pygame.draw.rect(screen, BLACK, checkbox_rect, 2)
                if enabled:
                    pygame.draw.line(screen, BLACK, (checkbox_rect.left + 2, checkbox_rect.centery),
                                     (checkbox_rect.centerx, checkbox_rect.bottom - 2), 3)
                    pygame.draw.line(screen, BLACK, (checkbox_rect.centerx, checkbox_rect.bottom - 2),
                                     (checkbox_rect.right - 2, checkbox_rect.top + 2), 3)

            current_y += item_height

        if total_height > HEIGHT - 200:
            scroll_bar_height = (HEIGHT - 200) * (HEIGHT - 200) / total_height
            scroll_bar_y = y_offset + (scroll_offset / max_scroll) * (HEIGHT - 200 - scroll_bar_height)
            pygame.draw.rect(screen, (100, 100, 100), (WIDTH - 20, y_offset, 10, HEIGHT - 200))
            pygame.draw.rect(screen, (50, 50, 50), (WIDTH - 20, scroll_bar_y, 10, scroll_bar_height))

        back_button.draw(screen)
        random_button.draw(screen)
        pygame.display.flip()
        clock.tick(FPS)

def start_sandbox_play(style):
    global current_state, game_mode
    sandbox_settings["style"] = style
    game_mode = "sandbox"
    current_state = "ability_selection"

def show_sandbox_play():
    global current_state
    abilities = selected_abilities.copy()
    for name, data in abilities.items():
        data["cooldown"] = 0
        data["uses"] = data["max_uses"]

    style = sandbox_settings["style"]
    bird_x, bird_y = GRID_SIZE // 2, GRID_SIZE // 2
    last_direction = 'up'

    snakes = []
    fireballs = []
    spiders = []
    shadows = []
    spider_fireballs = []
    gas_clouds = []
    slimes = []
    slime_balls = []
    slime_gas_clouds = []
    invisible_clouds = []
    lava_cells_temp = []
    ants = []
    beetles = []
    anthills = []
    insect_shadows = []
    poison_clouds = []
    fishes = []

    turn_state = 'player'
    player_moved_this_turn = False
    game_over = False
    invulnerable_timer = 0
    double_turn_active = False
    moves_in_turn = 0

    last_bird_pos = (bird_x, bird_y)
    black_birds = set()
    mirages = []
    torch_cooldown = 0
    lava_cells_wall = set()

    if sandbox_modifiers.get("walls_are_lava", False):
        lava_cells_wall = set()
        for x in range(GRID_SIZE):
            for y in range(3):
                lava_cells_wall.add((x, y))
                lava_cells_wall.add((x, GRID_SIZE - 1 - y))
        for y in range(GRID_SIZE):
            for x in range(3):
                lava_cells_wall.add((x, y))
                lava_cells_wall.add((GRID_SIZE - 1 - x, y))

    immortal_anthills = []
    if sandbox_modifiers.get("xenos", False):
        corners = [(0, 0), (GRID_SIZE-3, 0), (0, GRID_SIZE-3), (GRID_SIZE-3, GRID_SIZE-3)]
        for cx, cy in corners:
            ah = Anthill(cx, cy)
            ah.spawn_interval = 8
            immortal_anthills.append(ah)

    def check_modifiers_collision(x, y):
        if (x, y) in black_birds:
            return True
        if (x, y) in lava_cells_wall:
            return True
        for lava in lava_cells_temp:
            if lava.active and lava.get_pos() == (x, y):
                return True
        return False

    def get_spawn_chance():
        base = 0.25
        if sandbox_modifiers.get("sociophobia", False):
            base *= 1.8
        return min(base, 0.6)

    def update_mirages():
        nonlocal mirages
        new_mirages = []
        for mx, my, life, path in mirages:
            life -= 1
            if life > 0:
                if len(path) > 0:
                    next_pos = path.pop(0)
                    new_mirages.append((next_pos[0], next_pos[1], life, path))
        mirages = new_mirages

    player_path = deque(maxlen=10)

    def create_mirage_from_path():
        if len(player_path) < 2:
            return
        start_pos = player_path[-1]
        n = random.randint(5, min(10, len(player_path)))
        path = list(player_path)[-n-1:-1]
        if path:
            mirages.append((start_pos[0], start_pos[1], len(path), path))

    def spawn_black_bird():
        if not sandbox_modifiers.get("paranoia", False):
            return
        nonlocal black_birds
        black_birds.clear()
        black_birds.add(last_bird_pos)

    def spawn_torch_fireballs():
        if not sandbox_modifiers.get("god_of_torches", False):
            return
        nonlocal torch_cooldown
        if torch_cooldown <= 0:
            if random.random() < 0.4:
                side = random.choice(['top', 'bottom', 'left', 'right'])
                if side == 'top':
                    x = random.randint(0, GRID_SIZE-1)
                    y = 0
                    dy = 1
                    dx = 0
                elif side == 'bottom':
                    x = random.randint(0, GRID_SIZE-1)
                    y = GRID_SIZE-1
                    dy = -1
                    dx = 0
                elif side == 'left':
                    x = 0
                    y = random.randint(0, GRID_SIZE-1)
                    dx = 1
                    dy = 0
                else:
                    x = GRID_SIZE-1
                    y = random.randint(0, GRID_SIZE-1)
                    dx = -1
                    dy = 0
                fireballs.append(Fireball(x, y, dx, dy, speed=1, color=(255, 69, 0)))
                torch_cooldown = 3
        else:
            torch_cooldown -= 1

    while current_state == "sandbox_play":
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                current_state = "menu"
                return
            elif event.type == pygame.KEYDOWN and not game_over:
                if turn_state == 'player' and not player_moved_this_turn:
                    if event.key == pygame.K_7 and "Метод скипа" in abilities:
                        data = abilities["Метод скипа"]
                        if data["cooldown"] == 0 and data["uses"] > 0:
                            data["uses"] -= 1
                            data["cooldown"] = data["max_cooldown"]
                            player_moved_this_turn = True
                    elif event.key == pygame.K_1 and "Гэмблинг" in abilities:
                        data = abilities["Гэмблинг"]
                        if data["cooldown"] == 0 and data["uses"] > 0:
                            occupied = set()
                            for snake in snakes:
                                occupied.update(snake.get_all_positions())
                            for fb in fireballs:
                                if fb.active:
                                    occupied.add((fb.x, fb.y))
                            for spider in spiders:
                                occupied.update(spider.get_positions())
                            for sh in shadows:
                                for i in range(sh.size):
                                    for j in range(sh.size):
                                        occupied.add((sh.x + i, sh.y + j))
                            for fb2 in spider_fireballs:
                                occupied.update(fb2.get_positions())
                            for gc in gas_clouds:
                                occupied.update(gc.get_affected_cells())
                            for slime in slimes:
                                occupied.add(slime.get_pos())
                            for ball in slime_balls:
                                if ball.active:
                                    occupied.add((ball.x, ball.y))
                            for gc2 in slime_gas_clouds:
                                occupied.update(gc2.get_affected_cells())
                            for ic in invisible_clouds:
                                occupied.update(ic.get_affected_cells())
                            for lava in lava_cells_temp:
                                if lava.active:
                                    occupied.add((lava.x, lava.y))
                            for ant in ants:
                                occupied.add(ant.get_pos())
                            for beetle in beetles:
                                occupied.add(beetle.get_pos())
                            for ah in anthills + immortal_anthills:
                                occupied.update(ah.get_positions())
                            for sh in insect_shadows:
                                for i in range(sh.size):
                                    for j in range(sh.size):
                                        occupied.add((sh.x + i, sh.y + j))
                            for pc in poison_clouds:
                                occupied.add(pc.get_pos())
                            for fish in fishes:
                                if not fish.underwater:
                                    occupied.update(fish.get_positions())
                                if isinstance(fish, Octopus) and not fish.underwater:
                                    occupied.update(fish.tentacles)
                            occupied.update(black_birds)
                            for mx, my, _, _ in mirages:
                                occupied.add((mx, my))
                            occupied.update(lava_cells_wall)
                            free_cells = [(x, y) for x in range(GRID_SIZE) for y in range(GRID_SIZE) if
                                          (x, y) not in occupied]
                            if free_cells:
                                bird_x, bird_y = random.choice(free_cells)
                                data["uses"] -= 1
                                data["cooldown"] = data["max_cooldown"]
                                player_moved_this_turn = True
                                if invulnerable_timer <= 0 and (check_collision(bird_x, bird_y, snakes, fireballs, invisible_clouds) or
                                                                check_collision_spider(bird_x, bird_y, spiders,
                                                                                       spider_fireballs, gas_clouds) or
                                                                check_collision_slime(bird_x, bird_y, slimes,
                                                                                      slime_balls, slime_gas_clouds,
                                                                                      invisible_clouds, lava_cells_temp) or
                                                                check_collision_insect(bird_x, bird_y, ants, beetles, anthills + immortal_anthills, poison_clouds, invisible_clouds) or
                                                                check_collision_fish(bird_x, bird_y, fishes) or
                                                                check_modifiers_collision(bird_x, bird_y)):
                                    game_over = True
                    elif event.key == pygame.K_2 and "Освежитель" in abilities:
                        data = abilities["Освежитель"]
                        if data["cooldown"] == 0 and data["uses"] > 0:
                            for gc in gas_clouds[:]:
                                if abs(gc.x - bird_x) <= 3 and abs(gc.y - bird_y) <= 3:
                                    gas_clouds.remove(gc)
                            for gc2 in slime_gas_clouds[:]:
                                if abs(gc2.x - bird_x) <= 3 and abs(gc2.y - bird_y) <= 3:
                                    slime_gas_clouds.remove(gc2)
                            for ic in invisible_clouds[:]:
                                if abs(ic.x - bird_x) <= 3 and abs(ic.y - bird_y) <= 3:
                                    invisible_clouds.remove(ic)
                            for pc in poison_clouds[:]:
                                if abs(pc.x - bird_x) <= 3 and abs(pc.y - bird_y) <= 3:
                                    poison_clouds.remove(pc)
                            data["uses"] -= 1
                            data["cooldown"] = data["max_cooldown"]
                    elif event.key == pygame.K_3 and "Айсаир" in abilities:
                        data = abilities["Айсаир"]
                        if data["cooldown"] == 0 and data["uses"] > 0:
                            all_fireballs = fireballs + spider_fireballs + slime_balls
                            for fb in all_fireballs[:]:
                                if abs(fb.x - bird_x) + abs(fb.y - bird_y) <= 3:
                                    if fb.color == PURPLE_FIRE:
                                        fb.color = (255, 69, 0)
                                        fb.speed = 1
                                    elif fb.color == (255, 69, 0):
                                        if isinstance(fb, SlimeBall):
                                            fb.color = (100, 255, 100, 200)
                                        else:
                                            fb.color = (100, 255, 100)
                                        fb.speed = 0.5
                                    elif fb.color in [(100, 255, 100), (100, 255, 100, 200)]:
                                        fb.active = False
                            data["uses"] -= 1
                            data["cooldown"] = data["max_cooldown"]
                    elif event.key == pygame.K_4 and "Мощные крылья" in abilities:
                        data = abilities["Мощные крылья"]
                        if data["cooldown"] == 0 and data["uses"] > 0:
                            dx, dy = 0, 0
                            if last_direction == 'up':
                                dy = -3
                            elif last_direction == 'down':
                                dy = 3
                            elif last_direction == 'left':
                                dx = -3
                            elif last_direction == 'right':
                                dx = 3
                            new_x = max(0, min(GRID_SIZE - 1, bird_x + dx))
                            new_y = max(0, min(GRID_SIZE - 1, bird_y + dy))
                            bird_x, bird_y = new_x, new_y
                            data["uses"] -= 1
                            data["cooldown"] = data["max_cooldown"]
                            player_moved_this_turn = True
                            if invulnerable_timer <= 0 and (check_collision(bird_x, bird_y, snakes, fireballs, invisible_clouds) or
                                                            check_collision_spider(bird_x, bird_y, spiders,
                                                                                   spider_fireballs, gas_clouds) or
                                                            check_collision_slime(bird_x, bird_y, slimes, slime_balls,
                                                                                  slime_gas_clouds, invisible_clouds, lava_cells_temp) or
                                                            check_collision_insect(bird_x, bird_y, ants, beetles, anthills + immortal_anthills, poison_clouds, invisible_clouds) or
                                                            check_collision_fish(bird_x, bird_y, fishes) or
                                                            check_modifiers_collision(bird_x, bird_y)):
                                game_over = True
                    elif event.key == pygame.K_5 and "Ремнант" in abilities:
                        data = abilities["Ремнант"]
                        if data["cooldown"] == 0 and data["uses"] > 0:
                            invulnerable_timer = 4
                            data["uses"] -= 1
                            data["cooldown"] = data["max_cooldown"]
                    elif event.key == pygame.K_6 and "The world" in abilities:
                        data = abilities["The world"]
                        if data["cooldown"] == 0 and data["uses"] > 0:
                            double_turn_active = True
                            moves_in_turn = 0
                            data["uses"] -= 1
                            data["cooldown"] = data["max_cooldown"]

                    if not player_moved_this_turn:
                        old_x, old_y = bird_x, bird_y
                        if event.key == pygame.K_w and bird_y > 0:
                            bird_y -= 1
                            last_direction = 'up'
                        elif event.key == pygame.K_s and bird_y < GRID_SIZE - 1:
                            bird_y += 1
                            last_direction = 'down'
                        elif event.key == pygame.K_a and bird_x > 0:
                            bird_x -= 1
                            last_direction = 'left'
                        elif event.key == pygame.K_d and bird_x < GRID_SIZE - 1:
                            bird_x += 1
                            last_direction = 'right'
                        if (bird_x, bird_y) != (old_x, old_y):
                            player_moved_this_turn = True
                            if invulnerable_timer <= 0 and (check_collision(bird_x, bird_y, snakes, fireballs, invisible_clouds) or
                                                            check_collision_spider(bird_x, bird_y, spiders,
                                                                                   spider_fireballs, gas_clouds) or
                                                            check_collision_slime(bird_x, bird_y, slimes, slime_balls,
                                                                                  slime_gas_clouds, invisible_clouds, lava_cells_temp) or
                                                            check_collision_insect(bird_x, bird_y, ants, beetles, anthills + immortal_anthills, poison_clouds, invisible_clouds) or
                                                            check_collision_fish(bird_x, bird_y, fishes) or
                                                            check_modifiers_collision(bird_x, bird_y)):
                                game_over = True

                    if double_turn_active and player_moved_this_turn:
                        moves_in_turn += 1
                        if moves_in_turn >= 2:
                            double_turn_active = False
                            turn_state = 'snakes'
                        else:
                            player_moved_this_turn = False
                    elif player_moved_this_turn:
                        turn_state = 'snakes'
            elif event.type == pygame.KEYDOWN and game_over:
                if event.key == pygame.K_r:
                    show_sandbox_play()
                    return
                elif event.key == pygame.K_q:
                    current_state = "menu"
                    return

        if not game_over and turn_state == 'snakes':
            for snake in snakes[:]:
                snake.move(bird_x, bird_y, fireballs, invisible_clouds)
                if snake.is_completely_off_grid():
                    snakes.remove(snake)

            for fb in fireballs[:]:
                fb.move()
                if not fb.active:
                    fireballs.remove(fb)

            new_spiders = []
            for shadow in shadows[:]:
                if shadow.update():
                    spider = Spider(shadow.x, shadow.y, shadow.spider_type)
                    if shadow.spider_type == "dark_gray_red_cross":
                        cx, cy = shadow.x, shadow.y
                        for dx, dy in [(1, 0), (-1, 0), (0, 1), (0, -1)]:
                            spider_fireballs.append(SpiderFireball(cx + dx, cy + dy, dx, dy, speed=1))
                    elif shadow.spider_type == "white_purple_circle":
                        cx = shadow.x + shadow.size // 2
                        cy = shadow.y + shadow.size // 2
                        for dx, dy in [(1, 0), (-1, 0), (0, 1), (0, -1)]:
                            spider_fireballs.append(SpiderFireball(cx, cy, dx, dy, speed=2, length=1, color=PURPLE_FIRE))
                            spider_fireballs.append(SpiderFireball(cx + dx, cy + dy, dx, dy, speed=2, length=1, color=PURPLE_FIRE))
                    elif shadow.spider_type == "rainbow_spider":
                        spider.shoot_rainbow(spider_fireballs)
                    new_spiders.append(spider)
                    shadows.remove(shadow)
            spiders.extend(new_spiders)

            for spider in spiders[:]:
                spider.update(spider_fireballs, gas_clouds, bird_x, bird_y)
                if not spider.active:
                    spiders.remove(spider)

            for fb in spider_fireballs[:]:
                fb.move()
                if not fb.active:
                    spider_fireballs.remove(fb)

            for gc in gas_clouds[:]:
                gc.update()
                if not gc.active:
                    gas_clouds.remove(gc)

            new_slimes = []
            for slime in slimes[:]:
                slime.update(slime_balls, slime_gas_clouds, invisible_clouds, new_slimes, lava_cells_temp)
                if not slime.active:
                    slimes.remove(slime)
            slimes.extend(new_slimes)

            for ball in slime_balls[:]:
                ball.update()
                if not ball.active:
                    slime_balls.remove(ball)

            for gc in slime_gas_clouds[:]:
                gc.update()
                if not gc.active:
                    slime_gas_clouds.remove(gc)

            for ic in invisible_clouds[:]:
                ic.update()
                if not ic.active:
                    invisible_clouds.remove(ic)

            for lava in lava_cells_temp[:]:
                lava.update()
                if not lava.active:
                    lava_cells_temp.remove(lava)

            new_anthills = []
            for shadow in insect_shadows[:]:
                if shadow.update():
                    if shadow.insect_type == "anthill":
                        ah = Anthill(shadow.x, shadow.y)
                        new_anthills.append(ah)
                    insect_shadows.remove(shadow)
            anthills.extend(new_anthills)

            for ant in ants[:]:
                ant.update(bird_x, bird_y, poison_clouds, invisible_clouds)
                if not ant.active:
                    ants.remove(ant)

            for beetle in beetles[:]:
                if isinstance(beetle, DungBeetle):
                    beetle.update(bird_x, bird_y, poison_clouds)
                elif isinstance(beetle, StagBeetle):
                    beetle.update(bird_x, bird_y, invisible_clouds)
                if not beetle.active:
                    beetles.remove(beetle)

            for ah in anthills[:]:
                ah.update(ants)
                if not ah.active:
                    anthills.remove(ah)

            for pc in poison_clouds[:]:
                pc.update()
                if not pc.active:
                    poison_clouds.remove(pc)

            for fish in fishes[:]:
                fish.update(bird_x, bird_y, fishes)
                if not fish.active:
                    fishes.remove(fish)

            for ah in immortal_anthills:
                ah.timer += 1
                if ah.timer % 8 == 0:
                    possible_positions = []
                    for dx in range(-1, ah.size+1):
                        for dy in range(-1, ah.size+1):
                            nx = ah.x + dx
                            ny = ah.y + dy
                            if (dx < 0 or dx >= ah.size or dy < 0 or dy >= ah.size):
                                if 0 <= nx < GRID_SIZE and 0 <= ny < GRID_SIZE:
                                    possible_positions.append((nx, ny))
                    if possible_positions:
                        sx, sy = random.choice(possible_positions)
                        direction = random.choice(['up', 'down', 'left', 'right'])
                        ants.append(Ant(sx, sy, direction))

            spawn_chance = get_spawn_chance()
            total_enemies = len(snakes) + len(spiders) + len(shadows) + len(slimes) + len(ants) + len(beetles) + len(anthills) + len(insect_shadows) + len(fishes)
            if total_enemies < 15 and random.random() < spawn_chance:
                enabled = []
                for name, data in sandbox_settings["enemies"]["snakes"].items():
                    if data["enabled"]:
                        enabled.append(("snake", name))
                for name, data in sandbox_settings["enemies"]["spiders"].items():
                    if data["enabled"]:
                        enabled.append(("spider", name))
                for name, data in sandbox_settings["enemies"]["slimes"].items():
                    if data["enabled"]:
                        enabled.append(("slime", name))
                for name, data in sandbox_settings["enemies"]["insects"].items():
                    if data["enabled"]:
                        enabled.append(("insect", name))
                for name, data in sandbox_settings["enemies"]["fish"].items():
                    if data["enabled"]:
                        enabled.append(("fish", name))
                if enabled:
                    enemy_type, name = random.choice(enabled)
                    if enemy_type == "snake":
                        new_snake = create_snake_at_edge(name)
                        collision = any(new_snake.get_all_positions() & s.get_all_positions() for s in snakes)
                        if not collision:
                            snakes.append(new_snake)
                    elif enemy_type == "spider":
                        info = SPIDER_INFO[name]
                        size = info["size"]
                        max_attempts = 50
                        for _ in range(max_attempts):
                            x = random.randint(0, GRID_SIZE - size)
                            y = random.randint(0, GRID_SIZE - size)
                            occupied = set()
                            for s in spiders:
                                occupied.update(s.get_positions())
                            for sh in shadows:
                                for i in range(sh.size):
                                    for j in range(sh.size):
                                        occupied.add((sh.x + i, sh.y + j))
                            collision = False
                            for i in range(size):
                                for j in range(size):
                                    if (x + i, y + j) in occupied:
                                        collision = True
                                        break
                                if collision:
                                    break
                            if not collision:
                                shadows.append(Shadow(x, y, size, info["fall_time"], name))
                                break
                    elif enemy_type == "slime":
                        new_slime = spawn_slime(name, lava_cells_list=lava_cells_temp)
                        collision = any(new_slime.get_pos() == s.get_pos() for s in slimes)
                        if not collision:
                            slimes.append(new_slime)
                    elif enemy_type == "insect":
                        if name == "anthill":
                            for _ in range(50):
                                tx = random.randint(1, GRID_SIZE - 4)
                                ty = random.randint(1, GRID_SIZE - 4)
                                new_ah = Anthill(tx, ty)
                                collision = False
                                for ah in anthills:
                                    if new_ah.get_positions() & ah.get_positions():
                                        collision = True
                                        break
                                for sh in insect_shadows:
                                    for i in range(sh.size):
                                        for j in range(sh.size):
                                            if (sh.x + i, sh.y + j) in new_ah.get_positions():
                                                collision = True
                                                break
                                if not collision:
                                    insect_shadows.append(InsectShadow(tx, ty, 3, 5, "anthill"))
                                    break
                        else:
                            obj = spawn_insect(name)
                            if name == "ant":
                                ants.append(obj)
                            else:
                                beetles.append(obj)
                    elif enemy_type == "fish":
                        new_fish = spawn_fish(name)
                        fishes.append(new_fish)

            spawn_black_bird()
            if sandbox_modifiers.get("mirages", False):
                if random.random() < 0.05:
                    create_mirage_from_path()
            update_mirages()
            spawn_torch_fireballs()

            if invulnerable_timer <= 0 and (check_collision(bird_x, bird_y, snakes, fireballs, invisible_clouds) or
                                            check_collision_spider(bird_x, bird_y, spiders, spider_fireballs, gas_clouds) or
                                            check_collision_slime(bird_x, bird_y, slimes, slime_balls, slime_gas_clouds, invisible_clouds, lava_cells_temp) or
                                            check_collision_insect(bird_x, bird_y, ants, beetles, anthills + immortal_anthills, poison_clouds, invisible_clouds) or
                                            check_collision_fish(bird_x, bird_y, fishes) or
                                            check_modifiers_collision(bird_x, bird_y)):
                game_over = True

            last_bird_pos = (bird_x, bird_y)
            player_path.append((bird_x, bird_y))

            for data in abilities.values():
                if data["cooldown"] > 0:
                    data["cooldown"] -= 1
            if invulnerable_timer > 0:
                invulnerable_timer -= 1

            turn_state = 'player'
            player_moved_this_turn = False

        if not game_over and turn_state == 'player' and player_moved_this_turn and not double_turn_active:
            turn_state = 'snakes'

        for row in range(GRID_SIZE):
            for col in range(GRID_SIZE):
                rect = pygame.Rect(col * CELL_SIZE, row * CELL_SIZE, CELL_SIZE, CELL_SIZE)
                if style == 0:
                    color1, color2 = GRAY, LIGHT_GRAY
                elif style == 1:
                    color1, color2 = (40, 40, 50), (30, 30, 40)
                elif style == 2:
                    color1, color2 = LIGHT_BLUE_CELL, LIGHT_PINK_CELL
                elif style == 3:
                    color1, color2 = SAND_INSECT_LIGHT, SAND_INSECT_DARK
                else:
                    color1, color2 = FISH_LIGHT_BLUE, FISH_DARK_BLUE
                if (row + col) % 2 == 0:
                    pygame.draw.rect(screen, color1, rect)
                else:
                    pygame.draw.rect(screen, color2, rect)
                if (col, row) in lava_cells_wall:
                    pygame.draw.rect(screen, (255, 69, 0), rect)
                pygame.draw.rect(screen, BLACK, rect, 1)

        for lava in lava_cells_temp:
            if lava.active:
                lava.draw(screen)

        for bx, by in black_birds:
            if 0 <= bx < GRID_SIZE and 0 <= by < GRID_SIZE:
                draw_bird(screen, bx, by, True, black_shadow=True)

        for mx, my, _, _ in mirages:
            if 0 <= mx < GRID_SIZE and 0 <= my < GRID_SIZE:
                draw_bird(screen, mx, my, True)

        for ic in invisible_clouds:
            ic.draw(screen)
        for gc in slime_gas_clouds:
            gc.draw(screen)
        for gc in gas_clouds:
            gc.draw(screen)
        for pc in poison_clouds:
            pc.draw(screen)

        for shadow in shadows:
            shadow.draw(screen)
        for spider in spiders:
            spider.draw(screen)
        for fb in spider_fireballs:
            fb.draw(screen)

        for snake in snakes:
            snake.draw(screen)
        for fb in fireballs:
            fb.draw(screen)

        for slime in slimes:
            slime.draw(screen, invisible_clouds)
        for ball in slime_balls:
            ball.draw(screen, invisible_clouds)

        for shadow in insect_shadows:
            shadow.draw(screen)
        for ah in anthills + immortal_anthills:
            ah.draw(screen)
        for beetle in beetles:
            beetle.draw(screen)
        for ant in ants:
            ant.draw(screen)

        for fish in fishes:
            fish.draw(screen)

        bird_visible = True
        for ic in invisible_clouds:
            if (bird_x, bird_y) in ic.get_affected_cells():
                bird_visible = False
                break
        draw_bird(screen, bird_x, bird_y, bird_visible)

        ability_y = 10
        for name, data in abilities.items():
            info = next((a for a in ABILITY_INFO if a["name"] == name), None)
            if info:
                key_str = f"[{info['key']}]"
                status = f"{data['uses']}/{data['max_uses']}"
                if data["cooldown"] > 0:
                    status += f" (РљР” {data['cooldown']})"
                text = micro_font.render(f"{key_str} {name}: {status}", True, BLACK)
                screen.blit(text, (WIDTH - 250, ability_y))
                ability_y += 20
        if invulnerable_timer > 0:
            inv_text = micro_font.render(f"Неуязвимость: {invulnerable_timer}", True, (200, 0, 0))
            screen.blit(inv_text, (WIDTH - 250, ability_y))

        if game_over:
            overlay = pygame.Surface((WIDTH, HEIGHT))
            overlay.set_alpha(200)
            overlay.fill(BLACK)
            screen.blit(overlay, (0, 0))
            texts = [
                font.render("ПОРАЖЕНИЕ!", True, RED_SNAKE),
                small_font.render("R - рестарт | Q - выход", True, GREEN)
            ]
            y_text = HEIGHT // 2 - 40
            for text in texts:
                rect = text.get_rect(center=(WIDTH // 2, y_text))
                screen.blit(text, rect)
                y_text += 40

        pygame.display.flip()
        clock.tick(FPS)
# ---------------------- МЕНЮ, БЕСТИАРИЙ, НАСТРОЙКИ ----------------------
def show_menu():
    global current_state
    buttons = [
        Button(WIDTH // 2 - 100, 150, 200, 50, "Выбор режима", action=lambda: go_to_mode_select()),
        Button(WIDTH // 2 - 100, 220, 200, 50, "Бестиарий", action=lambda: go_to_bestiary()),
        Button(WIDTH // 2 - 100, 290, 200, 50, "Управление", action=lambda: go_to_controls()),
        Button(WIDTH // 2 - 100, 360, 200, 50, "Выбрать скин", action=lambda: go_to_skin_select()),
        Button(WIDTH // 2 - 100, 430, 200, 50, "Настройки", action=lambda: go_to_settings()),
        Button(WIDTH // 2 - 100, 500, 200, 50, "Выход", action=exit_game)
    ]
    while current_state == "menu":
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                sys.exit()
            for button in buttons:
                button.handle_event(event)
        screen.fill(MENU_BG)
        title_text = font.render("Птичка против Врагов", True, BLACK)
        title_rect = title_text.get_rect(center=(WIDTH // 2, 80))
        screen.blit(title_text, title_rect)
        for button in buttons:
            button.draw(screen)
        pygame.display.flip()

def show_game_mode_selection():
    global current_state
    buttons = [
        Button(WIDTH // 2 - 100, 150, 200, 50, "РЈСЂРѕРІРЅРё", action=lambda: go_to_level_select()),
        Button(WIDTH // 2 - 100, 220, 200, 50, "Испытания", action=lambda: go_to_challenge_select()),
        Button(WIDTH // 2 - 100, 290, 200, 50, "Выживание", action=lambda: go_to_survival_select()),
        Button(WIDTH // 2 - 100, 360, 200, 50, "Песочница", action=lambda: go_to_sandbox_menu()),
        Button(WIDTH // 2 - 100, 430, 200, 50, "Назад", action=go_to_menu)
    ]
    while current_state == "mode_select":
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                sys.exit()
            for button in buttons:
                button.handle_event(event)
        screen.fill(MENU_BG)
        title_text = font.render("Выберите режим", True, BLACK)
        title_rect = title_text.get_rect(center=(WIDTH // 2, 80))
        screen.blit(title_text, title_rect)
        for button in buttons:
            button.draw(screen)
        pygame.display.flip()

def show_level_select():
    global current_state
    back_button = Button(WIDTH // 2 - 100, HEIGHT - 70, 200, 50, "Назад", action=go_to_mode_select)
    button_size = 70
    spacing = 15

    # Глава 1: Змеи (уровни 1-10)
    snake_title_y = 100
    snake_buttons = []
    for i in range(1, 11):
        row = (i-1) // 5
        col = (i-1) % 5
        x = 30 + col * (button_size + spacing)
        y = snake_title_y + 30 + row * (button_size + spacing)
        btn = Button(x, y, button_size, button_size, str(i),
                     action=lambda level=i: start_level(level),
                     color=(100, 150, 200), hover_color=(70, 120, 170))
        snake_buttons.append(btn)

    # Глава 2: Пауки (уровни 11-20)
    spider_title_y = snake_title_y + 2 * (button_size + spacing) + 50
    spider_buttons = []
    for i in range(11, 21):
        row = (i-11) // 5
        col = (i-11) % 5
        x = 30 + col * (button_size + spacing)
        y = spider_title_y + 30 + row * (button_size + spacing)
        btn = Button(x, y, button_size, button_size, str(i),
                     action=lambda level=i: start_level(level),
                     color=(100, 200, 150), hover_color=(70, 170, 120))
        spider_buttons.append(btn)

    while current_state == "level_select":
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                sys.exit()
            back_button.handle_event(event)
            for btn in snake_buttons + spider_buttons:
                btn.handle_event(event)

        screen.fill(MENU_BG)
        title = font.render("Выберите уровень", True, BLACK)
        screen.blit(title, (WIDTH // 2 - title.get_width() // 2, 30))

        chapter1 = small_font.render("Глава 1: Змеи (1-10)", True, (0, 80, 0))
        screen.blit(chapter1, (WIDTH // 2 - chapter1.get_width() // 2, snake_title_y))
        for btn in snake_buttons:
            btn.draw(screen)

        chapter2 = small_font.render("Глава 2: Пауки (11-20)", True, (0, 80, 0))
        screen.blit(chapter2, (WIDTH // 2 - chapter2.get_width() // 2, spider_title_y))
        for btn in spider_buttons:
            btn.draw(screen)

        back_button.draw(screen)
        pygame.display.flip()

def show_level_info(level):
    global current_state
    info = LEVEL_INFO[level]
    target_type = info["target_type"]
    target_text = ""
    if target_type == "kill":
        target_text = f"Цель: пережить {info['target_kills']} врагов."
    elif target_type == "collect_apples":
        target_text = f"Цель: собрать {info['target_apples']} яблок."
    elif target_type == "survive_turns":
        target_text = f"Цель: прожить {info['target_turns']} ходов."
    elif target_type == "visit_borders":
        target_text = "Цель: побывать на каждой стороне арены (верх, низ, лево, право)."
    elif target_type == "visit_corners":
        target_text = "Цель: посетить все 4 угла арены."
    elif target_type == "kill_and_collect":
        target_text = f"Цель: пережить {info['target_kills']} врагов и собрать {info['target_apples']} яблок."

    # Враги
    initial = info["initial_enemies"]
    ru_spider_names = {
        "light_gray": "Светло-серый паук",
        "brown_gray": "Коричнево-серый паук",
        "dark_gray_red_cross": "Огненный паук (с крестом)",
        "dark_gray_green_circle": "Газовый паук",
        "dark_red": "Красный паук (2x2)",
        "big_dark_gray": "Большой тёмно-серый паук",
        "big_dark_gray_green_circle": "Большой газовый паук",
        "black_spider": "Чёрный паук",
        "white_purple_circle": "Фиолетовый малый паук",
        "rainbow_spider": "Радужный паук"
    }
    enemies_desc = []
    for enemy_type, sub_type, count in initial:
        if enemy_type == "snake":
            name = RU_NAMES_SNAKES.get(sub_type, sub_type)
        elif enemy_type == "spider":
            name = ru_spider_names.get(sub_type, sub_type)
        else:
            name = sub_type
        enemies_desc.append(f"{name} x{count}")
    enemies_str = ", ".join(enemies_desc)

    # Модификаторы
    modifiers = info.get("modifiers", {})
    modifier_descriptions = {
        "god_of_torches": "Бог факелов: с краёв карты вылетают красные шары.",
        "walls_are_lava": "Стены — это лава: по краям поля лава.",
        "fog": "Туман: вы видите только область радиусом 7 клеток вокруг птички."
    }
    modifier_texts = []
    for mod, desc in modifier_descriptions.items():
        if modifiers.get(mod):
            modifier_texts.append(desc)
    modifier_str = " | ".join(modifier_texts) if modifier_texts else "Нет"

    # Снаряжение
    equipment = info.get("equipment", [])
    equipment_str = ", ".join(equipment) if equipment else "Нет"

    back_button = Button(WIDTH // 2 - 100, HEIGHT - 70, 200, 50, "Назад", action=go_to_level_select)
    start_button = Button(WIDTH // 2 - 100, HEIGHT - 140, 200, 50, "Начать",
                          action=lambda: _start_level_game(level))

    def _start_level_game(lvl):
        global current_state
        current_state = f"level{lvl}"

    while current_state == "level_info":
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                sys.exit()
            back_button.handle_event(event)
            start_button.handle_event(event)

        screen.fill(MENU_BG)
        title = font.render(f"Уровень {level}", True, BLACK)
        screen.blit(title, (WIDTH // 2 - title.get_width() // 2, 40))

        y = 120
        # Цель
        screen.blit(small_font.render(target_text, True, BLACK), (50, y))
        y += 40

        # Начальные враги
        screen.blit(small_font.render("Начальные враги:", True, BLACK), (50, y))
        y += 30
        # перенос строки по словам (для длинных описаний)
        words = enemies_str.split()
        cur_line = ""
        for word in words:
            test_line = f"{cur_line} {word}".strip()
            if len(test_line) <= 50:
                cur_line = test_line
            else:
                screen.blit(small_font.render(cur_line, True, BLACK), (70, y))
                y += 25
                cur_line = word
        if cur_line:
            screen.blit(small_font.render(cur_line, True, BLACK), (70, y))
            y += 25

        y += 10
        # Модификаторы
        screen.blit(small_font.render("Модификаторы:", True, BLACK), (50, y))
        y += 25
        for mod_line in modifier_texts:
            screen.blit(micro_font.render(f"• {mod_line}", True, (150, 0, 0)), (70, y))
            y += 20

        y += 10
        # Снаряжение
        screen.blit(small_font.render("Снаряжение:", True, BLACK), (50, y))
        y += 25
        screen.blit(micro_font.render(equipment_str, True, (0, 0, 150)), (70, y))

        back_button.draw(screen)
        start_button.draw(screen)
        pygame.display.flip()
        clock.tick(FPS)

# ---------------------- УРОВНИ ----------------------
current_level = 1  # добавим в глобальные переменные

def start_level(level):
    global current_state, selected_abilities, game_mode, current_level
    info = LEVEL_INFO[level]
    equip_names = info.get("equipment", [])
    selected_abilities = {}
    for name in equip_names:
        # ищем способность по имени в ABILITY_INFO
        for ab in ABILITY_INFO:
            if ab["name"] == name:
                selected_abilities[name] = {
                    "uses": ab["uses"],
                    "cooldown": 0,
                    "slots": ab["slots"],
                    "key": ab["key"],
                    "max_uses": ab["uses"],
                    "max_cooldown": ab["cooldown"]
                }
                break
    game_mode = f"level{level}"
    current_level = level
    current_state = "level_info"

def show_challenge_select():
    global current_state
    back_button = Button(WIDTH // 2 - 100, HEIGHT - 70, 200, 50, "Назад", action=go_to_mode_select)
    chall1_btn = Button(WIDTH // 2 - 150, 150, 300, 60, "Сбор яблок", action=lambda: start_challenge(1))
    chall2_btn = Button(WIDTH // 2 - 150, 230, 300, 60, "Истинный бог факелов", action=lambda: start_challenge(2))
    chall3_btn = Button(WIDTH // 2 - 150, 310, 300, 60, "Сбор яблок 2", action=lambda: start_challenge(3))
    chall4_btn = Button(WIDTH // 2 - 150, 390, 300, 60, "Утро натурала", action=lambda: start_challenge(4))
    chall5_btn = Button(WIDTH // 2 - 150, 470, 300, 60, "Сбор яблок 3", action=lambda: start_challenge(5))
    while current_state == "challenge_select":
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                sys.exit()
            back_button.handle_event(event)
            chall1_btn.handle_event(event)
            chall2_btn.handle_event(event)
            chall3_btn.handle_event(event)
            chall4_btn.handle_event(event)
            chall5_btn.handle_event(event)
        screen.fill(MENU_BG)
        title = font.render("Выберите испытание", True, BLACK)
        screen.blit(title, (WIDTH//2 - title.get_width()//2, 80))
        chall1_btn.draw(screen)
        chall2_btn.draw(screen)
        chall3_btn.draw(screen)
        chall4_btn.draw(screen)
        chall5_btn.draw(screen)
        back_button.draw(screen)
        pygame.display.flip()

def start_challenge(num):
    global current_state, selected_abilities
    selected_abilities = {}
    if num == 1:
        current_state = "challenge1"
    elif num == 2:
        current_state = "challenge2"
    elif num == 3:
        current_state = "challenge3"
    elif num == 4:
        current_state = "challenge4"
    elif num == 5:
        current_state = "challenge5"

def show_survival_select():
    global current_state
    back_button = Button(WIDTH // 2 - 100, HEIGHT - 70, 200, 50, "Назад", action=go_to_mode_select)
    buttons = [
        Button(WIDTH // 2 - 100, 150, 200, 50, "Змеи", action=lambda: start_survival("snakes")),
        Button(WIDTH // 2 - 100, 220, 200, 50, "Пауки", action=lambda: start_survival("spiders")),
        Button(WIDTH // 2 - 100, 290, 200, 50, "Слизни", action=lambda: start_survival("slimes")),
        Button(WIDTH // 2 - 100, 360, 200, 50, "Насекомые", action=lambda: start_survival("insects")),
        Button(WIDTH // 2 - 100, 430, 200, 50, "Рыбы", action=lambda: start_survival("fish")),
    ]
    while current_state == "survival_select":
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                sys.exit()
            back_button.handle_event(event)
            for btn in buttons:
                btn.handle_event(event)
        screen.fill(MENU_BG)
        title = font.render("Выживание", True, BLACK)
        screen.blit(title, (WIDTH//2 - title.get_width()//2, 80))
        for btn in buttons:
            btn.draw(screen)
        back_button.draw(screen)
        pygame.display.flip()

def start_survival(mode):
    global current_state, selected_abilities
    selected_abilities = {}
    current_state = "ability_selection"
    global game_mode
    game_mode = mode
    show_ability_selection(mode)


# ---------------------- УРОВНИ ----------------------
def show_level_game(level):
    global current_state
    info = LEVEL_INFO[level]
    enemy_type = info.get("enemy_type", "snake")
    arena_style = info.get("arena_style", 0)
    target_type = info["target_type"]
    target_kills = info.get("target_kills", 0)
    target_apples = info.get("target_apples", 0)
    target_turns = info.get("target_turns", 0)
    max_enemies = info.get("max_enemies", 12)
    spawn_pool = info["spawn_pool"]
    spawn_chance = 0.3
    modifiers = info.get("modifiers", {})
    fog_enabled = modifiers.get("fog", False)

    # Копируем выданное снаряжение
    abilities = selected_abilities.copy()
    for name, data in abilities.items():
        data["cooldown"] = 0
        data["uses"] = data["max_uses"]

    bird_x, bird_y = GRID_SIZE // 2, GRID_SIZE // 2
    last_direction = 'up'
    enemies = []
    fireballs = []
    invisible_clouds = []
    spider_fireballs = []
    gas_clouds = []
    lava_cells_wall = set()

    if modifiers.get("walls_are_lava"):
        for x in range(GRID_SIZE):
            for y in range(3):
                lava_cells_wall.add((x, y))
                lava_cells_wall.add((x, GRID_SIZE - 1 - y))
        for y in range(GRID_SIZE):
            for x in range(3):
                lava_cells_wall.add((x, y))
                lava_cells_wall.add((GRID_SIZE - 1 - x, y))

    # Переменные для целей
    apple_pos = None
    apples_collected = 0
    turn_count = 0
    borders_visited = {"top": False, "bottom": False, "left": False, "right": False}
    corners_visited = set()
    total_killed = 0
    game_over = False
    victory = False

    turn_state = 'player'
    player_moved_this_turn = False
    invulnerable_timer = 0
    double_turn_active = False
    moves_in_turn = 0

    torch_cooldown = 0

    # Инициализация врагов
    for enemy_t, sub_type, count in info["initial_enemies"]:
        for _ in range(count):
            if enemy_t == "snake":
                enemies.append(create_snake_at_edge(sub_type))
            elif enemy_t == "spider":
                info_sp = SPIDER_INFO[sub_type]
                size = info_sp["size"]
                fall_time = info_sp["fall_time"]
                for _ in range(50):
                    x = random.randint(0, GRID_SIZE - size)
                    y = random.randint(0, GRID_SIZE - size)
                    occupied = set()
                    for e in enemies:
                        if isinstance(e, Spider):
                            occupied.update(e.get_positions())
                        elif isinstance(e, Shadow):
                            for i in range(e.size):
                                for j in range(e.size):
                                    occupied.add((e.x + i, e.y + j))
                    collision = False
                    for i in range(size):
                        for j in range(size):
                            if (x + i, y + j) in occupied:
                                collision = True
                                break
                        if collision:
                            break
                    if not collision:
                        enemies.append(Shadow(x, y, size, fall_time, sub_type))
                        break

    def spawn_apple():
        nonlocal apple_pos
        if target_type not in ("collect_apples", "kill_and_collect"):
            return
        occupied = set()
        for e in enemies:
            if isinstance(e, Snake):
                occupied.update(e.get_all_positions())
            elif isinstance(e, Spider):
                occupied.update(e.get_positions())
            elif isinstance(e, Shadow):
                for i in range(e.size):
                    for j in range(e.size):
                        occupied.add((e.x + i, e.y + j))
        if modifiers.get("walls_are_lava"):
            occupied.update(lava_cells_wall)
        free = [(x, y) for x in range(GRID_SIZE) for y in range(GRID_SIZE) if (x, y) not in occupied and (x, y) != (bird_x, bird_y)]
        if free:
            apple_pos = random.choice(free)
        else:
            apple_pos = None

    if target_type in ("collect_apples", "kill_and_collect"):
        spawn_apple()

    def spawn_enemy_if_needed():
        if len(enemies) >= max_enemies:
            return
        if random.random() > spawn_chance:
            return
        if enemy_type == "snake":
            if "special_spawn_limit" in info:
                for snake_type, limit in info["special_spawn_limit"].items():
                    current_count = sum(1 for e in enemies if isinstance(e, Snake) and e.snake_type == snake_type)
                    if current_count >= limit and snake_type in spawn_pool:
                        allowed_pool = [t for t in spawn_pool if t != snake_type]
                        if not allowed_pool:
                            return
                        enemy_t = random.choice(allowed_pool)
                    else:
                        enemy_t = random.choice(spawn_pool)
            else:
                enemy_t = random.choice(spawn_pool)
            new_snake = create_snake_at_edge(enemy_t)
            collision = any(isinstance(e, Snake) and new_snake.get_all_positions() & e.get_all_positions() for e in enemies)
            if not collision:
                enemies.append(new_snake)
        elif enemy_type == "spider":
            if "special_spawn_limit" in info:
                for sp_type, limit in info["special_spawn_limit"].items():
                    current_count = sum(1 for e in enemies if isinstance(e, Spider) and e.spider_type == sp_type)
                    if current_count >= limit and sp_type in spawn_pool:
                        allowed_pool = [t for t in spawn_pool if t != sp_type]
                        if not allowed_pool:
                            return
                        sp_type = random.choice(allowed_pool)
                    else:
                        sp_type = random.choice(spawn_pool)
            else:
                sp_type = random.choice(spawn_pool)
            info_sp = SPIDER_INFO[sp_type]
            size = info_sp["size"]
            fall_time = info_sp["fall_time"]
            for _ in range(50):
                x = random.randint(0, GRID_SIZE - size)
                y = random.randint(0, GRID_SIZE - size)
                occupied = set()
                for e in enemies:
                    if isinstance(e, Spider):
                        occupied.update(e.get_positions())
                    elif isinstance(e, Shadow):
                        for i in range(e.size):
                            for j in range(e.size):
                                occupied.add((e.x + i, e.y + j))
                collision = False
                for i in range(size):
                    for j in range(size):
                        if (x + i, y + j) in occupied:
                            collision = True
                            break
                    if collision:
                        break
                if not collision:
                    enemies.append(Shadow(x, y, size, fall_time, sp_type))
                    break

    def spawn_torch_fireballs():
        nonlocal torch_cooldown
        if not modifiers.get("god_of_torches", False):
            return
        if torch_cooldown <= 0:
            if random.random() < 0.4:
                side = random.choice(['top', 'bottom', 'left', 'right'])
                if side == 'top':
                    x = random.randint(0, GRID_SIZE-1)
                    y = 0
                    dy = 1
                    dx = 0
                elif side == 'bottom':
                    x = random.randint(0, GRID_SIZE-1)
                    y = GRID_SIZE-1
                    dy = -1
                    dx = 0
                elif side == 'left':
                    x = 0
                    y = random.randint(0, GRID_SIZE-1)
                    dx = 1
                    dy = 0
                else:
                    x = GRID_SIZE-1
                    y = random.randint(0, GRID_SIZE-1)
                    dx = -1
                    dy = 0
                fireballs.append(Fireball(x, y, dx, dy, speed=1, color=(255, 69, 0)))
                torch_cooldown = 3
        else:
            torch_cooldown -= 1

    def update_enemies():
        nonlocal total_killed
        if enemy_type == "snake":
            snakes = [e for e in enemies if isinstance(e, Snake)]
            for snake in snakes:
                snake.move(bird_x, bird_y, fireballs, invisible_clouds)
                if snake.is_completely_off_grid():
                    enemies.remove(snake)
                    total_killed += 1
            for fb in fireballs[:]:
                fb.move()
                if not fb.active:
                    fireballs.remove(fb)
            for ic in invisible_clouds[:]:
                ic.update()
                if not ic.active:
                    invisible_clouds.remove(ic)
        elif enemy_type == "spider":
            new_spiders = []
            for shadow in [e for e in enemies if isinstance(e, Shadow)]:
                if shadow.update():
                    spider = Spider(shadow.x, shadow.y, shadow.spider_type)
                    if shadow.spider_type == "dark_gray_red_cross":
                        cx, cy = shadow.x, shadow.y
                        for dx, dy in [(1, 0), (-1, 0), (0, 1), (0, -1)]:
                            spider_fireballs.append(SpiderFireball(cx + dx, cy + dy, dx, dy, speed=1))
                    elif shadow.spider_type == "white_purple_circle":
                        cx = shadow.x + shadow.size // 2
                        cy = shadow.y + shadow.size // 2
                        for dx, dy in [(1, 0), (-1, 0), (0, 1), (0, -1)]:
                            spider_fireballs.append(SpiderFireball(cx, cy, dx, dy, speed=2, length=1, color=PURPLE_FIRE))
                            spider_fireballs.append(SpiderFireball(cx + dx, cy + dy, dx, dy, speed=2, length=1, color=PURPLE_FIRE))
                    elif shadow.spider_type == "rainbow_spider":
                        spider.shoot_rainbow(spider_fireballs)
                    new_spiders.append(spider)
                    enemies.remove(shadow)
            enemies.extend(new_spiders)
            for spider in [e for e in enemies if isinstance(e, Spider)]:
                spider.update(spider_fireballs, gas_clouds, bird_x, bird_y)
                if not spider.active:
                    enemies.remove(spider)
                    total_killed += 1
            for fb in spider_fireballs[:]:
                fb.move()
                if not fb.active:
                    spider_fireballs.remove(fb)
            for gc in gas_clouds[:]:
                gc.update()
                if not gc.active:
                    gas_clouds.remove(gc)

    def is_any_visible(positions, bird_x, bird_y, fog):
        if not fog:
            return True
        for (px, py) in positions:
            if is_cell_visible(px, py, bird_x, bird_y, fog):
                return True
        return False

    def check_collision():
        bird_pos = (bird_x, bird_y)
        if bird_pos in lava_cells_wall:
            return True
        for e in enemies:
            if isinstance(e, Snake):
                if bird_pos in e.get_all_positions():
                    return True
            elif isinstance(e, Spider):
                if bird_pos in e.get_positions():
                    return True
        for fb in fireballs:
            if fb.active and fb.get_pos() == bird_pos:
                return True
        for fb in spider_fireballs:
            if fb.active and bird_pos in fb.get_positions():
                return True
        for ic in invisible_clouds:
            if ic.lethal and bird_pos in ic.get_affected_cells():
                return True
        for gc in gas_clouds:
            if bird_pos in gc.get_affected_cells():
                return True
        return False

    running = True
    while running and current_state == f"level{level}":
        # Обработка событий
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                current_state = "menu"
                running = False
            elif event.type == pygame.KEYDOWN and not game_over and not victory:
                if turn_state == 'player' and not player_moved_this_turn:
                    # Обработка способностей (клавиши 1-7)
                    if event.key == pygame.K_7 and "Метод скипа" in abilities:
                        data = abilities["Метод скипа"]
                        if data["cooldown"] == 0 and data["uses"] > 0:
                            data["uses"] -= 1
                            data["cooldown"] = data["max_cooldown"]
                            player_moved_this_turn = True
                    elif event.key == pygame.K_1 and "Гэмблинг" in abilities:
                        data = abilities["Гэмблинг"]
                        if data["cooldown"] == 0 and data["uses"] > 0:
                            occupied = set()
                            for e in enemies:
                                if isinstance(e, Snake):
                                    occupied.update(e.get_all_positions())
                                elif isinstance(e, Spider):
                                    occupied.update(e.get_positions())
                                elif isinstance(e, Shadow):
                                    for i in range(e.size):
                                        for j in range(e.size):
                                            occupied.add((e.x + i, e.y + j))
                            for fb in fireballs:
                                if fb.active:
                                    occupied.add((fb.x, fb.y))
                            for fb in spider_fireballs:
                                if fb.active:
                                    occupied.update(fb.get_positions())
                            occupied.update(lava_cells_wall)
                            free_cells = [(x, y) for x in range(GRID_SIZE) for y in range(GRID_SIZE) if (x, y) not in occupied]
                            if free_cells:
                                bird_x, bird_y = random.choice(free_cells)
                                data["uses"] -= 1
                                data["cooldown"] = data["max_cooldown"]
                                player_moved_this_turn = True
                                if invulnerable_timer <= 0 and check_collision():
                                    game_over = True
                    elif event.key == pygame.K_2 and "Освежитель" in abilities:
                        data = abilities["Освежитель"]
                        if data["cooldown"] == 0 and data["uses"] > 0:
                            for ic in invisible_clouds[:]:
                                if abs(ic.x - bird_x) <= 3 and abs(ic.y - bird_y) <= 3:
                                    invisible_clouds.remove(ic)
                            for gc in gas_clouds[:]:
                                if abs(gc.x - bird_x) <= 3 and abs(gc.y - bird_y) <= 3:
                                    gas_clouds.remove(gc)
                            data["uses"] -= 1
                            data["cooldown"] = data["max_cooldown"]
                    elif event.key == pygame.K_3 and "Айсаир" in abilities:
                        data = abilities["Айсаир"]
                        if data["cooldown"] == 0 and data["uses"] > 0:
                            all_fb = fireballs + spider_fireballs
                            for fb in all_fb:
                                if abs(fb.x - bird_x) + abs(fb.y - bird_y) <= 3:
                                    if fb.color == PURPLE_FIRE:
                                        fb.color = (255, 69, 0)
                                        fb.speed = 1
                                    elif fb.color == (255, 69, 0):
                                        fb.color = (100, 255, 100)
                                        fb.speed = 0.5
                                    elif fb.color == (100, 255, 100):
                                        fb.active = False
                            data["uses"] -= 1
                            data["cooldown"] = data["max_cooldown"]
                    elif event.key == pygame.K_4 and "Мощные крылья" in abilities:
                        data = abilities["Мощные крылья"]
                        if data["cooldown"] == 0 and data["uses"] > 0:
                            dx, dy = 0, 0
                            if last_direction == 'up':
                                dy = -3
                            elif last_direction == 'down':
                                dy = 3
                            elif last_direction == 'left':
                                dx = -3
                            elif last_direction == 'right':
                                dx = 3
                            new_x = max(0, min(GRID_SIZE - 1, bird_x + dx))
                            new_y = max(0, min(GRID_SIZE - 1, bird_y + dy))
                            bird_x, bird_y = new_x, new_y
                            data["uses"] -= 1
                            data["cooldown"] = data["max_cooldown"]
                            player_moved_this_turn = True
                            if invulnerable_timer <= 0 and check_collision():
                                game_over = True
                    elif event.key == pygame.K_5 and "Ремнант" in abilities:
                        data = abilities["Ремнант"]
                        if data["cooldown"] == 0 and data["uses"] > 0:
                            invulnerable_timer = 4
                            data["uses"] -= 1
                            data["cooldown"] = data["max_cooldown"]
                    elif event.key == pygame.K_6 and "The world" in abilities:
                        data = abilities["The world"]
                        if data["cooldown"] == 0 and data["uses"] > 0:
                            double_turn_active = True
                            moves_in_turn = 0
                            data["uses"] -= 1
                            data["cooldown"] = data["max_cooldown"]

                    if not player_moved_this_turn:
                        old_x, old_y = bird_x, bird_y
                        if event.key == pygame.K_w and bird_y > 0:
                            bird_y -= 1
                            last_direction = 'up'
                        elif event.key == pygame.K_s and bird_y < GRID_SIZE - 1:
                            bird_y += 1
                            last_direction = 'down'
                        elif event.key == pygame.K_a and bird_x > 0:
                            bird_x -= 1
                            last_direction = 'left'
                        elif event.key == pygame.K_d and bird_x < GRID_SIZE - 1:
                            bird_x += 1
                            last_direction = 'right'
                        if (bird_x, bird_y) != (old_x, old_y):
                            player_moved_this_turn = True
                            # Проверка столкновения
                            if invulnerable_timer <= 0 and check_collision():
                                game_over = True
                            else:
                                # Обновление целей посещения
                                if bird_x == 0: borders_visited["left"] = True
                                if bird_x == GRID_SIZE - 1: borders_visited["right"] = True
                                if bird_y == 0: borders_visited["top"] = True
                                if bird_y == GRID_SIZE - 1: borders_visited["bottom"] = True
                                if (bird_x, bird_y) in [(0,0), (0,GRID_SIZE-1), (GRID_SIZE-1,0), (GRID_SIZE-1,GRID_SIZE-1)]:
                                    corners_visited.add((bird_x, bird_y))
                                # Сбор яблока
                                if apple_pos and (bird_x, bird_y) == apple_pos:
                                    apples_collected += 1
                                    apple_pos = None
                                    if (target_type in ("collect_apples", "kill_and_collect") and
                                        apples_collected < target_apples):
                                        spawn_apple()

                            if double_turn_active:
                                moves_in_turn += 1
                                if moves_in_turn >= 2:
                                    double_turn_active = False
                                    turn_state = 'enemies'
                                else:
                                    player_moved_this_turn = False
                            else:
                                turn_state = 'enemies'

            elif event.type == pygame.KEYDOWN and (game_over or victory):
                if event.key == pygame.K_r:
                    show_level_game(level)
                    return
                elif event.key == pygame.K_q:
                    current_state = "menu"
                    running = False
        if not game_over and not victory and turn_state == 'player' and player_moved_this_turn and not double_turn_active:
            turn_state = 'enemies'

        if not game_over and not victory and turn_state == 'enemies':
            update_enemies()
            spawn_enemy_if_needed()
            spawn_torch_fireballs()

            if invulnerable_timer <= 0 and check_collision():
                game_over = True

            # Проверка целей
            if target_type == "kill" and total_killed >= target_kills:
                victory = True
            elif target_type == "collect_apples" and apples_collected >= target_apples:
                victory = True
            elif target_type == "survive_turns" and turn_count >= target_turns:
                victory = True
            elif target_type == "visit_borders" and all(borders_visited.values()):
                victory = True
            elif target_type == "visit_corners" and len(corners_visited) == 4:
                victory = True
            elif target_type == "kill_and_collect" and total_killed >= target_kills and apples_collected >= target_apples:
                victory = True

            # Уменьшаем кулдауны способностей и неуязвимости
            for data in abilities.values():
                if data["cooldown"] > 0:
                    data["cooldown"] -= 1
            if invulnerable_timer > 0:
                invulnerable_timer -= 1

            turn_state = 'player'
            player_moved_this_turn = False
            turn_count += 1

        # Отрисовка
        screen.fill(BLACK)  # фон за границами сетки
        # Рисуем клетки арены
        for row in range(GRID_SIZE):
            for col in range(GRID_SIZE):
                rect = pygame.Rect(col * CELL_SIZE, row * CELL_SIZE, CELL_SIZE, CELL_SIZE)
                if arena_style == 1:
                    color1, color2 = (40, 40, 50), (30, 30, 40)
                else:
                    color1, color2 = GRAY, LIGHT_GRAY
                if (row + col) % 2 == 0:
                    base_color = color1
                else:
                    base_color = color2
                pygame.draw.rect(screen, base_color, rect)
                # Лава
                if (col, row) in lava_cells_wall:
                    pygame.draw.rect(screen, (255, 69, 0), rect)
                pygame.draw.rect(screen, BLACK, rect, 1)

        # Отрисовка объектов с учетом тумана
        def draw_entity(entity, get_positions_func, draw_func):
            positions = get_positions_func() if callable(get_positions_func) else get_positions_func
            if is_any_visible(positions, bird_x, bird_y, fog_enabled):
                draw_func()

        for e in enemies:
            if isinstance(e, Snake):
                if is_any_visible(e.get_all_positions(), bird_x, bird_y, fog_enabled):
                    e.draw(screen)
            elif isinstance(e, Spider):
                if is_any_visible(e.get_positions(), bird_x, bird_y, fog_enabled):
                    e.draw(screen)
            elif isinstance(e, Shadow):
                pos = {(e.x + i, e.y + j) for i in range(e.size) for j in range(e.size)}
                if is_any_visible(pos, bird_x, bird_y, fog_enabled):
                    e.draw(screen)

        for fb in fireballs:
            if is_any_visible({fb.get_pos()}, bird_x, bird_y, fog_enabled):
                fb.draw(screen)
        for fb in spider_fireballs:
            if is_any_visible(fb.get_positions(), bird_x, bird_y, fog_enabled):
                fb.draw(screen)
        for gc in gas_clouds:
            if is_any_visible(gc.get_affected_cells(), bird_x, bird_y, fog_enabled):
                gc.draw(screen)
        for ic in invisible_clouds:
            if is_any_visible(ic.get_affected_cells(), bird_x, bird_y, fog_enabled):
                ic.draw(screen)

        # Яблоко
        if apple_pos:
            ax, ay = apple_pos
            if is_cell_visible(ax, ay, bird_x, bird_y, fog_enabled):
                rect = pygame.Rect(ax * CELL_SIZE, ay * CELL_SIZE, CELL_SIZE, CELL_SIZE)
                pygame.draw.circle(screen, (255, 0, 0), rect.center, CELL_SIZE // 3)
                pygame.draw.circle(screen, BLACK, rect.center, CELL_SIZE // 3, 2)

        # Птичка всегда видна
        draw_bird(screen, bird_x, bird_y, True)

        # Интерфейс: счётчики
        if target_type in ("kill", "kill_and_collect"):
            kill_text = small_font.render(f"Врагов: {total_killed}/{target_kills}", True, BLACK)
            screen.blit(kill_text, (10, 10))
        if target_type in ("collect_apples", "kill_and_collect"):
            apple_text = small_font.render(f"Яблок: {apples_collected}/{target_apples}", True, BLACK)
            screen.blit(apple_text, (10, 30))
        if target_type == "survive_turns":
            turn_text = small_font.render(f"РҐРѕРґ: {turn_count}/{target_turns}", True, BLACK)
            screen.blit(turn_text, (10, 10))
        # Посещение краёв и углов можно показывать маленькими индикаторами (опционально)
        if target_type == "visit_borders":
            b_text = small_font.render(f"Края: {sum(borders_visited.values())}/4", True, BLACK)
            screen.blit(b_text, (10, 10))
        if target_type == "visit_corners":
            c_text = small_font.render(f"Углы: {len(corners_visited)}/4", True, BLACK)
            screen.blit(c_text, (10, 10))

        # Способности
        y_abl = 70
        for name, data in abilities.items():
            info_ab = next((a for a in ABILITY_INFO if a["name"] == name), None)
            if info_ab:
                key_str = f"[{info_ab['key']}]"
                status = f"{data['uses']}/{data['max_uses']}"
                if data["cooldown"] > 0:
                    status += f" (РљР” {data['cooldown']})"
                text = micro_font.render(f"{key_str} {name}: {status}", True, BLACK)
                screen.blit(text, (WIDTH - 250, y_abl))
                y_abl += 20

        if invulnerable_timer > 0:
            inv_text = micro_font.render(f"Неуязвимость: {invulnerable_timer}", True, (200, 0, 0))
            screen.blit(inv_text, (WIDTH - 250, y_abl))

        # Затемнение при поражении/победе
        if game_over or victory:
            overlay = pygame.Surface((WIDTH, HEIGHT))
            overlay.set_alpha(200)
            overlay.fill(BLACK)
            screen.blit(overlay, (0, 0))
            if game_over:
                texts = [font.render("ПОРАЖЕНИЕ!", True, RED_SNAKE),
                         small_font.render("R - рестарт | Q - выход", True, GREEN)]
            else:
                texts = [font.render("ПОБЕДА!", True, GREEN),
                         small_font.render("R - заново | Q - выход", True, GREEN)]
            y_text = HEIGHT // 2 - 40
            for text in texts:
                rect = text.get_rect(center=(WIDTH // 2, y_text))
                screen.blit(text, rect)
                y_text += 40

        pygame.display.flip()
        clock.tick(FPS)

# ---------------------- ИСПЫТАНИЯ ----------------------
def show_challenge1():
    global current_state
    bird_x, bird_y = GRID_SIZE // 2, GRID_SIZE // 2
    last_direction = 'up'
    state = {'apples_collected': 0, 'apple_pos': None, 'victory': False, 'game_over': False}
    enemies = []
    fireballs = []
    gas_clouds = []
    invisible_clouds = []
    turn_count = 0
    turn_state = 'player'
    player_moved_this_turn = False

    # Максимальное количество врагов на поле
    MAX_ENEMIES = 10
    # Вероятность появления нового врага каждый ход
    SPAWN_CHANCE = 0.35

    def spawn_apple():
        if target_type not in ("collect_apples", "kill_and_collect"):
            return None
        occupied = set()
        for e in enemies:
            if isinstance(e, Snake):
                occupied.update(e.get_all_positions())
            elif isinstance(e, Spider):
                occupied.update(e.get_positions())
            elif isinstance(e, Shadow):
                for i in range(e.size):
                    for j in range(e.size):
                        occupied.add((e.x + i, e.y + j))
        if modifiers.get("walls_are_lava"):
            occupied.update(lava_cells_wall)
        free = [(x, y) for x in range(GRID_SIZE) for y in range(GRID_SIZE)
                if (x, y) not in occupied and (x, y) != (bird_x, bird_y)]
        if free:
            return random.choice(free)
        return None

        if modifiers.get("walls_are_lava"):
            occupied.update(lava_cells_wall)

        # Свободные клетки — те, что не заняты врагами/лавой и где нет самой птички
        free = [(x, y) for x in range(GRID_SIZE) for y in range(GRID_SIZE)
                if (x, y) not in occupied and (x, y) != (bird_x, bird_y)]

        if free:
            apple_pos = random.choice(free)
        else:
            apple_pos = None

    # Начальные враги
    enemies.append(create_snake_at_edge("stripe_green"))
    enemies.append(create_snake_at_edge("bright_green"))
    sh = Shadow(random.randint(0, GRID_SIZE-1), random.randint(0, GRID_SIZE-1), 1, 3, "dark_gray_green_circle")
    enemies.append(sh)
    enemies.append(spawn_slime("green_slime_jump1"))
    enemies.append(spawn_slime("dark_green_slime"))
    spawn_apple()

    def spawn_enemy_if_needed():
        """Пытается создать нового врага, если их меньше MAX_ENEMIES."""
        if len(enemies) >= MAX_ENEMIES:
            return
        if random.random() > SPAWN_CHANCE:
            return

        available_types = [
            "stripe_green",          # змея
            "bright_green",          # змея
            "dark_gray_green_circle",# паук (через тень)
            "green_slime_jump1",     # слизень
            "dark_green_slime"       # слизень
        ]
        enemy_type = random.choice(available_types)

        if enemy_type in ("stripe_green", "bright_green"):
            new_snake = create_snake_at_edge(enemy_type)
            # Проверяем, что змея не пересекается с существующими
            collision = False
            for e in enemies:
                if isinstance(e, Snake):
                    if new_snake.get_all_positions() & e.get_all_positions():
                        collision = True
                        break
                elif isinstance(e, Spider):
                    if new_snake.get_all_positions() & e.get_positions():
                        collision = True
                        break
                elif isinstance(e, Slime):
                    if any(pos == e.get_pos() for pos in new_snake.get_all_positions()):
                        collision = True
                        break
            if not collision:
                enemies.append(new_snake)
        elif enemy_type == "dark_gray_green_circle":
            # Создаём тень паука
            size = 1
            max_attempts = 20
            for _ in range(max_attempts):
                x = random.randint(0, GRID_SIZE - size)
                y = random.randint(0, GRID_SIZE - size)
                occupied = set()
                for e in enemies:
                    if isinstance(e, Spider):
                        occupied.update(e.get_positions())
                    elif isinstance(e, Shadow):
                        for i in range(e.size):
                            for j in range(e.size):
                                occupied.add((e.x + i, e.y + j))
                collision = any((x + i, y + j) in occupied for i in range(size) for j in range(size))
                if not collision:
                    enemies.append(Shadow(x, y, size, 3, enemy_type))
                    break
        else:
            # Слизень
            new_slime = spawn_slime(enemy_type)
            collision = any(isinstance(e, Slime) and e.get_pos() == new_slime.get_pos() for e in enemies)
            if not collision:
                enemies.append(new_slime)

    def update_enemies():
        snakes = [e for e in enemies if isinstance(e, Snake)]
        spiders = [e for e in enemies if isinstance(e, Spider)]
        slimes = [e for e in enemies if isinstance(e, Slime)]
        shadows = [e for e in enemies if isinstance(e, Shadow)]
        for sh in shadows[:]:
            if sh.update():
                spider = Spider(sh.x, sh.y, sh.spider_type)
                enemies.append(spider)
                enemies.remove(sh)
        for snake in snakes:
            snake.move(bird_x, bird_y, fireballs, invisible_clouds)
            if snake.is_completely_off_grid():
                enemies.remove(snake)
        for spider in spiders:
            spider.update(fireballs, gas_clouds, bird_x, bird_y)
            if not spider.active:
                enemies.remove(spider)
        new_slimes = []
        for slime in slimes[:]:
            slime.update(fireballs, gas_clouds, invisible_clouds, new_slimes)
            if not slime.active:
                enemies.remove(slime)
        enemies.extend(new_slimes)
        for fb in fireballs[:]:
            if hasattr(fb, 'move'):
                fb.move()
            elif hasattr(fb, 'update'):
                fb.update()
            if not fb.active:
                fireballs.remove(fb)
        for gc in gas_clouds[:]:
            gc.update()
            if not gc.active:
                gas_clouds.remove(gc)
        for ic in invisible_clouds[:]:
            ic.update()
            if not ic.active:
                invisible_clouds.remove(ic)

        if state['apple_pos'] and (bird_x, bird_y) == state['apple_pos']:
            state['apples_collected'] += 1
            if state['apples_collected'] >= 10:
                state['victory'] = True
            else:
                spawn_apple()

    def check_collision():
        bird_pos = (bird_x, bird_y)
        for e in enemies:
            if isinstance(e, Snake):
                if bird_pos in e.get_all_positions():
                    return True
            elif isinstance(e, Spider):
                if bird_pos in e.get_positions():
                    return True
            elif isinstance(e, Slime):
                if e.get_pos() == bird_pos and e.slime_type not in ("light_gray_slime", "white_slime"):
                    return True
        for fb in fireballs:
            if not fb.active:
                continue
            if hasattr(fb, 'get_positions'):
                if bird_pos in fb.get_positions():
                    return True
            elif hasattr(fb, 'get_pos'):
                if fb.get_pos() == bird_pos:
                    return True
        for gc in gas_clouds:
            if bird_pos in gc.get_affected_cells():
                return True
        return False

    running = True
    while running and current_state == "challenge1":
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                current_state = "menu"
                running = False
            elif event.type == pygame.KEYDOWN and not state['game_over'] and not state['victory']:
                if turn_state == 'player' and not player_moved_this_turn:
                    old_x, old_y = bird_x, bird_y
                    if event.key == pygame.K_w and bird_y > 0:
                        bird_y -= 1
                        last_direction = 'up'
                    elif event.key == pygame.K_s and bird_y < GRID_SIZE - 1:
                        bird_y += 1
                        last_direction = 'down'
                    elif event.key == pygame.K_a and bird_x > 0:
                        bird_x -= 1
                        last_direction = 'left'
                    elif event.key == pygame.K_d and bird_x < GRID_SIZE - 1:
                        bird_x += 1
                        last_direction = 'right'
                    if (bird_x, bird_y) != (old_x, old_y):
                        player_moved_this_turn = True
                        if check_collision():
                            state['game_over'] = True
                        else:
                            if state['apple_pos'] and (bird_x, bird_y) == state['apple_pos']:
                                state['apples_collected'] += 1
                                if state['apples_collected'] >= 10:
                                    state['victory'] = True
                                else:
                                    spawn_apple()
                    turn_state = 'enemies'
            elif event.type == pygame.KEYDOWN and (state['game_over'] or state['victory']):
                if event.key == pygame.K_r:
                    show_challenge1()
                    return
                elif event.key == pygame.K_q:
                    current_state = "menu"
                    running = False

        if not state['game_over'] and not state['victory'] and turn_state == 'enemies':
            update_enemies()
            spawn_enemy_if_needed()   # <-- новый спавн
            if check_collision():
                state['game_over'] = True
            turn_state = 'player'
            player_moved_this_turn = False
            turn_count += 1

        # Отрисовка (без изменений)
        screen.fill(WHITE)
        draw_grid()
        for e in enemies:
            if isinstance(e, Snake):
                e.draw(screen)
            elif isinstance(e, Spider):
                e.draw(screen)
            elif isinstance(e, Slime):
                e.draw(screen)
            elif isinstance(e, Shadow):
                e.draw(screen)
        for fb in fireballs:
            fb.draw(screen)
        for gc in gas_clouds:
            gc.draw(screen)
        for ic in invisible_clouds:
            ic.draw(screen)
        if state['apple_pos']:
            ax, ay = state['apple_pos']
            rect = pygame.Rect(ax * CELL_SIZE, ay * CELL_SIZE, CELL_SIZE, CELL_SIZE)
            pygame.draw.circle(screen, (255, 0, 0), rect.center, CELL_SIZE // 3)
        draw_bird(screen, bird_x, bird_y, True)

        apple_text = small_font.render(f"Яблок: {state['apples_collected']} / 10", True, BLACK)
        screen.blit(apple_text, (WIDTH - 200, 10))

        if state['game_over']:
            overlay = pygame.Surface((WIDTH, HEIGHT))
            overlay.set_alpha(200)
            overlay.fill(BLACK)
            screen.blit(overlay, (0, 0))
            texts = [font.render("ПОРАЖЕНИЕ!", True, RED_SNAKE),
                     small_font.render("R - рестарт | Q - выход", True, GREEN)]
            y_text = HEIGHT // 2 - 40
            for text in texts:
                rect = text.get_rect(center=(WIDTH // 2, y_text))
                screen.blit(text, rect)
                y_text += 40
        elif state['victory']:
            overlay = pygame.Surface((WIDTH, HEIGHT))
            overlay.set_alpha(200)
            overlay.fill(BLACK)
            screen.blit(overlay, (0, 0))
            texts = [font.render("ПОБЕДА!", True, GREEN),
                     small_font.render("R - рестарт | Q - выход", True, GREEN)]
            y_text = HEIGHT // 2 - 40
            for text in texts:
                rect = text.get_rect(center=(WIDTH // 2, y_text))
                screen.blit(text, rect)
                y_text += 40

        pygame.display.flip()
        clock.tick(FPS)


def show_challenge2():
    global current_state
    bird_x, bird_y = GRID_SIZE // 2, GRID_SIZE // 2
    last_direction = 'up'
    turn_count = 0
    max_turns = 100
    state = {'game_over': False, 'victory': False}
    turn_state = 'player'
    player_moved_this_turn = False
    enemies = []
    fireballs = []
    gas_clouds = []
    invisible_clouds = []
    torch_cooldown = 0

    MAX_ENEMIES = 12
    SPAWN_CHANCE = 0.4

    # Начальные враги
    enemies.append(create_snake_at_edge("stripe_green"))
    enemies.append(create_snake_at_edge("stripe_blue"))
    enemies.append(create_snake_at_edge("red"))
    sh = Shadow(random.randint(0, GRID_SIZE-1), random.randint(0, GRID_SIZE-1), 2, 5, "dark_red")
    enemies.append(sh)
    enemies.append(spawn_slime("red_slime"))

    def spawn_torch_fireballs():
        nonlocal torch_cooldown
        if torch_cooldown <= 0:
            if random.random() < 0.4:
                side = random.choice(['top', 'bottom', 'left', 'right'])
                if side == 'top':
                    x = random.randint(0, GRID_SIZE-1)
                    y = 0
                    dy = 1
                    dx = 0
                elif side == 'bottom':
                    x = random.randint(0, GRID_SIZE-1)
                    y = GRID_SIZE-1
                    dy = -1
                    dx = 0
                elif side == 'left':
                    x = 0
                    y = random.randint(0, GRID_SIZE-1)
                    dx = 1
                    dy = 0
                else:
                    x = GRID_SIZE-1
                    y = random.randint(0, GRID_SIZE-1)
                    dx = -1
                    dy = 0
                fireballs.append(Fireball(x, y, dx, dy, speed=1, color=(255, 69, 0)))
                torch_cooldown = 3
        else:
            torch_cooldown -= 1

    def spawn_enemy_if_needed():
        if len(enemies) >= MAX_ENEMIES:
            return
        if random.random() > SPAWN_CHANCE:
            return

        available_types = [
            "stripe_green",
            "stripe_blue",
            "red",           # красная змея
            "dark_red",      # паук
            "red_slime"      # слизень
        ]
        enemy_type = random.choice(available_types)

        if enemy_type in ("stripe_green", "stripe_blue", "red"):
            new_snake = create_snake_at_edge(enemy_type)
            collision = False
            for e in enemies:
                if isinstance(e, Snake):
                    if new_snake.get_all_positions() & e.get_all_positions():
                        collision = True
                        break
                elif isinstance(e, Spider):
                    if new_snake.get_all_positions() & e.get_positions():
                        collision = True
                        break
                elif isinstance(e, Slime):
                    if any(pos == e.get_pos() for pos in new_snake.get_all_positions()):
                        collision = True
                        break
            if not collision:
                enemies.append(new_snake)
        elif enemy_type == "dark_red":
            size = 2
            max_attempts = 20
            for _ in range(max_attempts):
                x = random.randint(0, GRID_SIZE - size)
                y = random.randint(0, GRID_SIZE - size)
                occupied = set()
                for e in enemies:
                    if isinstance(e, Spider):
                        occupied.update(e.get_positions())
                    elif isinstance(e, Shadow):
                        for i in range(e.size):
                            for j in range(e.size):
                                occupied.add((e.x + i, e.y + j))
                collision = any((x + i, y + j) in occupied for i in range(size) for j in range(size))
                if not collision:
                    enemies.append(Shadow(x, y, size, 5, enemy_type))
                    break
        else:  # red_slime
            new_slime = spawn_slime(enemy_type)
            collision = any(isinstance(e, Slime) and e.get_pos() == new_slime.get_pos() for e in enemies)
            if not collision:
                enemies.append(new_slime)

    def update_enemies():
        snakes = [e for e in enemies if isinstance(e, Snake)]
        spiders = [e for e in enemies if isinstance(e, Spider)]
        slimes = [e for e in enemies if isinstance(e, Slime)]
        shadows = [e for e in enemies if isinstance(e, Shadow)]
        for sh in shadows[:]:
            if sh.update():
                spider = Spider(sh.x, sh.y, sh.spider_type)
                enemies.append(spider)
                enemies.remove(sh)
        for snake in snakes:
            snake.move(bird_x, bird_y, fireballs, invisible_clouds)
            if snake.is_completely_off_grid():
                enemies.remove(snake)
        for spider in spiders:
            spider.update(fireballs, gas_clouds, bird_x, bird_y)
            if not spider.active:
                enemies.remove(spider)
        new_slimes = []
        for slime in slimes[:]:
            slime.update(fireballs, gas_clouds, invisible_clouds, new_slimes)
            if not slime.active:
                enemies.remove(slime)
        enemies.extend(new_slimes)
        for fb in fireballs[:]:
            if hasattr(fb, 'move'):
                fb.move()
            elif hasattr(fb, 'update'):
                fb.update()
            if not fb.active:
                fireballs.remove(fb)
        for gc in gas_clouds[:]:
            gc.update()
            if not gc.active:
                gas_clouds.remove(gc)
        for ic in invisible_clouds[:]:
            ic.update()
            if not ic.active:
                invisible_clouds.remove(ic)

    def check_collision():
        bird_pos = (bird_x, bird_y)
        for e in enemies:
            if isinstance(e, Snake):
                if bird_pos in e.get_all_positions():
                    return True
            elif isinstance(e, Spider):
                if bird_pos in e.get_positions():
                    return True
            elif isinstance(e, Slime):
                if e.get_pos() == bird_pos and e.slime_type not in ("light_gray_slime", "white_slime"):
                    return True
        for fb in fireballs:
            if not fb.active:
                continue
            if hasattr(fb, 'get_positions'):
                if bird_pos in fb.get_positions():
                    return True
            elif hasattr(fb, 'get_pos'):
                if fb.get_pos() == bird_pos:
                    return True
        for gc in gas_clouds:
            if bird_pos in gc.get_affected_cells():
                return True
        return False

    running = True
    while running and current_state == "challenge2":
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                current_state = "menu"
                running = False
            elif event.type == pygame.KEYDOWN and not state['game_over'] and not state['victory']:
                if turn_state == 'player' and not player_moved_this_turn:
                    old_x, old_y = bird_x, bird_y
                    if event.key == pygame.K_w and bird_y > 0:
                        bird_y -= 1
                        last_direction = 'up'
                    elif event.key == pygame.K_s and bird_y < GRID_SIZE - 1:
                        bird_y += 1
                        last_direction = 'down'
                    elif event.key == pygame.K_a and bird_x > 0:
                        bird_x -= 1
                        last_direction = 'left'
                    elif event.key == pygame.K_d and bird_x < GRID_SIZE - 1:
                        bird_x += 1
                        last_direction = 'right'
                    if (bird_x, bird_y) != (old_x, old_y):
                        player_moved_this_turn = True
                        if check_collision():
                            state['game_over'] = True
                    turn_state = 'enemies'
            elif event.type == pygame.KEYDOWN and (state['game_over'] or state['victory']):
                if event.key == pygame.K_r:
                    show_challenge2()
                    return
                elif event.key == pygame.K_q:
                    current_state = "menu"
                    running = False

        if not state['game_over'] and not state['victory'] and turn_state == 'enemies':
            update_enemies()
            spawn_torch_fireballs()
            spawn_enemy_if_needed()   # <-- новый спавн
            if check_collision():
                state['game_over'] = True
            turn_state = 'player'
            player_moved_this_turn = False
            turn_count += 1
            if turn_count >= max_turns:
                state['victory'] = True

        # Отрисовка (без изменений)
        screen.fill(WHITE)
        draw_grid()
        for e in enemies:
            if isinstance(e, Snake):
                e.draw(screen)
            elif isinstance(e, Spider):
                e.draw(screen)
            elif isinstance(e, Slime):
                e.draw(screen)
            elif isinstance(e, Shadow):
                e.draw(screen)
        for fb in fireballs:
            fb.draw(screen)
        for gc in gas_clouds:
            gc.draw(screen)
        for ic in invisible_clouds:
            ic.draw(screen)
        draw_bird(screen, bird_x, bird_y, True)

        turns_text = small_font.render(f"РҐРѕРґ: {turn_count} / {max_turns}", True, BLACK)
        screen.blit(turns_text, (WIDTH - 200, 10))

        if state['game_over']:
            overlay = pygame.Surface((WIDTH, HEIGHT))
            overlay.set_alpha(200)
            overlay.fill(BLACK)
            screen.blit(overlay, (0, 0))
            texts = [font.render("ПОРАЖЕНИЕ!", True, RED_SNAKE),
                     small_font.render("R - рестарт | Q - выход", True, GREEN)]
            y_text = HEIGHT // 2 - 40
            for text in texts:
                rect = text.get_rect(center=(WIDTH // 2, y_text))
                screen.blit(text, rect)
                y_text += 40
        elif state['victory']:
            overlay = pygame.Surface((WIDTH, HEIGHT))
            overlay.set_alpha(200)
            overlay.fill(BLACK)
            screen.blit(overlay, (0, 0))
            texts = [font.render("ПОБЕДА!", True, GREEN),
                     small_font.render("R - рестарт | Q - выход", True, GREEN)]
            y_text = HEIGHT // 2 - 40
            for text in texts:
                rect = text.get_rect(center=(WIDTH // 2, y_text))
                screen.blit(text, rect)
                y_text += 40

        pygame.display.flip()
        clock.tick(FPS)

def show_challenge3():
    global current_state
    bird_x, bird_y = GRID_SIZE // 2, GRID_SIZE // 2
    last_direction = 'up'
    state = {'apples_collected': 0, 'apple_pos': None, 'victory': False, 'game_over': False}
    enemies = []
    fireballs = []
    gas_clouds = []
    invisible_clouds = []
    spider_fireballs = []
    slime_balls = []
    slime_gas_clouds = []
    turn_count = 0
    turn_state = 'player'
    player_moved_this_turn = False

    MAX_ENEMIES = 10
    SPAWN_CHANCE = 0.35

    def spawn_apple():
        occupied = set()
        for e in enemies:
            if isinstance(e, Snake):
                occupied.update(e.get_all_positions())
            elif isinstance(e, Spider):
                occupied.update(e.get_positions())
            elif isinstance(e, Slime):
                occupied.add(e.get_pos())
            elif isinstance(e, Shadow):
                for i in range(e.size):
                    for j in range(e.size):
                        occupied.add((e.x + i, e.y + j))
        free = [(x, y) for x in range(GRID_SIZE) for y in range(GRID_SIZE)
                if (x, y) not in occupied and (x, y) != (bird_x, bird_y)]
        if free:
            state['apple_pos'] = random.choice(free)
        else:
            state['apple_pos'] = None

    # Начальные враги: быстрые зелёная и синяя змеи, стреляющие зелёная и синяя, коричневый паук, жёлтый слизень, чёрная змея
    enemies.append(create_snake_at_edge("bright_green"))
    enemies.append(create_snake_at_edge("light_blue"))
    enemies.append(create_snake_at_edge("stripe_green"))
    enemies.append(create_snake_at_edge("stripe_blue"))
    sh = Shadow(random.randint(0, GRID_SIZE-1), random.randint(0, GRID_SIZE-1), 1, 3, "brown_gray")
    enemies.append(sh)
    enemies.append(create_snake_at_edge("black"))
    spawn_apple()

    def spawn_enemy_if_needed():
        if len(enemies) >= MAX_ENEMIES:
            return
        if random.random() > SPAWN_CHANCE:
            return
        available_types = [
            "bright_green", "light_blue", "stripe_green", "stripe_blue",
            "brown_gray", "black"
        ]
        enemy_type = random.choice(available_types)
        if enemy_type in ("bright_green", "light_blue", "stripe_green", "stripe_blue", "black"):
            new_snake = create_snake_at_edge(enemy_type)
            collision = False
            for e in enemies:
                if isinstance(e, Snake):
                    if new_snake.get_all_positions() & e.get_all_positions():
                        collision = True
                        break
                elif isinstance(e, Spider):
                    if new_snake.get_all_positions() & e.get_positions():
                        collision = True
                        break
                elif isinstance(e, Slime):
                    if any(pos == e.get_pos() for pos in new_snake.get_all_positions()):
                        collision = True
                        break
            if not collision:
                enemies.append(new_snake)
        elif enemy_type == "brown_gray":
            size = 1
            max_attempts = 20
            for _ in range(max_attempts):
                x = random.randint(0, GRID_SIZE - size)
                y = random.randint(0, GRID_SIZE - size)
                occupied = set()
                for e in enemies:
                    if isinstance(e, Spider):
                        occupied.update(e.get_positions())
                    elif isinstance(e, Shadow):
                        for i in range(e.size):
                            for j in range(e.size):
                                occupied.add((e.x + i, e.y + j))
                collision = any((x + i, y + j) in occupied for i in range(size) for j in range(size))
                if not collision:
                    enemies.append(Shadow(x, y, size, 3, enemy_type))
                    break
        else:  # yellow_slime
            new_slime = spawn_slime(enemy_type)
            collision = any(isinstance(e, Slime) and e.get_pos() == new_slime.get_pos() for e in enemies)
            if not collision:
                enemies.append(new_slime)

    def update_enemies():
        snakes = [e for e in enemies if isinstance(e, Snake)]
        spiders = [e for e in enemies if isinstance(e, Spider)]
        slimes = [e for e in enemies if isinstance(e, Slime)]
        shadows = [e for e in enemies if isinstance(e, Shadow)]
        for sh in shadows[:]:
            if sh.update():
                spider = Spider(sh.x, sh.y, sh.spider_type)
                enemies.append(spider)
                enemies.remove(sh)
        for snake in snakes:
            snake.move(bird_x, bird_y, fireballs, invisible_clouds)
            if snake.is_completely_off_grid():
                enemies.remove(snake)
        for spider in spiders:
            spider.update(spider_fireballs, gas_clouds, bird_x, bird_y)
            if not spider.active:
                enemies.remove(spider)
        new_slimes = []
        for slime in slimes[:]:
            slime.update(slime_balls, slime_gas_clouds, invisible_clouds, new_slimes)
            if not slime.active:
                enemies.remove(slime)
        enemies.extend(new_slimes)
        # Обновление всех снарядов
        for fb_list in [fireballs, spider_fireballs, slime_balls]:
            for fb in fb_list[:]:
                if hasattr(fb, 'move'):
                    fb.move()
                elif hasattr(fb, 'update'):
                    fb.update()
                if not fb.active:
                    fb_list.remove(fb)
        for gc_list in [gas_clouds, slime_gas_clouds]:
            for gc in gc_list[:]:
                gc.update()
                if not gc.active:
                    gc_list.remove(gc)
        for ic in invisible_clouds[:]:
            ic.update()
            if not ic.active:
                invisible_clouds.remove(ic)

        if state['apple_pos'] and (bird_x, bird_y) == state['apple_pos']:
            state['apples_collected'] += 1
            if state['apples_collected'] >= 17:
                state['victory'] = True
            else:
                spawn_apple()

    def check_collision():
        bird_pos = (bird_x, bird_y)
        for e in enemies:
            if isinstance(e, Snake):
                if bird_pos in e.get_all_positions():
                    return True
            elif isinstance(e, Spider):
                if bird_pos in e.get_positions():
                    return True
            elif isinstance(e, Slime):
                if e.get_pos() == bird_pos and e.slime_type not in ("light_gray_slime", "white_slime"):
                    return True
        for fb_list in [fireballs, spider_fireballs, slime_balls]:
            for fb in fb_list:
                if not fb.active:
                    continue
                if hasattr(fb, 'get_positions'):
                    if bird_pos in fb.get_positions():
                        return True
                elif hasattr(fb, 'get_pos'):
                    if fb.get_pos() == bird_pos:
                        return True
        for gc_list in [gas_clouds, slime_gas_clouds]:
            for gc in gc_list:
                if bird_pos in gc.get_affected_cells():
                    return True
        return False

    running = True
    while running and current_state == "challenge3":
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                current_state = "menu"
                running = False
            elif event.type == pygame.KEYDOWN and not state['game_over'] and not state['victory']:
                if turn_state == 'player' and not player_moved_this_turn:
                    old_x, old_y = bird_x, bird_y
                    if event.key == pygame.K_w and bird_y > 0:
                        bird_y -= 1
                        last_direction = 'up'
                    elif event.key == pygame.K_s and bird_y < GRID_SIZE - 1:
                        bird_y += 1
                        last_direction = 'down'
                    elif event.key == pygame.K_a and bird_x > 0:
                        bird_x -= 1
                        last_direction = 'left'
                    elif event.key == pygame.K_d and bird_x < GRID_SIZE - 1:
                        bird_x += 1
                        last_direction = 'right'
                    if (bird_x, bird_y) != (old_x, old_y):
                        player_moved_this_turn = True
                        if check_collision():
                            state['game_over'] = True
                        else:
                            if state['apple_pos'] and (bird_x, bird_y) == state['apple_pos']:
                                state['apples_collected'] += 1
                                if state['apples_collected'] >= 17:
                                    state['victory'] = True
                                else:
                                    spawn_apple()
                    turn_state = 'enemies'
            elif event.type == pygame.KEYDOWN and (state['game_over'] or state['victory']):
                if event.key == pygame.K_r:
                    show_challenge3()
                    return
                elif event.key == pygame.K_q:
                    current_state = "menu"
                    running = False

        if not state['game_over'] and not state['victory'] and turn_state == 'enemies':
            update_enemies()
            spawn_enemy_if_needed()
            if check_collision():
                state['game_over'] = True
            turn_state = 'player'
            player_moved_this_turn = False
            turn_count += 1

        # Отрисовка (аналогично challenge1, но используем стиль по умолчанию)
        screen.fill(WHITE)
        draw_grid()
        for e in enemies:
            if isinstance(e, Snake):
                e.draw(screen)
            elif isinstance(e, Spider):
                e.draw(screen)
            elif isinstance(e, Slime):
                e.draw(screen)
            elif isinstance(e, Shadow):
                e.draw(screen)
        for fb in fireballs + spider_fireballs + slime_balls:
            fb.draw(screen)
        for gc in gas_clouds + slime_gas_clouds:
            gc.draw(screen)
        for ic in invisible_clouds:
            ic.draw(screen)
        if state['apple_pos']:
            ax, ay = state['apple_pos']
            rect = pygame.Rect(ax * CELL_SIZE, ay * CELL_SIZE, CELL_SIZE, CELL_SIZE)
            pygame.draw.circle(screen, (255, 0, 0), rect.center, CELL_SIZE // 3)
        draw_bird(screen, bird_x, bird_y, True)

        apple_text = small_font.render(f"Яблок: {state['apples_collected']} / 17", True, BLACK)
        screen.blit(apple_text, (WIDTH - 200, 10))

        if state['game_over']:
            overlay = pygame.Surface((WIDTH, HEIGHT))
            overlay.set_alpha(200)
            overlay.fill(BLACK)
            screen.blit(overlay, (0, 0))
            texts = [font.render("ПОРАЖЕНИЕ!", True, RED_SNAKE),
                     small_font.render("R - рестарт | Q - выход", True, GREEN)]
            y_text = HEIGHT // 2 - 40
            for text in texts:
                rect = text.get_rect(center=(WIDTH // 2, y_text))
                screen.blit(text, rect)
                y_text += 40
        elif state['victory']:
            overlay = pygame.Surface((WIDTH, HEIGHT))
            overlay.set_alpha(200)
            overlay.fill(BLACK)
            screen.blit(overlay, (0, 0))
            texts = [font.render("ПОБЕДА!", True, GREEN),
                     small_font.render("R - рестарт | Q - выход", True, GREEN)]
            y_text = HEIGHT // 2 - 40
            for text in texts:
                rect = text.get_rect(center=(WIDTH // 2, y_text))
                screen.blit(text, rect)
                y_text += 40

        pygame.display.flip()
        clock.tick(FPS)

def show_challenge4():
    global current_state
    bird_x, bird_y = GRID_SIZE // 2, GRID_SIZE // 2
    last_direction = 'up'
    state = {'killed': 0, 'victory': False, 'game_over': False}
    enemies = []
    fireballs = []
    gas_clouds = []
    invisible_clouds = []
    spider_fireballs = []
    slime_balls = []
    slime_gas_clouds = []
    turn_count = 0
    turn_state = 'player'
    player_moved_this_turn = False

    MAX_ENEMIES = 4
    SPAWN_CHANCE = 0.5

    # Начальные враги: по одному радужному каждого вида
    enemies.append(create_snake_at_edge("rainbow_snake"))
    sh_spider = Shadow(random.randint(0, GRID_SIZE-1), random.randint(0, GRID_SIZE-1), 1, 3, "rainbow_spider")
    enemies.append(sh_spider)
    enemies.append(spawn_slime("rainbow_slime"))

    def spawn_enemy_if_needed():
        if len(enemies) >= MAX_ENEMIES:
            return
        if random.random() > SPAWN_CHANCE:
            return
        enemy_type = random.choice(["rainbow_snake", "rainbow_spider", "rainbow_slime"])
        if enemy_type == "rainbow_snake":
            new_snake = create_snake_at_edge("rainbow_snake")
            collision = any(isinstance(e, Snake) and new_snake.get_all_positions() & e.get_all_positions() for e in enemies)
            if not collision:
                enemies.append(new_snake)
        elif enemy_type == "rainbow_spider":
            size = 1
            max_attempts = 20
            for _ in range(max_attempts):
                x = random.randint(0, GRID_SIZE - size)
                y = random.randint(0, GRID_SIZE - size)
                occupied = set()
                for e in enemies:
                    if isinstance(e, Spider):
                        occupied.update(e.get_positions())
                    elif isinstance(e, Shadow):
                        for i in range(e.size):
                            for j in range(e.size):
                                occupied.add((e.x + i, e.y + j))
                collision = any((x + i, y + j) in occupied for i in range(size) for j in range(size))
                if not collision:
                    enemies.append(Shadow(x, y, size, 3, enemy_type))
                    break
        else:  # rainbow_slime
            new_slime = spawn_slime("rainbow_slime")
            collision = any(isinstance(e, Slime) and e.get_pos() == new_slime.get_pos() for e in enemies)
            if not collision:
                enemies.append(new_slime)

    def update_enemies():
        nonlocal state
        snakes = [e for e in enemies if isinstance(e, Snake)]
        spiders = [e for e in enemies if isinstance(e, Spider)]
        slimes = [e for e in enemies if isinstance(e, Slime)]
        shadows = [e for e in enemies if isinstance(e, Shadow)]
        for sh in shadows[:]:
            if sh.update():
                spider = Spider(sh.x, sh.y, sh.spider_type)
                enemies.append(spider)
                enemies.remove(sh)
        for snake in snakes:
            snake.move(bird_x, bird_y, fireballs, invisible_clouds)
            if snake.is_completely_off_grid():
                enemies.remove(snake)
                state['killed'] += 1
        for spider in spiders:
            spider.update(spider_fireballs, gas_clouds, bird_x, bird_y)
            if not spider.active:
                enemies.remove(spider)
                state['killed'] += 1
        new_slimes = []
        for slime in slimes[:]:
            slime.update(slime_balls, slime_gas_clouds, invisible_clouds, new_slimes)
            if not slime.active:
                enemies.remove(slime)
                state['killed'] += 1
        enemies.extend(new_slimes)

        for fb_list in [fireballs, spider_fireballs, slime_balls]:
            for fb in fb_list[:]:
                if hasattr(fb, 'move'):
                    fb.move()
                elif hasattr(fb, 'update'):
                    fb.update()
                if not fb.active:
                    fb_list.remove(fb)
        for gc_list in [gas_clouds, slime_gas_clouds]:
            for gc in gc_list[:]:
                gc.update()
                if not gc.active:
                    gc_list.remove(gc)
        for ic in invisible_clouds[:]:
            ic.update()
            if not ic.active:
                invisible_clouds.remove(ic)

        if state['killed'] >= 20:
            state['victory'] = True

    def check_collision():
        bird_pos = (bird_x, bird_y)
        for e in enemies:
            if isinstance(e, Snake):
                if bird_pos in e.get_all_positions():
                    return True
            elif isinstance(e, Spider):
                if bird_pos in e.get_positions():
                    return True
            elif isinstance(e, Slime):
                if e.get_pos() == bird_pos and e.slime_type not in ("light_gray_slime", "white_slime"):
                    return True
        for fb_list in [fireballs, spider_fireballs, slime_balls]:
            for fb in fb_list:
                if not fb.active:
                    continue
                if hasattr(fb, 'get_positions'):
                    if bird_pos in fb.get_positions():
                        return True
                elif hasattr(fb, 'get_pos'):
                    if fb.get_pos() == bird_pos:
                        return True
        for gc_list in [gas_clouds, slime_gas_clouds]:
            for gc in gc_list:
                if bird_pos in gc.get_affected_cells():
                    return True
        return False

    running = True
    while running and current_state == "challenge4":
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                current_state = "menu"
                running = False
            elif event.type == pygame.KEYDOWN and not state['game_over'] and not state['victory']:
                if turn_state == 'player' and not player_moved_this_turn:
                    old_x, old_y = bird_x, bird_y
                    if event.key == pygame.K_w and bird_y > 0:
                        bird_y -= 1
                        last_direction = 'up'
                    elif event.key == pygame.K_s and bird_y < GRID_SIZE - 1:
                        bird_y += 1
                        last_direction = 'down'
                    elif event.key == pygame.K_a and bird_x > 0:
                        bird_x -= 1
                        last_direction = 'left'
                    elif event.key == pygame.K_d and bird_x < GRID_SIZE - 1:
                        bird_x += 1
                        last_direction = 'right'
                    if (bird_x, bird_y) != (old_x, old_y):
                        player_moved_this_turn = True
                        if check_collision():
                            state['game_over'] = True
                    turn_state = 'enemies'
            elif event.type == pygame.KEYDOWN and (state['game_over'] or state['victory']):
                if event.key == pygame.K_r:
                    show_challenge4()
                    return
                elif event.key == pygame.K_q:
                    current_state = "menu"
                    running = False

        if not state['game_over'] and not state['victory'] and turn_state == 'enemies':
            update_enemies()
            spawn_enemy_if_needed()
            if check_collision():
                state['game_over'] = True
            turn_state = 'player'
            player_moved_this_turn = False
            turn_count += 1

        screen.fill(WHITE)
        draw_grid()
        for e in enemies:
            if isinstance(e, Snake):
                e.draw(screen)
            elif isinstance(e, Spider):
                e.draw(screen)
            elif isinstance(e, Slime):
                e.draw(screen)
            elif isinstance(e, Shadow):
                e.draw(screen)
        for fb in fireballs + spider_fireballs + slime_balls:
            fb.draw(screen)
        for gc in gas_clouds + slime_gas_clouds:
            gc.draw(screen)
        for ic in invisible_clouds:
            ic.draw(screen)
        draw_bird(screen, bird_x, bird_y, True)

        kills_text = small_font.render(f"Убито: {state['killed']} / 20", True, BLACK)
        screen.blit(kills_text, (WIDTH - 200, 10))

        if state['game_over']:
            overlay = pygame.Surface((WIDTH, HEIGHT))
            overlay.set_alpha(200)
            overlay.fill(BLACK)
            screen.blit(overlay, (0, 0))
            texts = [font.render("ПОРАЖЕНИЕ!", True, RED_SNAKE),
                     small_font.render("R - рестарт | Q - выход", True, GREEN)]
            y_text = HEIGHT // 2 - 40
            for text in texts:
                rect = text.get_rect(center=(WIDTH // 2, y_text))
                screen.blit(text, rect)
                y_text += 40
        elif state['victory']:
            overlay = pygame.Surface((WIDTH, HEIGHT))
            overlay.set_alpha(200)
            overlay.fill(BLACK)
            screen.blit(overlay, (0, 0))
            texts = [font.render("ПОБЕДА!", True, GREEN),
                     small_font.render("R - рестарт | Q - выход", True, GREEN)]
            y_text = HEIGHT // 2 - 40
            for text in texts:
                rect = text.get_rect(center=(WIDTH // 2, y_text))
                screen.blit(text, rect)
                y_text += 40

        pygame.display.flip()
        clock.tick(FPS)

def show_challenge5():
    global current_state
    bird_x, bird_y = GRID_SIZE // 2, GRID_SIZE // 2
    last_direction = 'up'
    state = {'apples_collected': 0, 'apple_pos': None, 'victory': False, 'game_over': False}
    enemies = []
    fireballs = []
    gas_clouds = []
    invisible_clouds = []
    spider_fireballs = []
    slime_balls = []
    slime_gas_clouds = []
    lava_cells_temp = []
    turn_count = 0
    turn_state = 'player'
    player_moved_this_turn = False

    MAX_ENEMIES = 10
    SPAWN_CHANCE = 0.35

    def spawn_apple():
        occupied = set()
        for e in enemies:
            if isinstance(e, Snake):
                occupied.update(e.get_all_positions())
            elif isinstance(e, Spider):
                occupied.update(e.get_positions())
            elif isinstance(e, Slime):
                occupied.add(e.get_pos())
            elif isinstance(e, Shadow):
                for i in range(e.size):
                    for j in range(e.size):
                        occupied.add((e.x + i, e.y + j))
        free = [(x, y) for x in range(GRID_SIZE) for y in range(GRID_SIZE)
                if (x, y) not in occupied and (x, y) != (bird_x, bird_y)]
        if free:
            state['apple_pos'] = random.choice(free)
        else:
            state['apple_pos'] = None

    # Начальные враги
    enemies.append(create_snake_at_edge("dark_blue"))
    enemies.append(create_snake_at_edge("white_red"))
    enemies.append(create_snake_at_edge("pink_azure"))
    enemies.append(spawn_slime("bright_orange_slime", lava_cells_list=lava_cells_temp))
    sh = Shadow(random.randint(0, GRID_SIZE-2), random.randint(0, GRID_SIZE-2), 2, 5, "dark_red")
    enemies.append(sh)
    spawn_apple()

    def spawn_enemy_if_needed():
        if len(enemies) >= MAX_ENEMIES:
            return
        if random.random() > SPAWN_CHANCE:
            return
        available_types = ["dark_blue", "white_red", "pink_azure", "bright_orange_slime", "dark_red"]
        enemy_type = random.choice(available_types)
        if enemy_type in ("dark_blue", "white_red", "pink_azure"):
            new_snake = create_snake_at_edge(enemy_type)
            collision = False
            for e in enemies:
                if isinstance(e, Snake):
                    if new_snake.get_all_positions() & e.get_all_positions():
                        collision = True
                        break
                elif isinstance(e, Spider):
                    if new_snake.get_all_positions() & e.get_positions():
                        collision = True
                        break
                elif isinstance(e, Slime):
                    if any(pos == e.get_pos() for pos in new_snake.get_all_positions()):
                        collision = True
                        break
            if not collision:
                enemies.append(new_snake)
        elif enemy_type == "bright_orange_slime":
            new_slime = spawn_slime(enemy_type, lava_cells_list=lava_cells_temp)
            collision = any(isinstance(e, Slime) and e.get_pos() == new_slime.get_pos() for e in enemies)
            if not collision:
                enemies.append(new_slime)
        else:  # dark_red
            size = 2
            max_attempts = 20
            for _ in range(max_attempts):
                x = random.randint(0, GRID_SIZE - size)
                y = random.randint(0, GRID_SIZE - size)
                occupied = set()
                for e in enemies:
                    if isinstance(e, Spider):
                        occupied.update(e.get_positions())
                    elif isinstance(e, Shadow):
                        for i in range(e.size):
                            for j in range(e.size):
                                occupied.add((e.x + i, e.y + j))
                collision = any((x + i, y + j) in occupied for i in range(size) for j in range(size))
                if not collision:
                    enemies.append(Shadow(x, y, size, 5, enemy_type))
                    break

    def update_enemies():
        snakes = [e for e in enemies if isinstance(e, Snake)]
        spiders = [e for e in enemies if isinstance(e, Spider)]
        slimes = [e for e in enemies if isinstance(e, Slime)]
        shadows = [e for e in enemies if isinstance(e, Shadow)]
        for sh in shadows[:]:
            if sh.update():
                spider = Spider(sh.x, sh.y, sh.spider_type)
                enemies.append(spider)
                enemies.remove(sh)
        for snake in snakes:
            snake.move(bird_x, bird_y, fireballs, invisible_clouds)
            if snake.is_completely_off_grid():
                enemies.remove(snake)
        for spider in spiders:
            spider.update(spider_fireballs, gas_clouds, bird_x, bird_y)
            if not spider.active:
                enemies.remove(spider)
        new_slimes = []
        for slime in slimes[:]:
            slime.update(slime_balls, slime_gas_clouds, invisible_clouds, new_slimes, lava_cells_temp)
            if not slime.active:
                enemies.remove(slime)
        enemies.extend(new_slimes)
        # Лава
        for lava in lava_cells_temp[:]:
            lava.update()
            if not lava.active:
                lava_cells_temp.remove(lava)

        for fb_list in [fireballs, spider_fireballs, slime_balls]:
            for fb in fb_list[:]:
                if hasattr(fb, 'move'):
                    fb.move()
                elif hasattr(fb, 'update'):
                    fb.update()
                if not fb.active:
                    fb_list.remove(fb)
        for gc_list in [gas_clouds, slime_gas_clouds]:
            for gc in gc_list[:]:
                gc.update()
                if not gc.active:
                    gc_list.remove(gc)
        for ic in invisible_clouds[:]:
            ic.update()
            if not ic.active:
                invisible_clouds.remove(ic)

        if state['apple_pos'] and (bird_x, bird_y) == state['apple_pos']:
            state['apples_collected'] += 1
            if state['apples_collected'] >= 25:
                state['victory'] = True
            else:
                spawn_apple()

    def check_collision():
        bird_pos = (bird_x, bird_y)
        for e in enemies:
            if isinstance(e, Snake):
                if bird_pos in e.get_all_positions():
                    return True
            elif isinstance(e, Spider):
                if bird_pos in e.get_positions():
                    return True
            elif isinstance(e, Slime):
                if e.get_pos() == bird_pos and e.slime_type not in ("light_gray_slime", "white_slime"):
                    return True
        for fb_list in [fireballs, spider_fireballs, slime_balls]:
            for fb in fb_list:
                if not fb.active:
                    continue
                if hasattr(fb, 'get_positions'):
                    if bird_pos in fb.get_positions():
                        return True
                elif hasattr(fb, 'get_pos'):
                    if fb.get_pos() == bird_pos:
                        return True
        for gc_list in [gas_clouds, slime_gas_clouds]:
            for gc in gc_list:
                if bird_pos in gc.get_affected_cells():
                    return True
        for lava in lava_cells_temp:
            if lava.active and lava.get_pos() == bird_pos:
                return True
        return False

    running = True
    while running and current_state == "challenge5":
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                current_state = "menu"
                running = False
            elif event.type == pygame.KEYDOWN and not state['game_over'] and not state['victory']:
                if turn_state == 'player' and not player_moved_this_turn:
                    old_x, old_y = bird_x, bird_y
                    if event.key == pygame.K_w and bird_y > 0:
                        bird_y -= 1
                        last_direction = 'up'
                    elif event.key == pygame.K_s and bird_y < GRID_SIZE - 1:
                        bird_y += 1
                        last_direction = 'down'
                    elif event.key == pygame.K_a and bird_x > 0:
                        bird_x -= 1
                        last_direction = 'left'
                    elif event.key == pygame.K_d and bird_x < GRID_SIZE - 1:
                        bird_x += 1
                        last_direction = 'right'
                    if (bird_x, bird_y) != (old_x, old_y):
                        player_moved_this_turn = True
                        if check_collision():
                            state['game_over'] = True
                        else:
                            if state['apple_pos'] and (bird_x, bird_y) == state['apple_pos']:
                                state['apples_collected'] += 1
                                if state['apples_collected'] >= 25:
                                    state['victory'] = True
                                else:
                                    spawn_apple()
                    turn_state = 'enemies'
            elif event.type == pygame.KEYDOWN and (state['game_over'] or state['victory']):
                if event.key == pygame.K_r:
                    show_challenge5()
                    return
                elif event.key == pygame.K_q:
                    current_state = "menu"
                    running = False

        if not state['game_over'] and not state['victory'] and turn_state == 'enemies':
            update_enemies()
            spawn_enemy_if_needed()
            if check_collision():
                state['game_over'] = True
            turn_state = 'player'
            player_moved_this_turn = False
            turn_count += 1

        screen.fill(WHITE)
        draw_grid()
        for lava in lava_cells_temp:
            if lava.active:
                lava.draw(screen)
        for e in enemies:
            if isinstance(e, Snake):
                e.draw(screen)
            elif isinstance(e, Spider):
                e.draw(screen)
            elif isinstance(e, Slime):
                e.draw(screen)
            elif isinstance(e, Shadow):
                e.draw(screen)
        for fb in fireballs + spider_fireballs + slime_balls:
            fb.draw(screen)
        for gc in gas_clouds + slime_gas_clouds:
            gc.draw(screen)
        for ic in invisible_clouds:
            ic.draw(screen)
        if state['apple_pos']:
            ax, ay = state['apple_pos']
            rect = pygame.Rect(ax * CELL_SIZE, ay * CELL_SIZE, CELL_SIZE, CELL_SIZE)
            pygame.draw.circle(screen, (255, 0, 0), rect.center, CELL_SIZE // 3)
        draw_bird(screen, bird_x, bird_y, True)

        apple_text = small_font.render(f"Яблок: {state['apples_collected']} / 25", True, BLACK)
        screen.blit(apple_text, (WIDTH - 200, 10))

        if state['game_over']:
            overlay = pygame.Surface((WIDTH, HEIGHT))
            overlay.set_alpha(200)
            overlay.fill(BLACK)
            screen.blit(overlay, (0, 0))
            texts = [font.render("ПОРАЖЕНИЕ!", True, RED_SNAKE),
                     small_font.render("R - рестарт | Q - выход", True, GREEN)]
            y_text = HEIGHT // 2 - 40
            for text in texts:
                rect = text.get_rect(center=(WIDTH // 2, y_text))
                screen.blit(text, rect)
                y_text += 40
        elif state['victory']:
            overlay = pygame.Surface((WIDTH, HEIGHT))
            overlay.set_alpha(200)
            overlay.fill(BLACK)
            screen.blit(overlay, (0, 0))
            texts = [font.render("ПОБЕДА!", True, GREEN),
                     small_font.render("R - рестарт | Q - выход", True, GREEN)]
            y_text = HEIGHT // 2 - 40
            for text in texts:
                rect = text.get_rect(center=(WIDTH // 2, y_text))
                screen.blit(text, rect)
                y_text += 40

        pygame.display.flip()
        clock.tick(FPS)

def start_game_mode(mode):
    global current_state, selected_abilities
    selected_abilities = {}
    current_state = "ability_selection"
    global game_mode
    game_mode = mode
    show_ability_selection(mode)

game_mode = None

def show_ability_selection(mode):
    global current_state, selected_abilities
    max_slots = 5 if mode != "sandbox" else float('inf')
    selected = {i: False for i in range(len(ABILITY_INFO))}
    back_button = Button(WIDTH // 2 - 150, HEIGHT - 70, 300, 50, "Начать игру",
                         action=lambda: start_game_with_abilities())

    def start_game_with_abilities():
        nonlocal selected
        global current_state, selected_abilities
        chosen = {}
        total_slots = 0
        for idx, info in enumerate(ABILITY_INFO):
            if selected[idx]:
                total_slots += info["slots"]
        if total_slots <= max_slots or max_slots == float('inf'):
            for idx, info in enumerate(ABILITY_INFO):
                if selected[idx]:
                    chosen[info["name"]] = {
                        "uses": info["uses"],
                        "cooldown": 0,
                        "slots": info["slots"],
                        "key": info["key"],
                        "max_uses": info["uses"],
                        "max_cooldown": info["cooldown"]
                    }
            selected_abilities = chosen
            if mode == "snakes":
                current_state = "game"
            elif mode == "spiders":
                current_state = "spider_game"
            elif mode == "slimes":
                current_state = "slime_game"
            elif mode == "insects":
                current_state = "insect_game"
            elif mode == "fish":
                current_state = "fish_game"
            elif mode == "sandbox":
                current_state = "sandbox_play"
            elif mode.startswith("level"):  # <-- добавить
                current_state = mode  # "level1" или "level2"
        else:
            pass

    while current_state == "ability_selection":
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                sys.exit()
            elif event.type == pygame.MOUSEBUTTONDOWN:
                if event.button == 1:
                    mouse_x, mouse_y = event.pos
                    for idx, info in enumerate(ABILITY_INFO):
                        rect = pygame.Rect(WIDTH // 2 - 300, 150 + idx * 45, 30, 30)
                        if rect.collidepoint(mouse_x, mouse_y):
                            selected[idx] = not selected[idx]
            back_button.handle_event(event)

        screen.fill(MENU_BG)
        title = font.render("Выберите способности", True, BLACK)
        screen.blit(title, (WIDTH // 2 - title.get_width() // 2, 50))

        total_slots = sum(ABILITY_INFO[idx]["slots"] for idx, sel in selected.items() if sel)
        slot_text = f"Занято ячеек: {total_slots} / {max_slots if max_slots != float('inf') else '∞'}"
        slot_surf = small_font.render(slot_text, True, BLACK if total_slots <= max_slots else RED_SNAKE)
        screen.blit(slot_surf, (WIDTH // 2 - slot_surf.get_width() // 2, 100))

        y = 150
        for idx, info in enumerate(ABILITY_INFO):
            row_rect = pygame.Rect(WIDTH // 2 - 320, y, 640, 40)
            pygame.draw.rect(screen, (220, 220, 220), row_rect, border_radius=5)
            cb_rect = pygame.Rect(WIDTH // 2 - 300, y + 5, 30, 30)
            pygame.draw.rect(screen, BLACK, cb_rect, 2)
            if selected[idx]:
                pygame.draw.line(screen, BLACK, (cb_rect.left + 4, cb_rect.centery),
                                 (cb_rect.centerx, cb_rect.bottom - 4), 4)
                pygame.draw.line(screen, BLACK, (cb_rect.centerx, cb_rect.bottom - 4),
                                 (cb_rect.right - 4, cb_rect.top + 4), 4)
            name_surf = small_font.render(f"{info['name']} (клавиша {info['key']}) - {info['slots']} яч.", True, BLACK)
            screen.blit(name_surf, (WIDTH // 2 - 250, y + 10))
            desc_surf = micro_font.render(info["description"], True, (50, 50, 50))
            screen.blit(desc_surf, (WIDTH // 2 - 250, y + 25))
            y += 45

        back_button.draw(screen)
        pygame.display.flip()
        clock.tick(FPS)

def show_controls():
    global current_state
    back_button = Button(WIDTH // 2 - 100, HEIGHT - 70, 200, 50, "В меню", action=lambda: go_to_menu())
    while current_state == "controls":
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                sys.exit()
            back_button.handle_event(event)
        screen.fill(MENU_BG)
        title = font.render("Управление", True, BLACK)
        screen.blit(title, (WIDTH // 2 - title.get_width() // 2, 40))
        lines = [
            "Вы играете за птичку на поле 17x17.",
            "Цель: уклоняться от врагов.",
            "",
            "Управление:",
            "W, A, S, D - движение вверх, влево, вниз, вправо (пошагово).",
            "1-7 - использование способностей.",
            "R - перезапуск игры после поражения.",
            "Q - выход в главное меню.",
            "",
            "Совет: изучайте врагов и способности в Бестиарии."
        ]
        y = 130
        for line in lines:
            text = small_font.render(line, True, BLACK)
            screen.blit(text, (50, y))
            y += 30
        back_button.draw(screen)
        pygame.display.flip()

def show_skin_select():
    global current_state, bird_skin
    back_button = Button(WIDTH // 2 - 100, HEIGHT - 70, 200, 50, "Назад", action=go_to_menu)
    buttons = [
        Button(WIDTH // 2 - 350, 200, 120, 50, "Серый", action=lambda: set_skin(0)),
        Button(WIDTH // 2 - 350, 300, 120, 50, "РЎРёРЅРёР№", action=lambda: set_skin(1)),
        Button(WIDTH // 2 - 350, 400, 120, 50, "Красный", action=lambda: set_skin(2)),
        Button(WIDTH // 2 - 350, 500, 120, 50, "Жёлтый", action=lambda: set_skin(3)),
        Button(WIDTH // 2 - 350, 600, 120, 50, "Чёрный", action=lambda: set_skin(4)),
    ]

    def set_skin(skin):
        global bird_skin
        bird_skin = skin

    while current_state == "skin_select":
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                sys.exit()
            back_button.handle_event(event)
            for btn in buttons:
                btn.handle_event(event)
        screen.fill(MENU_BG)
        title = font.render("Выберите скин птички", True, BLACK)
        screen.blit(title, (WIDTH // 2 - title.get_width() // 2, 100))
        preview_x = WIDTH // 2
        preview_y = 280
        draw_bird(screen, preview_x // CELL_SIZE, preview_y // CELL_SIZE, True)
        for btn in buttons:
            btn.draw(screen)
        back_button.draw(screen)
        pygame.display.flip()

def show_settings():
    global current_state, fullscreen, screen, WIDTH, HEIGHT, CELL_SIZE, survival_records

    def reset_records():
        global survival_records
        survival_records = {"snakes": 0, "spiders": 0, "slimes": 0, "insects": 0, "fish": 0}
        save_records(survival_records)

    back_button = Button(WIDTH // 2 - 250, HEIGHT - 70, 500, 50, "Назад", action=lambda: go_to_menu())
    toggle_button = Button(WIDTH // 2 - 250, 200, 500, 50,
                           "Оконный режим (пока не доработано)" if fullscreen else "Полный экран (пока не доработано)",
                           action=toggle_fullscreen)
    reset_records_button = Button(WIDTH // 2 - 250, 270, 500, 50, "Сбросить рекорды выживания",
                                  action=reset_records)

    while current_state == "settings":
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                sys.exit()
            back_button.handle_event(event)
            toggle_button.handle_event(event)
            reset_records_button.handle_event(event)

        screen.fill(MENU_BG)
        title = font.render("Настройки", True, BLACK)
        screen.blit(title, (WIDTH // 2 - title.get_width() // 2, 80))
        toggle_button.draw(screen)
        reset_records_button.draw(screen)
        back_button.draw(screen)
        pygame.display.flip()

def toggle_fullscreen():
    global fullscreen, screen, WIDTH, HEIGHT, CELL_SIZE
    fullscreen = not fullscreen
    if fullscreen:
        screen = pygame.display.set_mode((0, 0), pygame.FULLSCREEN)
        info = pygame.display.Info()
        WIDTH, HEIGHT = info.current_w, info.current_h
        CELL_SIZE = min(WIDTH, HEIGHT) // GRID_SIZE
        WIDTH = GRID_SIZE * CELL_SIZE
        HEIGHT = GRID_SIZE * CELL_SIZE
        screen = pygame.display.set_mode((WIDTH, HEIGHT), pygame.FULLSCREEN)
    else:
        CELL_SIZE = 45
        WIDTH = GRID_SIZE * CELL_SIZE
        HEIGHT = GRID_SIZE * CELL_SIZE
        screen = pygame.display.set_mode((WIDTH, HEIGHT))

def show_bestiary():
    global current_state
    bestiary_tab = 0  # 0 - змеи, 1 - пауки, 2 - слизни, 3 - насекомые, 4 - рыбы, 5 - другое
    back_button = Button(WIDTH // 2 - 300, HEIGHT - 750, 600, 50, "В меню", action=lambda: go_to_menu())
    snake_btn = Button(WIDTH // 2 - 375, 70, 120, 40, "Змеи", action=lambda: set_tab(0), color=(100, 200, 100),
                       hover_color=(50, 150, 50), font=small_font)
    spider_btn = Button(WIDTH // 2 - 248, 70, 120, 40, "Пауки", action=lambda: set_tab(1), color=(100, 100, 200),
                        hover_color=(50, 50, 150), font=small_font)
    slime_btn = Button(WIDTH // 2 - 123, 70, 120, 40, "Слизни", action=lambda: set_tab(2), color=(200, 200, 100),
                       hover_color=(150, 150, 50), font=small_font)
    insect_btn = Button(WIDTH // 2 + 3, 70, 120, 40, "Насекомые", action=lambda: set_tab(3), color=(139, 69, 19),
                        hover_color=(101, 67, 33), font=small_font)
    fish_btn = Button(WIDTH // 2 + 128, 70, 120, 40, "Рыбы", action=lambda: set_tab(4), color=(100, 200, 255),
                      hover_color=(50, 150, 200), font=small_font)
    other_btn = Button(WIDTH // 2 + 255, 70, 120, 40, "Другое", action=lambda: set_tab(5), color=(200, 150, 200),
                       hover_color=(150, 100, 150), font=small_font)

    def set_tab(idx):
        nonlocal bestiary_tab
        bestiary_tab = idx

    current_snake_tab = 0
    tab_buttons_snakes = []
    tab_width = 130
    tab_height = 40
    tab_gap = 15
    n_tabs_snakes = len(TAB_NAMES_SNAKES)
    total_width_snakes = n_tabs_snakes * tab_width + (n_tabs_snakes - 1) * tab_gap
    tab_start_x_snakes = (WIDTH - total_width_snakes) // 2
    for i, name in enumerate(TAB_NAMES_SNAKES):
        if name == "Зелёные":
            color = (100, 200, 100)
            hover = (50, 150, 50)
        elif name == "РЎРёРЅРёРµ":
            color = (100, 100, 200)
            hover = (50, 50, 150)
        elif name == "Белые":
            color = (200, 200, 200)
            hover = (150, 150, 150)
        elif name == "РњРёРЅРёР±РѕСЃСЃС‹":
            color = (200, 100, 100)
            hover = (150, 50, 50)
        else:
            color = (200, 150, 200)
            hover = (150, 100, 150)
        x = tab_start_x_snakes + i * (tab_width + tab_gap)
        btn = Button(x, 120, tab_width, tab_height, name,
                     action=lambda idx=i: set_snake_tab(idx),
                     color=color, hover_color=hover, text_color=BLACK, font=small_font)
        tab_buttons_snakes.append(btn)

    current_spider_tab = 0
    tab_buttons_spiders = []
    n_tabs_spiders = len(TAB_NAMES_SPIDERS)
    total_width_spiders = n_tabs_spiders * tab_width + (n_tabs_spiders - 1) * tab_gap
    tab_start_x_spiders = (WIDTH - total_width_spiders) // 2
    for i, name in enumerate(TAB_NAMES_SPIDERS):
        color = (150, 150, 150)
        hover = (100, 100, 100)
        if name == "Радужные":
            color = (200, 150, 200)
            hover = (150, 100, 150)
        x = tab_start_x_spiders + i * (tab_width + tab_gap)
        btn = Button(x, 120, tab_width, tab_height, name,
                     action=lambda idx=i: set_spider_tab(idx),
                     color=color, hover_color=hover, text_color=BLACK, font=small_font)
        tab_buttons_spiders.append(btn)

    current_slime_tab = 0
    tab_buttons_slimes = []
    n_tabs_slimes = len(TAB_NAMES_SLIMES)
    total_width_slimes = n_tabs_slimes * tab_width + (n_tabs_slimes - 1) * tab_gap
    tab_start_x_slimes = (WIDTH - total_width_slimes) // 2
    for i, name in enumerate(TAB_NAMES_SLIMES):
        color = (200, 200, 100)
        hover = (150, 150, 50)
        if name == "Чёрные слизни":
            color = (100, 100, 100)
            hover = (70, 70, 70)
        elif name == "Радужные":
            color = (200, 150, 200)
            hover = (150, 100, 150)
        x = tab_start_x_slimes + i * (tab_width + tab_gap)
        btn = Button(x, 120, tab_width, tab_height, name,
                     action=lambda idx=i: set_slime_tab(idx),
                     color=color, hover_color=hover, text_color=BLACK, font=small_font)
        tab_buttons_slimes.append(btn)

    current_insect_tab = 0
    tab_buttons_insects = []
    n_tabs_insects = len(TAB_NAMES_INSECTS)
    total_width_insects = n_tabs_insects * tab_width + (n_tabs_insects - 1) * tab_gap
    tab_start_x_insects = (WIDTH - total_width_insects) // 2
    for i, name in enumerate(TAB_NAMES_INSECTS):
        color = (139, 69, 19)
        hover = (101, 67, 33)
        x = tab_start_x_insects + i * (tab_width + tab_gap)
        btn = Button(x, 120, tab_width, tab_height, name,
                     action=lambda idx=i: set_insect_tab(idx),
                     color=color, hover_color=hover, text_color=BLACK, font=small_font)
        tab_buttons_insects.append(btn)

    current_fish_tab = 0
    tab_buttons_fish = []
    fish_tab_names = ["Рыбы"]
    n_tabs_fish = len(fish_tab_names)
    total_width_fish = n_tabs_fish * tab_width + (n_tabs_fish - 1) * tab_gap
    tab_start_x_fish = (WIDTH - total_width_fish) // 2
    for i, name in enumerate(fish_tab_names):
        color = (100, 200, 255)
        hover = (50, 150, 200)
        x = tab_start_x_fish + i * (tab_width + tab_gap)
        btn = Button(x, 120, tab_width, tab_height, name,
                     action=lambda idx=i: set_fish_tab(idx),
                     color=color, hover_color=hover, text_color=BLACK, font=small_font)
        tab_buttons_fish.append(btn)

    current_other_tab = 0
    tab_buttons_other = []
    other_tab_names = ["Газы", "Снаряды", "Способности", "Усложнения"]
    n_tabs_other = len(other_tab_names)
    total_width_other = n_tabs_other * tab_width + (n_tabs_other - 1) * tab_gap
    tab_start_x_other = (WIDTH - total_width_other) // 2
    for i, name in enumerate(other_tab_names):
        color = (200, 150, 200)
        hover = (150, 100, 150)
        x = tab_start_x_other + i * (tab_width + tab_gap)
        btn = Button(x, 120, tab_width, tab_height, name,
                     action=lambda idx=i: set_other_tab(idx),
                     color=color, hover_color=hover, text_color=BLACK, font=small_font)
        tab_buttons_other.append(btn)

    def set_snake_tab(idx):
        nonlocal current_snake_tab
        current_snake_tab = idx

    def set_spider_tab(idx):
        nonlocal current_spider_tab
        current_spider_tab = idx

    def set_slime_tab(idx):
        nonlocal current_slime_tab
        current_slime_tab = idx

    def set_insect_tab(idx):
        nonlocal current_insect_tab
        current_insect_tab = idx

    def set_fish_tab(idx):
        nonlocal current_fish_tab
        current_fish_tab = idx

    def set_other_tab(idx):
        nonlocal current_other_tab
        current_other_tab = idx

    GASES_INFO = [
        {"name": "Ядовитое облако", "color": (100, 200, 100),
         "description": "Наносит урон при касании. Радиус и длительность зависят от источника."},
        {"name": "Невидимое облако", "color": (150, 150, 150),
         "description": "Скрывает врагов и снаряды внутри. Не наносит урона."},
        {"name": "Лава", "color": (255, 69, 0),
         "description": "Наносит урон при касании. Длительность зависит от источника."},
    ]
    PROJECTILES_INFO = [
        {"name": "Зелёный шар", "color": (100, 255, 100), "description": "Медленный шар слизней (скорость 0.5)."},
        {"name": "Оранжевый шар", "color": (255, 69, 0), "description": "Обычный огненный шар змей (скорость 1)."},
        {"name": "Фиолетовый шар", "color": PURPLE_FIRE,
         "description": "Быстрый шар (скорость 2), часто выпускается линиями."}
    ]

    while current_state == "bestiary":
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                sys.exit()
            back_button.handle_event(event)
            snake_btn.handle_event(event)
            spider_btn.handle_event(event)
            slime_btn.handle_event(event)
            insect_btn.handle_event(event)
            fish_btn.handle_event(event)
            other_btn.handle_event(event)
            if bestiary_tab == 0:
                for btn in tab_buttons_snakes:
                    btn.handle_event(event)
            elif bestiary_tab == 1:
                for btn in tab_buttons_spiders:
                    btn.handle_event(event)
            elif bestiary_tab == 2:
                for btn in tab_buttons_slimes:
                    btn.handle_event(event)
            elif bestiary_tab == 3:
                for btn in tab_buttons_insects:
                    btn.handle_event(event)
            elif bestiary_tab == 4:
                for btn in tab_buttons_fish:
                    btn.handle_event(event)
            else:
                for btn in tab_buttons_other:
                    btn.handle_event(event)

        screen.fill(MENU_BG)
        snake_btn.draw(screen)
        spider_btn.draw(screen)
        slime_btn.draw(screen)
        insect_btn.draw(screen)
        fish_btn.draw(screen)
        other_btn.draw(screen)

        if bestiary_tab == 0:
            for btn in tab_buttons_snakes:
                btn.draw(screen)
            start_x = 20
            start_y = 300
            row_height = 50
            col_widths = [130, 70, 80, 170, 170, 80]
            headers = ["Тип", "Длина", "Скорость", "Особенности", "Вид"]
            header_bg = (70, 70, 70)
            header_text_color = (255, 255, 255)

            category = TAB_NAMES_SNAKES[current_snake_tab]
            snake_types = TAB_CATEGORIES_SNAKES[category]
            snake_types = [st for st in SNAKE_INFO_ORDERED if st in snake_types]

            table_width = sum(col_widths) + 40
            table_height = row_height * (len(snake_types) + 1) + 20
            table_x = start_x - 15
            table_y = start_y - 40
            pygame.draw.rect(screen, (50, 50, 50), (table_x + 5, table_y + 5, table_width, table_height),
                             border_radius=10)
            pygame.draw.rect(screen, WHITE, (table_x, table_y, table_width, table_height), border_radius=10)

            title = font.render(f"Бестиарий — {category}", True, BLACK)
            screen.blit(title, (WIDTH // 2 - title.get_width() // 2, start_y - 130))

            desc_text = "Змеи длинные и выползают с краёв поля."
            desc_surf = small_font.render(desc_text, True, BLACK)
            screen.blit(desc_surf, (start_x, start_y - 80))

            x = start_x
            for i, header in enumerate(headers):
                header_surf = micro_font.render(header, True, header_text_color)
                pygame.draw.rect(screen, header_bg, (x - 5, start_y - 35, col_widths[i] + 10, row_height - 5))
                screen.blit(header_surf, (x + 5, start_y - 30))
                x += col_widths[i]
            pygame.draw.line(screen, BLACK, (start_x - 5, start_y - 10), (x + 15, start_y - 10), 2)

            y = start_y
            for idx, snake_type in enumerate(snake_types):
                info = SNAKE_INFO[snake_type]
                if idx % 2 == 0:
                    row_color = (240, 248, 255)
                else:
                    row_color = (255, 255, 240)
                pygame.draw.rect(screen, row_color, (start_x - 5, y - 5, x - start_x + 25, row_height))

                ru_names = {
                    "green": "Зелёная", "dark_green": "Тёмно-зелёная", "bright_green": "Ярко-зелёная",
                    "stripe_green": "Полосатая зелёная", "swamp_green": "Болотная",
                    "blue": "Синяя", "dark_blue": "Тёмно-синяя", "light_blue": "Светло-синяя",
                    "stripe_blue": "Полосатая синяя", "pink_azure": "Розово-лазурная",
                    "white": "Белая", "white_purple": "Бело-фиолетовая", "white_red": "Бело-красная",
                    "red": "Красная", "black": "Чёрная", "rainbow_snake": "Радужная", "white_gray": "Бело-серая"
                }
                type_surf = micro_font.render(ru_names.get(snake_type, snake_type), True, info.get("color", BLACK))
                screen.blit(type_surf, (start_x + 5, y + 15))
                len_surf = micro_font.render(str(info["length_range"]), True, BLACK)
                screen.blit(len_surf, (start_x + col_widths[0] + 5, y + 15))
                speed_surf = micro_font.render(str(info["speed"]), True, BLACK)
                screen.blit(speed_surf, (start_x + col_widths[0] + col_widths[1] + 5, y + 15))

                special_text = info["special"]
                if len(special_text) > 25:
                    lines = [special_text[i:i + 20] for i in range(0, len(special_text), 20)]
                    for li, line in enumerate(lines[:2]):
                        special_surf = micro_font.render(line, True, BLACK)
                        screen.blit(special_surf,
                                    (start_x + col_widths[0] + col_widths[1] + col_widths[2] + 5, y + 2 + li * 18))
                else:
                    special_surf = micro_font.render(special_text, True, BLACK)
                    screen.blit(special_surf, (start_x + col_widths[0] + col_widths[1] + col_widths[2] + 5, y + 15))
                icon_x = start_x + col_widths[0] + col_widths[1] + col_widths[2] + col_widths[3] + col_widths[4] + 15
                icon_y = y + 17
                head_color = info["head_color"]
                body_color = info["body_color"]
                if snake_type == "rainbow_snake":
                    hue = (pygame.time.get_ticks() // 10) % 360
                    c = pygame.Color(0)
                    c.hsva = (hue, 100, 100)
                    head_color = body_color = c
                pygame.draw.rect(screen, head_color, (icon_x, icon_y, 16, 16))
                pygame.draw.rect(screen, body_color, (icon_x + 16, icon_y, 16, 16))
                pygame.draw.rect(screen, BLACK, (icon_x, icon_y, 32, 16), 1)
                pygame.draw.circle(screen, WHITE, (icon_x + 4, icon_y + 4), 2)
                pygame.draw.circle(screen, BLACK, (icon_x + 4, icon_y + 4), 1)
                y += row_height

            pygame.draw.line(screen, BLACK, (start_x - 5, y), (x + 15, y), 2)

        elif bestiary_tab == 1:
            for btn in tab_buttons_spiders:
                btn.draw(screen)
            start_x = 20
            start_y = 300
            row_height = 70
            col_widths = [130, 50, 50, 50, 190, 70]
            headers = ["Тип", "Разм", "Пад", "Сид", "Особенности", "Вид"]
            header_bg = (70, 70, 70)
            header_text_color = (255, 255, 255)

            category = TAB_NAMES_SPIDERS[current_spider_tab]
            spider_types = SPIDER_CATEGORIES[category]
            spider_types = [st for st in SPIDER_INFO_ORDERED if st in spider_types]

            table_width = sum(col_widths) + 40
            table_height = row_height * (len(spider_types) + 1) + 20
            table_x = start_x - 15
            table_y = start_y - 40
            pygame.draw.rect(screen, (50, 50, 50), (table_x + 5, table_y + 5, table_width, table_height),
                             border_radius=10)
            pygame.draw.rect(screen, WHITE, (table_x, table_y, table_width, table_height), border_radius=10)

            title = font.render(f"Бестиарий — Пауки ({category})", True, BLACK)
            screen.blit(title, (WIDTH // 2 - title.get_width() // 2, start_y - 130))

            desc_text = "Пауки падают с неба с характерной тенью."
            desc_surf = small_font.render(desc_text, True, BLACK)
            screen.blit(desc_surf, (start_x, start_y - 80))

            x = start_x
            for i, header in enumerate(headers):
                header_surf = micro_font.render(header, True, header_text_color)
                pygame.draw.rect(screen, header_bg, (x - 5, start_y - 35, col_widths[i] + 10, row_height - 5))
                screen.blit(header_surf, (x + 5, start_y - 30))
                x += col_widths[i]
            pygame.draw.line(screen, BLACK, (start_x - 5, start_y - 10), (x + 15, start_y - 10), 2)

            y = start_y
            for idx, spider_type in enumerate(spider_types):
                info = SPIDER_INFO[spider_type]
                if idx % 2 == 0:
                    row_color = (240, 248, 255)
                else:
                    row_color = (255, 255, 240)
                pygame.draw.rect(screen, row_color, (start_x - 5, y - 5, x - start_x + 25, row_height))

                ru_names = {
                    "light_gray": "Светло-серый", "brown_gray": "Коричнево-серый",
                    "dark_gray_red_cross": "Тёмно-серый с крестом", "dark_gray_green_circle": "Тёмно-серый с кругом",
                    "dark_red": "Тёмно-красный", "big_dark_gray": "Большой тёмно-серый",
                    "big_dark_gray_green_circle": "Большой с зелёным кругом", "black_spider": "Чёрный",
                    "white_purple_circle": "Белый с фиолетовым", "rainbow_spider": "Радужный"
                }
                type_surf = micro_font.render(ru_names.get(spider_type, spider_type), True, info["color"])
                screen.blit(type_surf, (start_x + 5, y + 8))
                size_surf = micro_font.render(str(info["size"]), True, BLACK)
                screen.blit(size_surf, (start_x + col_widths[0] + 5, y + 25))
                fall_surf = micro_font.render(str(info["fall_time"]), True, BLACK)
                screen.blit(fall_surf, (start_x + col_widths[0] + col_widths[1] + 5, y + 25))
                sit_surf = micro_font.render(str(info["sit_time"]), True, BLACK)
                screen.blit(sit_surf, (start_x + col_widths[0] + col_widths[1] + col_widths[2] + 5, y + 25))

                special_text = info["special"]
                words = special_text.split()
                lines = []
                current_line = ""
                for w in words:
                    if len(current_line) + len(w) + 1 <= 25:
                        if current_line:
                            current_line += " "
                        current_line += w
                    else:
                        lines.append(current_line)
                        current_line = w
                if current_line:
                    lines.append(current_line)
                text_x = start_x + col_widths[0] + col_widths[1] + col_widths[2] + col_widths[3] + 5
                for line_idx, line in enumerate(lines[:2]):
                    special_surf = micro_font.render(line, True, BLACK)
                    screen.blit(special_surf, (text_x, y + 8 + line_idx * 18))

                icon_size = 32
                icon_x = start_x + col_widths[0] + col_widths[1] + col_widths[2] + col_widths[3] + col_widths[4] + 10
                icon_y = y + (row_height - icon_size) // 2
                spider_icon_surface = pygame.Surface((icon_size, icon_size))
                spider_icon_surface.fill(row_color)
                body_color = info["color"]
                if spider_type == "rainbow_spider":
                    hue = (pygame.time.get_ticks() // 10) % 360
                    c = pygame.Color(0)
                    c.hsva = (hue, 100, 100)
                    body_color = c
                if info["size"] == 1:
                    pygame.draw.rect(spider_icon_surface, body_color, (4, 4, icon_size - 8, icon_size - 8))
                    pygame.draw.rect(spider_icon_surface, (0, 0, 0), (4, 4, icon_size - 8, icon_size - 8), 1)
                    eye_r = max(2, icon_size // 10)
                    pygame.draw.circle(spider_icon_surface, WHITE, (icon_size // 3, icon_size // 3), eye_r)
                    pygame.draw.circle(spider_icon_surface, WHITE, (2 * icon_size // 3, icon_size // 3), eye_r)
                    pygame.draw.circle(spider_icon_surface, BLACK, (icon_size // 3, icon_size // 3), eye_r // 2)
                    pygame.draw.circle(spider_icon_surface, BLACK, (2 * icon_size // 3, icon_size // 3), eye_r // 2)
                    leg_color = (0, 0, 0)
                    for ox, oy in [(-6, -6), (6, -6), (-6, 6), (6, 6), (-8, 0), (8, 0), (0, -8), (0, 8)]:
                        pygame.draw.line(spider_icon_surface, leg_color, (icon_size // 2, icon_size // 2),
                                         (icon_size // 2 + ox // 2, icon_size // 2 + oy // 2), 1)
                else:
                    pygame.draw.rect(spider_icon_surface, body_color, (2, 2, icon_size - 4, icon_size - 4))
                    pygame.draw.rect(spider_icon_surface, (0, 0, 0), (2, 2, icon_size - 4, icon_size - 4), 1)

                if spider_type == "dark_gray_red_cross":
                    cx, cy = icon_size // 2, icon_size // 2
                    pygame.draw.line(spider_icon_surface, SPIDER_RED_CROSS, (cx - 8, cy), (cx + 8, cy), 2)
                    pygame.draw.line(spider_icon_surface, SPIDER_RED_CROSS, (cx, cy - 8), (cx, cy + 8), 2)
                elif spider_type in ("dark_gray_green_circle", "big_dark_gray_green_circle"):
                    cx, cy = icon_size // 2, icon_size // 2
                    pygame.draw.circle(spider_icon_surface, SPIDER_GREEN_CIRCLE, (cx, cy), icon_size // 4)
                    pygame.draw.circle(spider_icon_surface, BLACK, (cx, cy), icon_size // 4, 1)
                elif spider_type == "white_purple_circle":
                    cx, cy = icon_size // 2, icon_size // 2
                    pygame.draw.circle(spider_icon_surface, (128, 0, 128), (cx, cy), icon_size // 4)
                elif spider_type == "black_spider":
                    eye_r = max(3, icon_size // 8)
                    pygame.draw.circle(spider_icon_surface, RED_EYE, (icon_size // 3, icon_size // 3), eye_r)
                    pygame.draw.circle(spider_icon_surface, RED_EYE, (2 * icon_size // 3, icon_size // 3), eye_r)
                    pygame.draw.circle(spider_icon_surface, BLACK, (icon_size // 3, icon_size // 3), eye_r // 2)
                    pygame.draw.circle(spider_icon_surface, BLACK, (2 * icon_size // 3, icon_size // 3), eye_r // 2)

                screen.blit(spider_icon_surface, (icon_x, icon_y))
                pygame.draw.rect(screen, BLACK, (icon_x, icon_y, icon_size, icon_size), 1)
                y += row_height

            pygame.draw.line(screen, BLACK, (start_x - 5, y), (x + 15, y), 2)

        elif bestiary_tab == 2:
            for btn in tab_buttons_slimes:
                btn.draw(screen)
            start_x = 20
            start_y = 300
            row_height = 80
            col_widths = [160, 70, 80, 90, 160, 70]
            headers = ["Тип", "Прыжок", "Частота", "Макс.прыж.", "Эффект при смерти", "Вид"]
            header_bg = (70, 70, 70)
            header_text_color = (255, 255, 255)

            category = TAB_NAMES_SLIMES[current_slime_tab]
            slime_types = SLIME_CATEGORIES[category]
            slime_types = [st for st in SLIME_INFO_ORDERED if st in slime_types]

            table_width = sum(col_widths) + 40
            table_height = row_height * (len(slime_types) + 1) + 20
            table_x = start_x - 15
            table_y = start_y - 40
            pygame.draw.rect(screen, (50, 50, 50), (table_x + 5, table_y + 5, table_width, table_height),
                             border_radius=10)
            pygame.draw.rect(screen, WHITE, (table_x, table_y, table_width, table_height), border_radius=10)

            title = font.render(f"Бестиарий — Слизни ({category})", True, BLACK)
            screen.blit(title, (WIDTH // 2 - title.get_width() // 2, start_y - 130))

            desc_text = "Слизни перепрыгивают клетки и разрушаются после определённого количества прыжков."
            desc_surf = small_font.render(desc_text, True, BLACK)
            screen.blit(desc_surf, (start_x, start_y - 80))

            x = start_x
            for i, header in enumerate(headers):
                header_surf = micro_font.render(header, True, header_text_color)
                pygame.draw.rect(screen, header_bg, (x - 5, start_y - 35, col_widths[i] + 10, row_height - 5))
                screen.blit(header_surf, (x + 5, start_y - 30))
                x += col_widths[i]
            pygame.draw.line(screen, BLACK, (start_x - 5, start_y - 10), (x + 15, start_y - 10), 2)

            y = start_y
            for idx, slime_type in enumerate(slime_types):
                info = SLIME_INFO[slime_type]
                if idx % 2 == 0:
                    row_color = (240, 248, 255)
                else:
                    row_color = (255, 255, 240)
                pygame.draw.rect(screen, row_color, (start_x - 5, y - 5, x - start_x + 25, row_height))

                ru_names = {
                    "green_slime_jump1": "Зелёный прыгун 1", "green_slime_jump2": "Зелёный прыгун 2",
                    "dark_green_slime": "Тёмно-зелёный", "red_slime": "Красный",
                    "purple_blue_slime": "Фиолетово-синий",
                    "black_slime": "Чёрный", "dark_gray_slime": "Тёмно-серый", "light_gray_slime": "Светло-серый",
                    "white_slime": "Белый", "rainbow_slime": "Радужный",
                    "bright_orange_slime": "Ярко-оранжевый", "yellow_slime": "Жёлтый"
                }
                type_surf1 = micro_font.render(ru_names.get(slime_type, slime_type), True, (0, 0, 0))
                screen.blit(type_surf1, (start_x + 5, y + 30))

                jump_val = info["jump_length"]
                if slime_type == "rainbow_slime":
                    jump_str = "2-5"
                else:
                    jump_str = str(jump_val)
                jump_surf = micro_font.render(jump_str, True, BLACK)
                screen.blit(jump_surf, (start_x + col_widths[0] + 5, y + 30))
                freq_text = "каждый ход" if info["jump_freq"] == 1 else "каждый 2-й"
                freq_surf = micro_font.render(freq_text, True, BLACK)
                screen.blit(freq_surf, (start_x + col_widths[0] + col_widths[1] + 5, y + 30))
                if info["max_jumps"] is not None:
                    maxj_surf = micro_font.render(f"{info['max_jumps'][0]}-{info['max_jumps'][1]}", True, BLACK)
                else:
                    maxj_surf = micro_font.render("в€ћ", True, BLACK)
                screen.blit(maxj_surf, (start_x + col_widths[0] + col_widths[1] + col_widths[2] + 5, y + 30))

                effect_text = info.get("death_effect")
                if effect_text == "balls":
                    eff = "4 шара (скор.0.5)"
                elif effect_text == "invis_gas":
                    eff = f"Невидимость R{info['gas_radius']} ({info['gas_duration']} х.)"
                elif effect_text == "gas":
                    eff = f"РЇРґ R{info['gas_radius']} ({info['gas_duration']} С….)"
                elif effect_text == "shoot":
                    eff = "4 шара (скор.1)"
                elif effect_text == "spawn_dark_gray":
                    eff = "Создаёт темно-серых слизней"
                elif effect_text == "spawn_light_gray":
                    eff = "Создаёт светло-серых слизней"
                elif effect_text == "spawn_white":
                    eff = "Создаёт белых слизней"
                elif effect_text == "lava":
                    eff = f"Лава R{info['lava_radius']} ({info['lava_duration']} х.)"
                elif effect_text == "spawn_two":
                    eff = "Спавнит двух слизней (серо-зелёный или оранжевый)"
                else:
                    eff = "-"
                eff_surf = micro_font.render(eff, True, BLACK)
                screen.blit(eff_surf,
                            (start_x + col_widths[0] + col_widths[1] + col_widths[2] + col_widths[3] + 5, y + 8))

                icon_size = 32
                icon_x = start_x + sum(col_widths[:5]) + 15
                icon_y = y + (row_height - icon_size) // 2
                slime_icon = pygame.Surface((icon_size, icon_size), pygame.SRCALPHA)
                if slime_type == "rainbow_slime":
                    hue = (pygame.time.get_ticks() // 10) % 360
                    c = pygame.Color(0)
                    c.hsva = (hue, 100, 100)
                    c.a = 180
                    color = c
                else:
                    color = info["color"]
                pygame.draw.ellipse(slime_icon, color, (2, 2, icon_size - 4, icon_size - 4))
                pygame.draw.ellipse(slime_icon, (255, 255, 255, 100), (6, 6, icon_size - 12, icon_size - 12), 1)
                eye_c = (0, 0, 0, 200)
                pygame.draw.circle(slime_icon, eye_c, (icon_size // 3, icon_size // 3), icon_size // 8)
                pygame.draw.circle(slime_icon, eye_c, (2 * icon_size // 3, icon_size // 3), icon_size // 8)
                screen.blit(slime_icon, (icon_x, icon_y))
                pygame.draw.rect(screen, BLACK, (icon_x, icon_y, icon_size, icon_size), 1)

                y += row_height

            pygame.draw.line(screen, BLACK, (start_x - 5, y), (x + 15, y), 2)

        elif bestiary_tab == 3:
            for btn in tab_buttons_insects:
                btn.draw(screen)
            start_x = 20
            start_y = 300
            row_height = 80
            col_widths = [150, 70, 200, 150, 100]
            headers = ["Тип", "Размер", "Особенности", "Появление", "Вид"]
            header_bg = (70, 70, 70)
            header_text_color = (255, 255, 255)

            category = TAB_NAMES_INSECTS[current_insect_tab]
            insect_types = INSECT_CATEGORIES[category]
            insect_types = [st for st in INSECT_INFO_ORDERED if st in insect_types]

            table_width = sum(col_widths) + 40
            table_height = row_height * (len(insect_types) + 1) + 20
            table_x = start_x - 15
            table_y = start_y - 40
            pygame.draw.rect(screen, (50, 50, 50), (table_x + 5, table_y + 5, table_width, table_height),
                             border_radius=10)
            pygame.draw.rect(screen, WHITE, (table_x, table_y, table_width, table_height), border_radius=10)

            title = font.render(f"Бестиарий — {category}", True, BLACK)
            screen.blit(title, (WIDTH // 2 - title.get_width() // 2, start_y - 130))

            desc_text = "Насекомые появляются с краёв поля (кроме муравейника)."
            desc_surf = small_font.render(desc_text, True, BLACK)
            screen.blit(desc_surf, (start_x, start_y - 80))

            x = start_x
            for i, header in enumerate(headers):
                header_surf = micro_font.render(header, True, header_text_color)
                pygame.draw.rect(screen, header_bg, (x - 5, start_y - 35, col_widths[i] + 10, row_height - 5))
                screen.blit(header_surf, (x + 5, start_y - 30))
                x += col_widths[i]
            pygame.draw.line(screen, BLACK, (start_x - 5, start_y - 10), (x + 15, start_y - 10), 2)

            y = start_y
            for idx, insect_type in enumerate(insect_types):
                info = INSECT_INFO[insect_type]
                if idx % 2 == 0:
                    row_color = (240, 248, 255)
                else:
                    row_color = (255, 255, 240)
                pygame.draw.rect(screen, row_color, (start_x - 5, y - 5, x - start_x + 25, row_height))

                ru_names = {
                    "ant": "Муравей",
                    "dung_beetle": "Навозник",
                    "stag_beetle": "Рогач",
                    "anthill": "Муравейник"
                }
                type_surf = micro_font.render(ru_names.get(insect_type, insect_type), True, info["color"])
                screen.blit(type_surf, (start_x + 5, y + 30))

                size_str = f"{info['size']}x{info['size']}" if insect_type == "anthill" else f"{info['size']}x{info['size']}"
                size_surf = micro_font.render(size_str, True, BLACK)
                screen.blit(size_surf, (start_x + col_widths[0] + 5, y + 30))

                special_surf = micro_font.render(info["special"], True, BLACK)
                screen.blit(special_surf, (start_x + col_widths[0] + col_widths[1] + 5, y + 30))

                spawn_surf = micro_font.render(info["spawn_condition"], True, BLACK)
                screen.blit(spawn_surf, (start_x + col_widths[0] + col_widths[1] + col_widths[2] + 5, y + 30))

                icon_size = 32
                icon_x = start_x + sum(col_widths[:4]) + 15
                icon_y = y + (row_height - icon_size) // 2
                insect_icon = pygame.Surface((icon_size, icon_size))
                insect_icon.fill(row_color)
                pygame.draw.rect(insect_icon, info["color"], (2, 2, icon_size-4, icon_size-4))
                pygame.draw.rect(insect_icon, BLACK, (2, 2, icon_size-4, icon_size-4), 1)
                screen.blit(insect_icon, (icon_x, icon_y))
                pygame.draw.rect(screen, BLACK, (icon_x, icon_y, icon_size, icon_size), 1)

                y += row_height

            pygame.draw.line(screen, BLACK, (start_x - 5, y), (x + 15, y), 2)

        elif bestiary_tab == 4:
            for btn in tab_buttons_fish:
                btn.draw(screen)
            start_x = 20
            start_y = 300
            row_height = 70
            col_widths = [150, 60, 60, 250, 70]
            headers = ["Тип", "Размер", "Скорость", "Особенности", "Вид"]
            header_bg = (70, 70, 70)
            header_text_color = (255, 255, 255)

            fish_types = FISH_INFO_ORDERED

            table_width = sum(col_widths) + 40
            table_height = row_height * (len(fish_types) + 1) + 20
            table_x = start_x - 15
            table_y = start_y - 40
            pygame.draw.rect(screen, (50, 50, 50), (table_x + 5, table_y + 5, table_width, table_height), border_radius=10)
            pygame.draw.rect(screen, WHITE, (table_x, table_y, table_width, table_height), border_radius=10)

            title = font.render("Бестиарий — Рыбы", True, BLACK)
            screen.blit(title, (WIDTH // 2 - title.get_width() // 2, start_y - 130))

            desc_text = "Рыбы плавают под водой (тенью) и выпрыгивают, чтобы атаковать."
            desc_surf = small_font.render(desc_text, True, BLACK)
            screen.blit(desc_surf, (start_x, start_y - 80))

            x = start_x
            for i, header in enumerate(headers):
                header_surf = micro_font.render(header, True, header_text_color)
                pygame.draw.rect(screen, header_bg, (x - 5, start_y - 35, col_widths[i] + 10, row_height - 5))
                screen.blit(header_surf, (x + 5, start_y - 30))
                x += col_widths[i]
            pygame.draw.line(screen, BLACK, (start_x - 5, start_y - 10), (x + 15, start_y - 10), 2)

            y = start_y
            for idx, fish_type in enumerate(fish_types):
                info = FISH_INFO[fish_type]
                if idx % 2 == 0:
                    row_color = (240, 248, 255)
                else:
                    row_color = (255, 255, 240)
                pygame.draw.rect(screen, row_color, (start_x - 5, y - 5, x - start_x + 25, row_height))

                ru_names = {
                    "swallow": "Рыба-ласточка",
                    "swordfish": "Рыба-меч",
                    "shark": "Акула",
                    "octopus": "РћСЃСЊРјРёРЅРѕРі"
                }
                type_surf = micro_font.render(ru_names.get(fish_type, fish_type), True, info["color"])
                screen.blit(type_surf, (start_x + 5, y + 25))
                size_surf = micro_font.render(str(info["size"]), True, BLACK)
                screen.blit(size_surf, (start_x + col_widths[0] + 5, y + 25))
                speed_surf = micro_font.render("1", True, BLACK)
                screen.blit(speed_surf, (start_x + col_widths[0] + col_widths[1] + 5, y + 25))
                special_surf = micro_font.render(info["description"], True, BLACK)
                screen.blit(special_surf, (start_x + col_widths[0] + col_widths[1] + col_widths[2] + 5, y + 8))

                icon_size = 32
                icon_x = start_x + sum(col_widths[:4]) + 15
                icon_y = y + (row_height - icon_size) // 2
                pygame.draw.rect(screen, info["color"], (icon_x, icon_y, icon_size, icon_size))
                pygame.draw.rect(screen, BLACK, (icon_x, icon_y, icon_size, icon_size), 1)
                y += row_height

            pygame.draw.line(screen, BLACK, (start_x - 5, y), (x + 15, y), 2)

        else:
            for btn in tab_buttons_other:
                btn.draw(screen)

            start_x = 50
            start_y = 300
            row_height = 60

            if current_other_tab == 0:
                gases = GASES_INFO
                col_widths = [200, 60, 350]
                headers = ["Название", "Цвет", "Описание"]
                header_bg = (70, 70, 70)
                header_text_color = (255, 255, 255)

                table_width = sum(col_widths) + 40
                table_height = row_height * (len(gases) + 1) + 20
                table_x = start_x - 15
                table_y = start_y - 40
                pygame.draw.rect(screen, (50, 50, 50), (table_x + 5, table_y + 5, table_width, table_height),
                                 border_radius=10)
                pygame.draw.rect(screen, WHITE, (table_x, table_y, table_width, table_height), border_radius=10)

                title = font.render("Газы", True, BLACK)
                screen.blit(title, (WIDTH // 2 - title.get_width() // 2, start_y - 130))

                x = start_x
                for i, header in enumerate(headers):
                    header_surf = micro_font.render(header, True, header_text_color)
                    pygame.draw.rect(screen, header_bg, (x - 5, start_y - 35, col_widths[i] + 10, row_height - 5))
                    screen.blit(header_surf, (x + 5, start_y - 30))
                    x += col_widths[i]
                pygame.draw.line(screen, BLACK, (start_x - 5, start_y - 10), (x + 15, start_y - 10), 2)

                y = start_y
                for idx, gas in enumerate(gases):
                    if idx % 2 == 0:
                        row_color = (240, 248, 255)
                    else:
                        row_color = (255, 255, 240)
                    pygame.draw.rect(screen, row_color, (start_x - 5, y - 5, x - start_x + 25, row_height))

                    name_surf = small_font.render(gas["name"], True, BLACK)
                    screen.blit(name_surf, (start_x + 5, y + 15))

                    color_rect = pygame.Rect(start_x + col_widths[0] + 10, y + 15, 30, 30)
                    pygame.draw.rect(screen, gas["color"], color_rect)
                    pygame.draw.rect(screen, BLACK, color_rect, 1)

                    desc_surf = micro_font.render(gas["description"], True, BLACK)
                    screen.blit(desc_surf, (start_x + col_widths[0] + col_widths[1] + 5, y + 15))
                    y += row_height

                pygame.draw.line(screen, BLACK, (start_x - 5, y), (x + 15, y), 2)

            elif current_other_tab == 1:
                projs = PROJECTILES_INFO
                col_widths = [200, 60, 350]
                headers = ["Название", "Цвет", "Описание"]
                header_bg = (70, 70, 70)
                header_text_color = (255, 255, 255)

                table_width = sum(col_widths) + 40
                table_height = row_height * (len(projs) + 1) + 20
                table_x = start_x - 15
                table_y = start_y - 40
                pygame.draw.rect(screen, (50, 50, 50), (table_x + 5, table_y + 5, table_width, table_height),
                                 border_radius=10)
                pygame.draw.rect(screen, WHITE, (table_x, table_y, table_width, table_height), border_radius=10)

                title = font.render("Снаряды", True, BLACK)
                screen.blit(title, (WIDTH // 2 - title.get_width() // 2, start_y - 130))

                x = start_x
                for i, header in enumerate(headers):
                    header_surf = micro_font.render(header, True, header_text_color)
                    pygame.draw.rect(screen, header_bg, (x - 5, start_y - 35, col_widths[i] + 10, row_height - 5))
                    screen.blit(header_surf, (x + 5, start_y - 30))
                    x += col_widths[i]
                pygame.draw.line(screen, BLACK, (start_x - 5, start_y - 10), (x + 15, start_y - 10), 2)

                y = start_y
                for idx, proj in enumerate(projs):
                    if idx % 2 == 0:
                        row_color = (240, 248, 255)
                    else:
                        row_color = (255, 255, 240)
                    pygame.draw.rect(screen, row_color, (start_x - 5, y - 5, x - start_x + 25, row_height))

                    name_surf = small_font.render(proj["name"], True, BLACK)
                    screen.blit(name_surf, (start_x + 5, y + 15))

                    color_rect = pygame.Rect(start_x + col_widths[0] + 10, y + 15, 30, 30)
                    pygame.draw.rect(screen, proj["color"], color_rect)
                    pygame.draw.rect(screen, BLACK, color_rect, 1)
                    pygame.draw.circle(screen, proj["color"], color_rect.center, 12)
                    pygame.draw.circle(screen, WHITE, (color_rect.centerx - 3, color_rect.centery - 3), 3)

                    desc_surf = micro_font.render(proj["description"], True, BLACK)
                    screen.blit(desc_surf, (start_x + col_widths[0] + col_widths[1] + 5, y + 15))
                    y += row_height

                pygame.draw.line(screen, BLACK, (start_x - 5, y), (x + 15, y), 2)
            elif current_other_tab == 2:
                abilities_list = ABILITY_INFO
                col_widths = [180, 50, 50, 50, 300]
                headers = ["Название", "Клав.", "Исп.", "КД", "Описание"]
                header_bg = (70, 70, 70)
                header_text_color = (255, 255, 255)

                table_width = sum(col_widths) + 40
                table_height = row_height * (len(abilities_list) + 1) + 20
                table_x = start_x - 15
                table_y = start_y - 40
                pygame.draw.rect(screen, (50, 50, 50), (table_x + 5, table_y + 5, table_width, table_height),
                                 border_radius=10)
                pygame.draw.rect(screen, WHITE, (table_x, table_y, table_width, table_height), border_radius=10)

                title = font.render("Способности", True, BLACK)
                screen.blit(title, (WIDTH // 2 - title.get_width() // 2, start_y - 130))

                x = start_x
                for i, header in enumerate(headers):
                    header_surf = micro_font.render(header, True, header_text_color)
                    pygame.draw.rect(screen, header_bg, (x - 5, start_y - 35, col_widths[i] + 10, row_height - 5))
                    screen.blit(header_surf, (x + 5, start_y - 30))
                    x += col_widths[i]
                pygame.draw.line(screen, BLACK, (start_x - 5, start_y - 10), (x + 15, start_y - 10), 2)

                y = start_y
                for idx, ab in enumerate(abilities_list):
                    if idx % 2 == 0:
                        row_color = (240, 248, 255)
                    else:
                        row_color = (255, 255, 240)
                    pygame.draw.rect(screen, row_color, (start_x - 5, y - 5, x - start_x + 25, row_height))

                    name_surf = small_font.render(ab["name"], True, BLACK)
                    screen.blit(name_surf, (start_x + 5, y + 15))
                    key_surf = micro_font.render(str(ab["key"]), True, BLACK)
                    screen.blit(key_surf, (start_x + col_widths[0] + 5, y + 15))
                    uses_surf = micro_font.render(str(ab["uses"]), True, BLACK)
                    screen.blit(uses_surf, (start_x + col_widths[0] + col_widths[1] + 5, y + 15))
                    cd_surf = micro_font.render(str(ab["cooldown"]), True, BLACK)
                    screen.blit(cd_surf, (start_x + col_widths[0] + col_widths[1] + col_widths[2] + 5, y + 15))
                    desc_surf = micro_font.render(ab["description"], True, BLACK)
                    screen.blit(desc_surf,
                                (start_x + col_widths[0] + col_widths[1] + col_widths[2] + col_widths[3] + 5, y + 15))
                    y += row_height

                pygame.draw.line(screen, BLACK, (start_x - 5, y), (x + 15, y), 2)
            else:
                modifiers_list = list(MODIFIERS_INFO.items())
                col_widths = [250, 500]
                headers = ["Усложнение", "Описание"]
                header_bg = (70, 70, 70)
                header_text_color = (255, 255, 255)

                table_width = sum(col_widths) + 40
                table_height = row_height * (len(modifiers_list) + 1) + 20
                table_x = start_x - 15
                table_y = start_y - 40
                pygame.draw.rect(screen, (50, 50, 50), (table_x + 5, table_y + 5, table_width, table_height),
                                 border_radius=10)
                pygame.draw.rect(screen, WHITE, (table_x, table_y, table_width, table_height), border_radius=10)

                title = font.render("Усложнения (песочница)", True, BLACK)
                screen.blit(title, (WIDTH // 2 - title.get_width() // 2, start_y - 130))

                x = start_x
                for i, header in enumerate(headers):
                    header_surf = micro_font.render(header, True, header_text_color)
                    pygame.draw.rect(screen, header_bg, (x - 5, start_y - 35, col_widths[i] + 10, row_height - 5))
                    screen.blit(header_surf, (x + 5, start_y - 30))
                    x += col_widths[i]
                pygame.draw.line(screen, BLACK, (start_x - 5, start_y - 10), (x + 15, start_y - 10), 2)

                y = start_y
                for idx, (key, desc) in enumerate(modifiers_list):
                    if idx % 2 == 0:
                        row_color = (240, 248, 255)
                    else:
                        row_color = (255, 255, 240)
                    pygame.draw.rect(screen, row_color, (start_x - 5, y - 5, x - start_x + 25, row_height))

                    name_surf = small_font.render(key.replace('_', ' ').capitalize(), True, BLACK)
                    screen.blit(name_surf, (start_x + 5, y + 15))

                    words = desc.split()
                    lines = []
                    cur_line = ""
                    for w in words:
                        if len(cur_line) + len(w) + 1 <= 60:
                            if cur_line:
                                cur_line += " "
                            cur_line += w
                        else:
                            lines.append(cur_line)
                            cur_line = w
                    if cur_line:
                        lines.append(cur_line)
                    for li, line in enumerate(lines[:3]):
                        desc_surf = micro_font.render(line, True, (50, 50, 50))
                        screen.blit(desc_surf, (start_x + col_widths[0] + 5, y + 5 + li * 18))
                    y += row_height

                pygame.draw.line(screen, BLACK, (start_x - 5, y), (x + 15, y), 2)

        back_button.draw(screen)
        pygame.display.flip()

# ---------------------- ВСПОМОГАТЕЛЬНЫЕ ФУНКЦИИ ----------------------
def go_to_game(*args):
    global current_state
    current_state = "game"

def go_to_bestiary(*args):
    global current_state
    current_state = "bestiary"

def go_to_level_select():
    global current_state
    current_state = "level_select"

def go_to_challenge_select():
    global current_state
    current_state = "challenge_select"

def go_to_survival_select():
    global current_state
    current_state = "survival_select"

def go_to_controls(*args):
    global current_state
    current_state = "controls"

def go_to_menu(*args):
    global current_state
    current_state = "menu"

def go_to_mode_select(*args):
    global current_state
    current_state = "mode_select"

def go_to_skin_select(*args):
    global current_state
    current_state = "skin_select"

def go_to_settings(*args):
    global current_state
    current_state = "settings"

def go_to_sandbox_menu(*args):
    global current_state
    current_state = "sandbox_menu"

def exit_game(*args):
    pygame.quit()
    sys.exit()

# ---------------------- ОСНОВНОЙ ЦИКЛ ----------------------
current_state = "menu"
game_mode = None
selected_abilities = {}

running = True
while running:
    if current_state == "menu":
        show_menu()
    elif current_state == "mode_select":
        show_game_mode_selection()
    elif current_state == "level_select":
        show_level_select()
    elif current_state == "level_info":
        show_level_info(current_level)
    elif current_state == "challenge_select":
        show_challenge_select()
    elif current_state == "survival_select":
        show_survival_select()
    elif current_state == "ability_selection":
        show_ability_selection(game_mode)
    elif current_state == "game":
        show_game()
    elif current_state == "spider_game":
        show_spider_game()
    elif current_state == "slime_game":
        show_slime_game()
    elif current_state == "insect_game":
        show_insect_game()
    elif current_state == "fish_game":
        show_fish_game()
    elif current_state == "level1":
        show_level_game(1)
    elif current_state == "level2":
        show_level_game(2)
    elif current_state == "level3":
        show_level_game(3)
    elif current_state == "level4":
        show_level_game(4)
    elif current_state == "level5":
        show_level_game(5)
    elif current_state == "level6":
        show_level_game(6)
    elif current_state == "level7":
        show_level_game(7)
    elif current_state == "level8":
        show_level_game(8)
    elif current_state == "level9":
        show_level_game(9)
    elif current_state == "level10":
        show_level_game(10)
    elif current_state == "level11":
        show_level_game(11)
    elif current_state == "level12":
        show_level_game(12)
    elif current_state == "level13":
        show_level_game(13)
    elif current_state == "level14":
        show_level_game(14)
    elif current_state == "level15":
        show_level_game(15)
    elif current_state == "level16":
        show_level_game(16)
    elif current_state == "level17":
        show_level_game(17)
    elif current_state == "level18":
        show_level_game(18)
    elif current_state == "level19":
        show_level_game(19)
    elif current_state == "level20":
        show_level_game(20)
    elif current_state == "challenge1":
        show_challenge1()
    elif current_state == "challenge2":
        show_challenge2()
    elif current_state == "challenge3":
        show_challenge3()
    elif current_state == "challenge4":
        show_challenge4()
    elif current_state == "challenge5":
        show_challenge5()
    elif current_state == "bestiary":
        show_bestiary()
    elif current_state == "controls":
        show_controls()
    elif current_state == "skin_select":
        show_skin_select()
    elif current_state == "settings":
        show_settings()
    elif current_state == "sandbox_menu":
        show_sandbox_menu()
    elif current_state == "sandbox_settings":
        show_sandbox_settings()
    elif current_state == "sandbox_modifiers":
        show_sandbox_modifiers()
    elif current_state == "sandbox_arena":
        show_sandbox_arena_selection()
    elif current_state == "sandbox_play":
        show_sandbox_play()
    else:
        current_state = "menu"

pygame.quit()
sys.exit()