🎮ArcadeLab

Hexagonic

by NeonFlare13
2536 lines100.2 KB
▶ Play
<!DOCTYPE html>
<html lang="ru">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
    <title>Hexagonic</title>
    <style>
        * { margin: 0; padding: 0; box-sizing: border-box; user-select: none; }
        body {
            background: #0a0a1a;
            display: flex;
            justify-content: center;
            align-items: center;
            min-height: 100vh;
            font-family: 'Segoe UI', Arial, sans-serif;
            overflow: hidden;
            position: relative;
        }
        .game-container {
            background: #141428;
            padding: 15px;
            border-radius: 20px;
            box-shadow: 0 10px 40px rgba(0,0,0,0.9);
            display: flex;
            flex-direction: column;
            align-items: center;
            max-width: 98vw;
            position: relative;
            z-index: 1;
        }
        h1 { color: #ff6b6b; font-size: 20px; margin-bottom: 6px; text-shadow: 0 0 30px rgba(255,107,107,0.3); letter-spacing: 3px; }
        .top-bar { display: flex; justify-content: space-between; width: 100%; margin-bottom: 8px; gap: 8px; flex-wrap: wrap; align-items: center; }
        .stats { display: flex; gap: 12px; background: rgba(255,255,255,0.05); padding: 5px 12px; border-radius: 10px; flex-wrap: wrap; }
        .stat { color: #ccc; font-size: 12px; }
        .stat span { font-weight: bold; }
        .stat .color-dot { display: inline-block; width: 10px; height: 10px; border-radius: 50%; vertical-align: middle; margin-right: 3px; border: 2px solid rgba(255,255,255,0.2); }
        .controls { display: flex; gap: 6px; flex-wrap: wrap; }

        .btn {
            border: none;
            color: white;
            padding: 5px 16px;
            border-radius: 30px;
            font-size: 12px;
            font-weight: 700;
            cursor: pointer;
            transition: all 0.25s ease;
            letter-spacing: 0.5px;
            background: rgba(255,255,255,0.06);
            backdrop-filter: blur(4px);
            border: 1px solid rgba(255,255,255,0.08);
            box-shadow: 0 4px 12px rgba(0,0,0,0.2);
            position: relative;
            overflow: hidden;
        }
        .btn::after {
            content: '';
            position: absolute;
            top: -50%;
            left: -50%;
            width: 200%;
            height: 200%;
            background: radial-gradient(circle at center, rgba(255,255,255,0.05) 0%, transparent 70%);
            opacity: 0;
            transition: opacity 0.4s;
            pointer-events: none;
        }
        .btn:hover:not(:disabled)::after { opacity: 1; }
        .btn:hover:not(:disabled) { transform: translateY(-2px) scale(1.02); box-shadow: 0 8px 20px rgba(0,0,0,0.3); }
        .btn:active:not(:disabled) { transform: scale(0.96); }
        .btn:disabled { opacity: 0.4; cursor: not-allowed; transform: none !important; box-shadow: none !important; }

        .btn-primary { background: linear-gradient(145deg, #ff6b6b, #e55555); border-color: #ff6b6b; }
        .btn-primary:hover:not(:disabled) { background: linear-gradient(145deg, #ff7a7a, #f55a5a); }

        .btn-secondary { background: rgba(45, 64, 89, 0.7); border-color: rgba(255,255,255,0.1); }
        .btn-secondary:hover:not(:disabled) { background: rgba(60, 85, 115, 0.9); }

        .btn-green { background: linear-gradient(145deg, #4ecca3, #3db892); border-color: #4ecca3; }
        .btn-green:hover:not(:disabled) { background: linear-gradient(145deg, #5edbb3, #4ac89e); }

        .btn-gold { background: linear-gradient(145deg, #ffd700, #f0c000); color: #1a1a3e; border-color: #ffd700; }
        .btn-gold:hover:not(:disabled) { background: linear-gradient(145deg, #ffe44d, #f5cc00); }

        .btn-outline { background: transparent; border: 1.5px solid rgba(255,255,255,0.15); }
        .btn-outline:hover:not(:disabled) { background: rgba(255,255,255,0.05); border-color: rgba(255,255,255,0.3); }

        .turn-indicator { color: #ff6b6b; font-size: 14px; font-weight: bold; padding: 3px 12px; border-radius: 30px; background: rgba(255,255,255,0.04); border: 1px solid rgba(255,255,255,0.06); backdrop-filter: blur(4px); }
        .message { color: #ffd700; font-size: 12px; min-height: 18px; text-align: center; margin-top: 3px; opacity: 0.9; }
        canvas { border-radius: 12px; background: #0f1a2e; display: block; touch-action: none; cursor: pointer; max-width: 100%; height: auto; border: 2px solid rgba(255,255,255,0.06); box-shadow: inset 0 0 60px rgba(0,0,0,0.4); }

        /* --- МЕНЮ --- */
        .menu-overlay {
            display: none;
            position: fixed;
            top: 0;
            left: 0;
            width: 100vw;
            height: 100vh;
            background: rgba(0, 0, 0, 0.85);
            z-index: 9999;
            justify-content: center;
            align-items: center;
            backdrop-filter: blur(16px);
        }
        .menu-overlay.active { display: flex; }
        
        .main-menu {
            display: none;
            flex-direction: column;
            align-items: center;
            gap: 20px;
            padding: 45px 50px 35px;
            background: linear-gradient(160deg, #1a1a3e, #0f0f2a);
            border-radius: 40px;
            min-width: 420px;
            max-width: 94vw;
            border: 1px solid rgba(255, 107, 107, 0.15);
            box-shadow: 0 50px 120px rgba(0,0,0,0.9), inset 0 0 80px rgba(255,107,107,0.02);
            position: relative;
            overflow: hidden;
            max-height: 90vh;
            overflow-y: auto;
        }
        .main-menu::-webkit-scrollbar { width: 4px; }
        .main-menu::-webkit-scrollbar-track { background: transparent; }
        .main-menu::-webkit-scrollbar-thumb { background: rgba(255,107,107,0.3); border-radius: 10px; }
        
        .main-menu::before {
            content: '';
            position: absolute;
            top: -50%;
            left: -50%;
            width: 200%;
            height: 200%;
            background: radial-gradient(ellipse at 30% 20%, rgba(255,107,107,0.03) 0%, transparent 60%);
            pointer-events: none;
        }
        .main-menu.active { display: flex; }
        
        .main-menu .menu-header {
            text-align: center;
            position: relative;
            z-index: 1;
        }
        .main-menu h2 {
            color: #ff6b6b;
            font-size: 38px;
            font-weight: 300;
            letter-spacing: 8px;
            text-shadow: 0 0 60px rgba(255,107,107,0.15);
            margin-bottom: 2px;
        }
        .main-menu .menu-subtitle {
            color: #888;
            font-size: 13px;
            letter-spacing: 4px;
            opacity: 0.6;
            font-weight: 300;
        }
        .main-menu .menu-divider {
            width: 60%;
            height: 1px;
            background: linear-gradient(90deg, transparent, rgba(255,107,107,0.2), transparent);
            margin: 2px 0 8px 0;
            position: relative;
            z-index: 1;
        }
        .menu-section-title {
            color: #999;
            font-size: 11px;
            text-transform: uppercase;
            letter-spacing: 5px;
            opacity: 0.5;
            margin-top: 2px;
            position: relative;
            z-index: 1;
        }

        .menu-main-buttons {
            display: flex;
            flex-direction: column;
            gap: 16px;
            width: 100%;
            position: relative;
            z-index: 1;
            padding: 10px 0;
        }
        .menu-main-btn {
            padding: 18px 30px;
            border-radius: 20px;
            border: 1.5px solid rgba(255,255,255,0.06);
            background: rgba(255,255,255,0.02);
            color: white;
            font-size: 20px;
            font-weight: 700;
            cursor: pointer;
            transition: all 0.3s ease;
            text-align: center;
            letter-spacing: 2px;
            backdrop-filter: blur(4px);
            position: relative;
            overflow: hidden;
        }
        .menu-main-btn::before {
            content: '';
            position: absolute;
            top: 0;
            left: 0;
            right: 0;
            bottom: 0;
            background: linear-gradient(135deg, rgba(255,255,255,0.03) 0%, transparent 60%);
            pointer-events: none;
        }
        .menu-main-btn::after {
            content: '';
            position: absolute;
            bottom: 0;
            left: 0;
            right: 0;
            height: 2px;
            background: linear-gradient(90deg, transparent, var(--btn-color, #ff6b6b), transparent);
            opacity: 0;
            transition: opacity 0.4s;
        }
        .menu-main-btn:hover {
            transform: translateY(-3px) scale(1.01);
            box-shadow: 0 20px 50px rgba(0,0,0,0.3);
            border-color: var(--btn-color, rgba(255,255,255,0.1));
        }
        .menu-main-btn:hover::after { opacity: 1; }
        .menu-main-btn:active { transform: scale(0.97); }
        
        .menu-main-btn.play-btn { --btn-color: #4ecca3; }
        .menu-main-btn.play-btn:hover { background: rgba(78, 204, 163, 0.06); border-color: rgba(78, 204, 163, 0.3); }
        
        .menu-main-btn.tutorial-btn { --btn-color: #ffd700; }
        .menu-main-btn.tutorial-btn:hover { background: rgba(255, 215, 0, 0.06); border-color: rgba(255, 215, 0, 0.3); }

        .menu-main-btn.settings-btn { --btn-color: #888; }
        .menu-main-btn.settings-btn:hover { background: rgba(255,255,255,0.04); border-color: rgba(255,255,255,0.15); }

        .menu-main-btn .btn-icon { font-size: 24px; margin-right: 12px; vertical-align: middle; }
        .menu-main-btn .btn-label { vertical-align: middle; }

        .menu-sub {
            display: none;
            flex-direction: column;
            align-items: center;
            gap: 16px;
            width: 100%;
            position: relative;
            z-index: 1;
            animation: fadeSlideIn 0.3s ease;
        }
        .menu-sub.active { display: flex; }
        
        @keyframes fadeSlideIn {
            from { opacity: 0; transform: translateY(10px); }
            to { opacity: 1; transform: translateY(0); }
        }

        .menu-sub-back {
            align-self: flex-start;
            background: rgba(255,255,255,0.03);
            border: 1px solid rgba(255,255,255,0.06);
            border-radius: 30px;
            color: #888;
            padding: 8px 20px;
            font-size: 13px;
            cursor: pointer;
            transition: all 0.3s;
            font-weight: 600;
            letter-spacing: 1px;
        }
        .menu-sub-back:hover {
            background: rgba(255,255,255,0.06);
            color: white;
            border-color: rgba(255,255,255,0.15);
        }

        /* --- ОБУЧЕНИЕ --- */
        .tutorial-container {
            width: 100%;
            max-width: 520px;
            position: relative;
            z-index: 1;
        }

        .tutorial-slide {
            display: none;
            flex-direction: column;
            gap: 12px;
            padding: 16px 20px 20px;
            background: rgba(255,255,255,0.02);
            border-radius: 18px;
            border: 1px solid rgba(255,255,255,0.06);
            animation: fadeSlideIn 0.35s ease;
        }
        .tutorial-slide.active { display: flex; }

        .tutorial-slide .step-badge {
            font-size: 10px;
            text-transform: uppercase;
            letter-spacing: 2px;
            color: #666;
            margin-bottom: -4px;
        }
        .tutorial-slide .step-title {
            font-size: 18px;
            font-weight: 700;
            color: #fff;
            display: flex;
            align-items: center;
            gap: 10px;
        }
        .tutorial-slide .step-title .emoji { font-size: 24px; }
        .tutorial-slide .step-desc {
            color: #aaa;
            font-size: 14px;
            line-height: 1.6;
            padding: 0 2px;
        }
        .tutorial-slide .step-desc strong { color: #fff; font-weight: 600; }
        .tutorial-slide .step-desc .highlight-red { color: #ff6b6b; font-weight: 600; }
        .tutorial-slide .step-desc .highlight-green { color: #4ecca3; font-weight: 600; }
        .tutorial-slide .step-desc .highlight-gold { color: #ffd700; font-weight: 600; }

        .tutorial-slide .example-box {
            background: rgba(255,255,255,0.03);
            border-radius: 12px;
            padding: 10px 14px;
            border-left: 3px solid var(--ex-color, #ff6b6b);
            margin: 2px 0;
        }
        .tutorial-slide .example-box .ex-label {
            font-size: 10px;
            text-transform: uppercase;
            letter-spacing: 1px;
            color: #666;
            margin-bottom: 3px;
        }
        .tutorial-slide .example-box .ex-text {
            color: #bbb;
            font-size: 13px;
            line-height: 1.5;
        }

        .tutorial-nav {
            display: flex;
            justify-content: space-between;
            align-items: center;
            gap: 12px;
            width: 100%;
            margin-top: 2px;
        }
        .tutorial-nav .dots {
            display: flex;
            gap: 6px;
        }
        .tutorial-nav .dot {
            width: 8px;
            height: 8px;
            border-radius: 50%;
            background: rgba(255,255,255,0.1);
            transition: all 0.3s;
            cursor: pointer;
        }
        .tutorial-nav .dot.active {
            background: #ff6b6b;
            box-shadow: 0 0 12px rgba(255,107,107,0.3);
            width: 18px;
            border-radius: 10px;
        }
        .tutorial-nav .dot:hover:not(.active) {
            background: rgba(255,255,255,0.2);
        }

        .tutorial-nav .tut-btn {
            background: rgba(255,255,255,0.04);
            border: 1px solid rgba(255,255,255,0.06);
            color: #aaa;
            padding: 6px 18px;
            border-radius: 30px;
            font-size: 12px;
            font-weight: 600;
            cursor: pointer;
            transition: all 0.3s;
            font-family: inherit;
        }
        .tutorial-nav .tut-btn:hover:not(:disabled) {
            background: rgba(255,255,255,0.08);
            color: white;
            border-color: rgba(255,255,255,0.15);
        }
        .tutorial-nav .tut-btn:disabled {
            opacity: 0.3;
            cursor: not-allowed;
        }
        .tutorial-nav .tut-btn.primary {
            background: rgba(78, 204, 163, 0.15);
            border-color: rgba(78, 204, 163, 0.2);
            color: #4ecca3;
        }
        .tutorial-nav .tut-btn.primary:hover:not(:disabled) {
            background: rgba(78, 204, 163, 0.25);
            border-color: rgba(78, 204, 163, 0.4);
        }

        /* Выбор сложности и карты */
        .game-options {
            display: flex;
            flex-direction: column;
            align-items: center;
            gap: 16px;
            width: 100%;
        }

        .difficulty-list {
            display: flex;
            flex-direction: column;
            gap: 12px;
            width: 100%;
            min-width: 280px;
            position: relative;
            z-index: 1;
        }
        .diff-card {
            padding: 16px 22px;
            border-radius: 18px;
            background: rgba(255,255,255,0.02);
            border: 1.5px solid rgba(255,255,255,0.06);
            cursor: pointer;
            transition: all 0.35s cubic-bezier(0.34, 1.56, 0.64, 1);
            text-align: left;
            color: white;
            font-weight: 600;
            position: relative;
            overflow: hidden;
            backdrop-filter: blur(4px);
            display: flex;
            align-items: center;
            gap: 16px;
        }
        .diff-card::before {
            content: '';
            position: absolute;
            top: 0;
            left: 0;
            right: 0;
            bottom: 0;
            background: linear-gradient(135deg, rgba(255,255,255,0.03) 0%, transparent 60%);
            pointer-events: none;
        }
        .diff-card::after {
            content: '';
            position: absolute;
            left: 0;
            top: 0;
            bottom: 0;
            width: 3px;
            background: var(--card-color, #ff6b6b);
            opacity: 0;
            transition: opacity 0.4s;
            border-radius: 0 3px 3px 0;
        }
        .diff-card:hover:not(:disabled) {
            transform: translateX(6px) scale(1.01);
            box-shadow: 0 10px 40px rgba(0,0,0,0.3);
            border-color: var(--card-color, rgba(255,255,255,0.1));
        }
        .diff-card:hover:not(:disabled)::after {
            opacity: 1;
        }
        .diff-card:active:not(:disabled) {
            transform: scale(0.97) translateX(3px);
        }
        .diff-card .diff-icon {
            font-size: 28px;
            flex-shrink: 0;
            filter: drop-shadow(0 0 20px rgba(255,255,255,0.05));
        }
        .diff-card .diff-info {
            flex: 1;
        }
        .diff-card .diff-label {
            font-size: 17px;
            font-weight: 700;
            display: block;
            letter-spacing: 0.5px;
        }
        .diff-card .diff-desc {
            font-size: 11px;
            opacity: 0.4;
            font-weight: 400;
            display: block;
            line-height: 1.3;
        }
        .diff-card .diff-badge {
            display: inline-block;
            font-size: 9px;
            text-transform: uppercase;
            letter-spacing: 1px;
            padding: 2px 12px;
            border-radius: 20px;
            background: rgba(255,255,255,0.04);
            border: 1px solid rgba(255,255,255,0.06);
            opacity: 0.4;
            flex-shrink: 0;
        }

        .diff-card.easy { --card-color: #4ecca3; }
        .diff-card.easy:hover { background: rgba(78, 204, 163, 0.06); border-color: rgba(78, 204, 163, 0.3); }
        .diff-card.easy .diff-badge { color: #4ecca3; border-color: rgba(78, 204, 163, 0.2); }

        .diff-card.medium { --card-color: #ffd700; }
        .diff-card.medium:hover { background: rgba(255, 215, 0, 0.06); border-color: rgba(255, 215, 0, 0.3); }
        .diff-card.medium .diff-badge { color: #ffd700; border-color: rgba(255, 215, 0, 0.2); }

        .diff-card.hard { --card-color: #ff6b6b; }
        .diff-card.hard:hover { background: rgba(255, 107, 107, 0.06); border-color: rgba(255, 107, 107, 0.3); }
        .diff-card.hard .diff-badge { color: #ff6b6b; border-color: rgba(255, 107, 107, 0.2); }

        .diff-card.impossible { --card-color: #ff0040; }
        .diff-card.impossible { background: rgba(255, 0, 64, 0.04); border-color: rgba(255, 0, 64, 0.15); }
        .diff-card.impossible:hover { background: rgba(255, 0, 64, 0.1); border-color: rgba(255, 0, 64, 0.4); }
        .diff-card.impossible .diff-badge { color: #ff0040; border-color: rgba(255, 0, 64, 0.2); }

        .map-grid {
            display: grid;
            grid-template-columns: 1fr 1fr;
            gap: 12px;
            width: 100%;
            position: relative;
            z-index: 1;
        }
        .map-btn {
            padding: 14px 16px;
            border-radius: 16px;
            background: rgba(255,255,255,0.02);
            border: 1.5px solid rgba(255,255,255,0.06);
            color: #888;
            font-size: 13px;
            font-weight: 600;
            cursor: pointer;
            transition: all 0.3s ease;
            text-align: center;
            letter-spacing: 0.5px;
            backdrop-filter: blur(4px);
            font-family: inherit;
        }
        .map-btn:hover {
            background: rgba(255,255,255,0.04);
            border-color: rgba(255,255,255,0.12);
            color: #ccc;
        }
        .map-btn.active {
            border-color: #ff6b6b;
            background: rgba(255, 107, 107, 0.06);
            color: white;
            box-shadow: 0 0 30px rgba(255, 107, 107, 0.04);
        }
        .map-btn.active:hover {
            background: rgba(255, 107, 107, 0.1);
        }
        .map-btn .map-icon {
            font-size: 24px;
            display: block;
            margin-bottom: 4px;
        }
        .map-btn .map-name {
            display: block;
            font-size: 12px;
        }
        .map-btn .map-desc {
            display: block;
            font-size: 9px;
            opacity: 0.4;
            margin-top: 2px;
        }

        .settings-placeholder {
            color: #666;
            font-size: 16px;
            text-align: center;
            padding: 30px 20px;
            letter-spacing: 2px;
            opacity: 0.5;
            font-weight: 300;
            width: 100%;
        }
        .settings-placeholder .settings-icon {
            font-size: 48px;
            display: block;
            margin-bottom: 16px;
            opacity: 0.3;
        }

        .menu-footer {
            display: none;
        }

        @media (max-width: 600px) {
            .game-container { padding: 8px; }
            h1 { font-size: 16px; }
            .stat { font-size: 10px; }
            .btn { padding: 4px 12px; font-size: 10px; }
            .top-bar { flex-direction: column; align-items: center; }
            
            .main-menu {
                min-width: unset;
                width: 92vw;
                padding: 28px 16px 24px;
                border-radius: 28px;
                gap: 16px;
            }
            .main-menu h2 { font-size: 28px; letter-spacing: 5px; }
            .menu-main-btn { padding: 14px 20px; font-size: 17px; }
            .menu-main-btn .btn-icon { font-size: 20px; margin-right: 8px; }
            
            .difficulty-list { min-width: unset; }
            .diff-card { padding: 14px 16px; gap: 12px; }
            .diff-card .diff-icon { font-size: 22px; }
            .diff-card .diff-label { font-size: 15px; }
            .diff-card .diff-desc { font-size: 10px; }
            .diff-card .diff-badge { font-size: 8px; padding: 1px 10px; }
            
            .map-grid { grid-template-columns: 1fr 1fr; gap: 8px; }
            .map-btn { padding: 10px 12px; font-size: 11px; }
            .map-btn .map-icon { font-size: 18px; }
            .map-btn .map-name { font-size: 10px; }

            .tutorial-slide { padding: 12px 14px 16px; }
            .tutorial-slide .step-title { font-size: 16px; }
            .tutorial-slide .step-desc { font-size: 13px; }
            .tutorial-nav .tut-btn { padding: 4px 14px; font-size: 11px; }
        }
        @media (max-width: 420px) {
            .diff-card .diff-icon { font-size: 18px; }
            .diff-card .diff-label { font-size: 13px; }
            .diff-card .diff-desc { font-size: 9px; }
            .diff-card { padding: 10px 12px; gap: 8px; }
            .map-grid { grid-template-columns: 1fr 1fr; gap: 6px; }
            .map-btn { padding: 8px 8px; font-size: 10px; }
            .map-btn .map-icon { font-size: 16px; }
        }
    </style>
</head>
<body>

<div class="menu-overlay active" id="menuOverlay">
    <div class="main-menu active" id="mainMenu">
        <div class="menu-header">
            <h2>✦ HEXAGONIC ✦</h2>
            <div class="menu-subtitle">Гексагональная стратегия</div>
        </div>
        <div class="menu-divider"></div>

        <div class="menu-main-buttons" id="menuMain">
            <button class="menu-main-btn play-btn" onclick="showSubMenu('play')">
                <span class="btn-icon">▶</span>
                <span class="btn-label">Играть</span>
            </button>
            <button class="menu-main-btn tutorial-btn" onclick="showSubMenu('tutorial')">
                <span class="btn-icon">📖</span>
                <span class="btn-label">Обучение</span>
            </button>
            <button class="menu-main-btn settings-btn" onclick="showSubMenu('settings')">
                <span class="btn-icon">⚙</span>
                <span class="btn-label">Настройки</span>
            </button>
        </div>

        <div class="menu-sub" id="menuSubPlay">
            <button class="menu-sub-back" onclick="showMainMenu()">← Назад</button>
            <!-- Выбор сложности и карты -->
            <div class="game-options" id="gameOptions">
                <div class="menu-divider"></div>
                <div class="menu-section-title">⚔️ Выберите сложность</div>
                <div class="difficulty-list">
                    <button class="diff-card easy" onclick="startGame(1)">
                        <span class="diff-icon">🌱</span>
                        <div class="diff-info">
                            <span class="diff-label">Лёгкий</span>
                            <span class="diff-desc">ИИ редко атакует</span>
                        </div>
                        <span class="diff-badge">спокойный</span>
                    </button>
                    <button class="diff-card medium" onclick="startGame(2)">
                        <span class="diff-icon">⚡</span>
                        <div class="diff-info">
                            <span class="diff-label">Средний</span>
                            <span class="diff-desc">ИИ атакует умеренно</span>
                        </div>
                        <span class="diff-badge">сбалансированный</span>
                    </button>
                    <button class="diff-card hard" onclick="startGame(3)">
                        <span class="diff-icon">🔥</span>
                        <div class="diff-info">
                            <span class="diff-label">Сложный</span>
                            <span class="diff-desc">ИИ умный и сильный</span>
                        </div>
                        <span class="diff-badge">вызов</span>
                    </button>
                    <button class="diff-card impossible" onclick="startGame(4)">
                        <span class="diff-icon">💀</span>
                        <div class="diff-info">
                            <span class="diff-label">Невозможный</span>
                            <span class="diff-desc">Супер-агрессивный ИИ</span>
                        </div>
                        <span class="diff-badge">экстрим</span>
                    </button>
                </div>

                <div class="menu-divider"></div>
                <div class="menu-section-title">🗺️ Выберите карту</div>
                <div class="map-grid">
                    <button class="map-btn active" data-map="1" onclick="selectMap(1)">
                        <span class="map-icon">🏝️</span>
                        <span class="map-name">Острова</span>
                        <span class="map-desc">с водой, по углам</span>
                    </button>
                    <button class="map-btn" data-map="2" onclick="selectMap(2)">
                        <span class="map-icon">🌿</span>
                        <span class="map-name">Долина</span>
                        <span class="map-desc">с водой, по бокам</span>
                    </button>
                    <button class="map-btn" data-map="3" onclick="selectMap(3)">
                        <span class="map-icon">🏜️</span>
                        <span class="map-name">Пустыня</span>
                        <span class="map-desc">без воды, по углам</span>
                    </button>
                    <button class="map-btn" data-map="4" onclick="selectMap(4)">
                        <span class="map-icon">⛰️</span>
                        <span class="map-name">Нагорье</span>
                        <span class="map-desc">без воды, центр-край</span>
                    </button>
                </div>
            </div>
        </div>

        <!-- Отдельное подменю для обучения -->
        <div class="menu-sub" id="menuSubTutorial">
            <button class="menu-sub-back" onclick="showMainMenu()">← Назад</button>
            <div class="tutorial-container" id="tutorialContainer2">
                <div class="tutorial-slide" data-step="0">
                    <div class="step-badge">📖 Шаг 1 из 6</div>
                    <div class="step-title"><span class="emoji">🎯</span> Цель игры</div>
                    <div class="step-desc">
                        Захватите все клетки на поле! <strong>Побеждает тот</strong>, у кого в конце останется больше клеток.
                        <br><br>
                        У вас <span class="highlight-red">красные</span> клетки, у ИИ — <span class="highlight-green">зелёные</span>.
                    </div>
                    <div class="example-box" style="--ex-color: #ff6b6b;">
                        <div class="ex-label">💡 Совет</div>
                        <div class="ex-text">Стартуете с двумя клетками. Захватывайте нейтральные (серые) и вражеские клетки.</div>
                    </div>
                </div>

                <div class="tutorial-slide" data-step="1">
                    <div class="step-badge">📖 Шаг 2 из 6</div>
                    <div class="step-title"><span class="emoji">⚔️</span> Как атаковать</div>
                    <div class="step-desc">
                        <strong>Кликните</strong> по своей клетке с силой <span class="highlight-gold">&gt; 1</span>, затем по соседней вражеской или нейтральной.
                        <br><br>
                        Сила атакующей клетки <strong>сравнивается</strong> с силой цели. Если ваша сила больше — вы захватываете клетку!
                    </div>
                    <div class="example-box" style="--ex-color: #4ecca3;">
                        <div class="ex-label">📊 Пример</div>
                        <div class="ex-text">Ваша клетка <strong>сила 5</strong> атакует клетку с <strong>силой 3</strong> → захват! Ваша клетка становится силой <strong>2</strong> (5−3).</div>
                    </div>
                </div>

                <div class="tutorial-slide" data-step="2">
                    <div class="step-badge">📖 Шаг 3 из 6</div>
                    <div class="step-title"><span class="emoji">⚡</span> Прокачка (главное!)</div>
                    <div class="step-desc">
                        В начале каждого хода вы получаете <strong>очки прокачки</strong> = количеству ваших клеток.
                        <br><br>
                        Чтобы потратить очки:
                        <br>1️⃣ Нажмите <span class="highlight-gold">«Пропустить»</span>
                        <br>2️⃣ Кликните по <strong>своей</strong> клетке, чтобы увеличить её силу на +1
                        <br>3️⃣ Или нажмите <span class="highlight-gold">«Распределить»</span> — очки сами пойдут в самые слабые клетки
                    </div>
                    <div class="example-box" style="--ex-color: #ffd700;">
                        <div class="ex-label">⭐ MAX-режим</div>
                        <div class="ex-text">Включите <strong>MAX</strong> — тогда один клик вкинет <strong>все</strong> очки в одну клетку (до силы 20).</div>
                    </div>
                </div>

                <div class="tutorial-slide" data-step="3">
                    <div class="step-badge">📖 Шаг 4 из 6</div>
                    <div class="step-title"><span class="emoji">🔄</span> Очерёдность ходов</div>
                    <div class="step-desc">
                        1. <span class="highlight-red">Ваш ход</span> — вы прокачиваетесь, затем атакуете.<br>
                        2. Нажимаете <span class="highlight-gold">«Пропустить»</span>, чтобы завершить прокачку.<br>
                        3. После прокачки вы можете <strong>атаковать</strong> столько раз, сколько хотите.<br>
                        4. Когда закончите — нажмите <span class="highlight-gold">«Пропустить»</span> ещё раз, чтобы передать ход ИИ.
                    </div>
                    <div class="example-box" style="--ex-color: #888;">
                        <div class="ex-label">🔄 Важно</div>
                        <div class="ex-text">Если у вас <strong>нет</strong> очков прокачки — ход передаётся сразу, без «Пропустить».</div>
                    </div>
                </div>

                <div class="tutorial-slide" data-step="4">
                    <div class="step-badge">📖 Шаг 5 из 6</div>
                    <div class="step-title"><span class="emoji">🤖</span> Как играет ИИ</div>
                    <div class="step-desc">
                        ИИ тоже прокачивается и атакует. Его агрессивность зависит от выбранной <strong>сложности</strong>:
                        <br><br>
                        <span style="color: #4ecca3;">🌱 Лёгкий</span> — редко атакует, прокачивается слабо.<br>
                        <span style="color: #ffd700;">⚡ Средний</span> — атакует умеренно, сбалансирован.<br>
                        <span style="color: #ff6b6b;">🔥 Сложный</span> — умный, агрессивный, сильный.<br>
                        <span style="color: #ff0040;">💀 Невозможный</span> — сверхагрессивный, с бонусной прокачкой.
                    </div>
                    <div class="example-box" style="--ex-color: #ff0040;">
                        <div class="ex-label">⚠️ Осторожно</div>
                        <div class="ex-text">На «Невозможном» ИИ получает <strong>+80%</strong> очков прокачки и атакует до 10 раз за ход!</div>
                    </div>
                </div>

                <div class="tutorial-slide" data-step="5">
                    <div class="step-badge">📖 Шаг 6 из 6</div>
                    <div class="step-title"><span class="emoji">🗺️</span> Карты и стратегия</div>
                    <div class="step-desc">
                        <strong>4 типа карт</strong> с уникальной генерацией:
                        <br><br>
                        🏝️ <strong>Острова</strong> — вода разбросана по карте, старт из углов.<br>
                        🌿 <strong>Долина</strong> — река с мостами, старт с боков.<br>
                        🏜️ <strong>Пустыня</strong> — стены-препятствия, старт из углов.<br>
                        ⛰️ <strong>Нагорье</strong> — кольцевые стены, старт случайный.
                    </div>
                    <div class="example-box" style="--ex-color: #ff6b6b;">
                        <div class="ex-label">💡 Стратегия</div>
                        <div class="ex-text">Захватывайте нейтральные клетки, чтобы получить больше очков прокачки. Сильные клетки пробивают оборону ИИ!</div>
                    </div>
                </div>

                <div class="tutorial-nav">
                    <button class="tut-btn" id="tutPrev2" onclick="tutorialPrev2()" disabled>← Назад</button>
                    <div class="dots" id="tutDots2"></div>
                    <button class="tut-btn primary" id="tutNext2" onclick="tutorialNext2()">Далее →</button>
                </div>
            </div>
            <div style="margin-top: 6px; color: #666; font-size: 12px; opacity:0.5;">Изучите механику перед игрой</div>
        </div>

        <div class="menu-sub" id="menuSubSettings">
            <button class="menu-sub-back" onclick="showMainMenu()">← Назад</button>
            <div class="settings-placeholder">
                <span class="settings-icon">⚙</span>
                Настройки игры<br>
                <span style="font-size: 12px; opacity: 0.5;">(будут доступны в следующих обновлениях)</span>
            </div>
        </div>
    </div>
</div>

<div class="game-container">
    <h1>✦ HEXAGONIC ✦</h1>
    <div class="top-bar">
        <div class="stats">
            <div class="stat"><span class="color-dot" style="background:#ff6b6b;"></span> Вы: <span id="playerScore">0</span></div>
            <div class="stat"><span class="color-dot" style="background:#4ecca3;"></span> ИИ: <span id="aiScore">0</span></div>
            <div class="stat">Ход: <span id="turnNum">1</span></div>
            <div class="stat">⚡ <span id="upgradePoints">0</span></div>
            <div class="stat">📊 <span id="usedUpgrades">0</span>/<span id="totalUpgrades">0</span></div>
        </div>
        <div class="controls">
            <button class="btn btn-secondary" onclick="resetGame()">🔄 Новая</button>
            <button class="btn btn-secondary" id="menuBtn" onclick="showMenu()">📋 Меню</button>
            <button class="btn btn-green" id="distributeBtn" onclick="distributePoints()" disabled>Распределить</button>
            <button class="btn btn-gold" id="maxBtn" onclick="toggleMaxMode()" disabled>MAX</button>
            <button class="btn btn-outline" id="skipBtn" onclick="skipTurn()">⏭ Пропустить</button>
        </div>
    </div>
    <div class="turn-indicator" id="turnIndicator">🔴 Ваш ход</div>
    <canvas id="gameCanvas"></canvas>
    <div class="message" id="message">Нажмите "Пропустить", чтобы начать прокачку</div>
</div>

<script>
    // ============================================================
    //  HEXAGONIC — ГЕКСАГОНАЛЬНАЯ СТРАТЕГИЯ
    // ============================================================

    const canvas = document.getElementById('gameCanvas');
    const ctx = canvas.getContext('2d');

    const COLS = 12;
    const ROWS = 10;
    const HEX_SIZE = 30;
    const SPACING = HEX_SIZE * 1.75;

    const W = COLS * SPACING + HEX_SIZE * 2;
    const H = ROWS * SPACING + HEX_SIZE * 2;
    canvas.width = W;
    canvas.height = H;

    const PLAYER = 0;
    const AI = 1;

    let grid = [];
    let currentPlayer = PLAYER;
    let turnNumber = 1;
    let selectedCell = null;
    let gameOver = false;
    let aiThinking = false;
    let upgradePoints = 0;
    let usedUpgrades = 0;
    let totalUpgrades = 0;
    let currentMap = 1;
    let skipPressed = false;
    let canUpgradeAfterSkip = false;
    let isFirstTurn = true;
    let playerUpgradedThisTurn = false;
    let difficulty = 2;
    let gameStarted = false;

    let maxModeActive = false;

    let animations = [];
    let animFrameId = null;

    const COLORS = {
        bg: '#0f1a2e',
        player: '#ff6b6b',
        playerGlow: 'rgba(255,107,107,0.3)',
        ai: '#4ecca3',
        aiGlow: 'rgba(78,204,163,0.3)',
        neutral: '#3a5570',
        neutralGlow: 'rgba(58,85,112,0.2)',
        selected: '#ffd700',
        selectedGlow: 'rgba(255,215,0,0.5)',
        water: '#0a1525',
        maxLevel: '#ffd700',
    };

    // ============================================================
    //  ГЕНЕРАЦИЯ КАРТ
    // ============================================================
    
    function getRandomStartPositions(type) {
        const positions = {
            corners: [
                { col: 2, row: 2 },
                { col: COLS-3, row: 2 },
                { col: 2, row: ROWS-3 },
                { col: COLS-3, row: ROWS-3 }
            ],
            sides: [
                { col: 2, row: 3 },
                { col: COLS-3, row: 3 },
                { col: 2, row: ROWS-4 },
                { col: COLS-3, row: ROWS-4 }
            ],
            diagonal: [
                { col: 2, row: 2 },
                { col: COLS-3, row: ROWS-3 },
                { col: COLS-3, row: 2 },
                { col: 2, row: ROWS-3 }
            ]
        };

        let pool;
        switch(type) {
            case 'corners': pool = positions.corners; break;
            case 'sides': pool = positions.sides; break;
            case 'diagonal': pool = positions.diagonal; break;
            default: pool = positions.corners;
        }

        const idx1 = Math.floor(Math.random() * pool.length);
        let idx2 = Math.floor(Math.random() * pool.length);
        while (idx2 === idx1) {
            idx2 = Math.floor(Math.random() * pool.length);
        }

        return {
            playerStart: pool[idx1],
            aiStart: pool[idx2]
        };
    }

    function generateMapIslands() {
        const map = [];
        const waterDensity = 0.06 + Math.random() * 0.08;
        
        for (let r = 0; r < ROWS; r++) {
            map[r] = [];
            for (let c = 0; c < COLS; c++) {
                map[r][c] = true;
            }
        }

        for (let r = 1; r < ROWS-1; r++) {
            for (let c = 1; c < COLS-1; c++) {
                const isNearStart = (r >= 1 && r <= 4 && c >= 1 && c <= 4) || 
                                   (r >= ROWS-5 && r <= ROWS-2 && c >= COLS-5 && c <= COLS-2);
                if (!isNearStart && Math.random() < waterDensity) {
                    map[r][c] = false;
                }
            }
        }

        for (let r = 4; r <= 5; r++) {
            for (let c = 4; c <= 7; c++) {
                map[r][c] = true;
            }
        }

        const positions = getRandomStartPositions('corners');
        return { map, ...positions };
    }

    function generateMapValley() {
        const map = [];
        const riverWidth = 1 + Math.floor(Math.random() * 2);

        for (let r = 0; r < ROWS; r++) {
            map[r] = [];
            for (let c = 0; c < COLS; c++) {
                map[r][c] = true;
            }
        }

        for (let r = 2; r < ROWS-2; r++) {
            const offset = Math.sin(r * 0.5) * 1.5;
            const center = 5 + Math.floor(offset);
            const w = riverWidth + Math.floor(Math.random() * 2);
            for (let c = center - w; c <= center + w; c++) {
                if (c > 1 && c < COLS-2) {
                    map[r][c] = false;
                }
            }
        }

        const numBridges = 2 + Math.floor(Math.random() * 3);
        for (let i = 0; i < numBridges; i++) {
            const bridgeRow = 3 + Math.floor(Math.random() * (ROWS - 6));
            const bridgeCol = 4 + Math.floor(Math.random() * 4);
            if (bridgeRow > 1 && bridgeRow < ROWS-2 && bridgeCol > 1 && bridgeCol < COLS-2) {
                map[bridgeRow][bridgeCol] = true;
                if (bridgeCol + 1 < COLS-2) map[bridgeRow][bridgeCol + 1] = true;
            }
        }

        const positions = getRandomStartPositions('sides');
        return { map, ...positions };
    }

    function generateMapDesert() {
        const map = [];
        const wallDensity = 0.08 + Math.random() * 0.10;

        for (let r = 0; r < ROWS; r++) {
            map[r] = [];
            for (let c = 0; c < COLS; c++) {
                map[r][c] = true;
            }
        }

        const numWalls = Math.floor(ROWS * COLS * wallDensity);
        for (let i = 0; i < numWalls; i++) {
            const r = 1 + Math.floor(Math.random() * (ROWS - 2));
            const c = 1 + Math.floor(Math.random() * (COLS - 2));
            const isStartZone = (r <= 4 && c <= 4) || (r >= ROWS-5 && c >= COLS-5) ||
                               (r <= 4 && c >= COLS-5) || (r >= ROWS-5 && c <= 4);
            if (!isStartZone) {
                const clusterSize = 1 + Math.floor(Math.random() * 3);
                for (let j = 0; j < clusterSize && r+j < ROWS-1 && c+j < COLS-1; j++) {
                    map[r+j][c+j] = false;
                }
            }
        }

        for (let r = 4; r <= 5; r++) {
            for (let c = 5; c <= 6; c++) {
                map[r][c] = true;
            }
        }

        const positions = getRandomStartPositions('corners');
        return { map, ...positions };
    }

    function generateMapHighland() {
        const map = [];

        for (let r = 0; r < ROWS; r++) {
            map[r] = [];
            for (let c = 0; c < COLS; c++) {
                map[r][c] = true;
            }
        }

        const centerR = 4 + Math.floor(Math.random() * 2);
        const centerC = 5 + Math.floor(Math.random() * 2);
        const radius = 2 + Math.floor(Math.random() * 2);

        for (let r = 0; r < ROWS; r++) {
            for (let c = 0; c < COLS; c++) {
                const dist = Math.sqrt(Math.pow(r - centerR, 2) + Math.pow(c - centerC, 2));
                if (dist > radius - 0.5 && dist < radius + 1.5) {
                    const angle = Math.atan2(r - centerR, c - centerC);
                    const isGate = Math.abs(Math.sin(angle * 2)) < 0.4 || 
                                  Math.abs(Math.cos(angle * 1.5)) < 0.3;
                    if (!isGate) {
                        map[r][c] = false;
                    }
                }
            }
        }

        for (let i = 0; i < 5 + Math.floor(Math.random() * 8); i++) {
            const r = 2 + Math.floor(Math.random() * (ROWS - 4));
            const c = 2 + Math.floor(Math.random() * (COLS - 4));
            const dist = Math.sqrt(Math.pow(r - centerR, 2) + Math.pow(c - centerC, 2));
            if (dist > 1.5 && dist < 5) {
                map[r][c] = false;
            }
        }

        const startTypes = ['corners', 'sides', 'diagonal'];
        const type = startTypes[Math.floor(Math.random() * startTypes.length)];
        const positions = getRandomStartPositions(type);
        return { map, ...positions };
    }

    // ============================================================
    //  ИНИЦИАЛИЗАЦИЯ
    // ============================================================
    function initGrid(mapType) {
        let landMap, playerStart, aiStart;
        
        switch(mapType) {
            case 1:
                const islands = generateMapIslands();
                landMap = islands.map;
                playerStart = islands.playerStart;
                aiStart = islands.aiStart;
                break;
            case 2:
                const valley = generateMapValley();
                landMap = valley.map;
                playerStart = valley.playerStart;
                aiStart = valley.aiStart;
                break;
            case 3:
                const desert = generateMapDesert();
                landMap = desert.map;
                playerStart = desert.playerStart;
                aiStart = desert.aiStart;
                break;
            case 4:
                const highland = generateMapHighland();
                landMap = highland.map;
                playerStart = highland.playerStart;
                aiStart = highland.aiStart;
                break;
            default:
                const def = generateMapIslands();
                landMap = def.map;
                playerStart = def.playerStart;
                aiStart = def.aiStart;
        }

        grid = [];
        for (let r = 0; r < ROWS; r++) {
            grid[r] = [];
            for (let c = 0; c < COLS; c++) {
                if (landMap[r][c]) {
                    grid[r][c] = { owner: null, power: 1 };
                } else {
                    grid[r][c] = null;
                }
            }
        }

        grid[playerStart.row][playerStart.col].owner = PLAYER;
        grid[playerStart.row][playerStart.col].power = 2;

        grid[aiStart.row][aiStart.col].owner = AI;
        grid[aiStart.row][aiStart.col].power = 2;

        for (let r = 0; r < ROWS; r++) {
            for (let c = 0; c < COLS; c++) {
                if (grid[r][c] !== null && grid[r][c].owner === null) {
                    grid[r][c].power = 1;
                }
            }
        }
    }

    // ============================================================
    //  СОСЕДИ
    // ============================================================
    function getNeighbors(col, row) {
        const neighbors = [];
        const directions = [];

        if (row % 2 === 0) {
            directions.push(
                { dc: -1, dr: 0 },
                { dc: 1, dr: 0 },
                { dc: 0, dr: -1 },
                { dc: 0, dr: 1 },
                { dc: -1, dr: -1 },
                { dc: -1, dr: 1 }
            );
        } else {
            directions.push(
                { dc: -1, dr: 0 },
                { dc: 1, dr: 0 },
                { dc: 0, dr: -1 },
                { dc: 0, dr: 1 },
                { dc: 1, dr: -1 },
                { dc: 1, dr: 1 }
            );
        }

        for (let dir of directions) {
            const nc = col + dir.dc;
            const nr = row + dir.dr;

            if (nr >= 0 && nr < ROWS && nc >= 0 && nc < COLS) {
                if (grid[nr][nc] !== null) {
                    neighbors.push({ col: nc, row: nr });
                }
            }
        }

        return neighbors;
    }

    // ============================================================
    //  АНИМАЦИЯ
    // ============================================================
    function addCaptureAnimation(fromCol, fromRow, toCol, toRow, owner) {
        const from = getHexCenter(fromCol, fromRow);
        const to = getHexCenter(toCol, toRow);
        const color = owner === PLAYER ? COLORS.player : COLORS.ai;
        const glowColor = owner === PLAYER ? COLORS.playerGlow : COLORS.aiGlow;

        animations.push({
            fromX: from.x,
            fromY: from.y,
            toX: to.x,
            toY: to.y,
            progress: 0,
            speed: 0.04 + Math.random() * 0.02,
            color: color,
            glowColor: glowColor,
            particles: 8,
            done: false
        });

        if (!animFrameId) {
            animFrameId = requestAnimationFrame(animateLoop);
        }
    }

    function animateLoop() {
        let allDone = true;

        for (let anim of animations) {
            anim.progress += anim.speed;
            if (anim.progress >= 1) {
                anim.progress = 1;
                anim.done = true;
            }
            allDone = allDone && anim.done;
        }

        draw();

        if (!allDone) {
            animFrameId = requestAnimationFrame(animateLoop);
        } else {
            animations = [];
            animFrameId = null;
            draw();
        }
    }

    function drawAnimations() {
        for (let anim of animations) {
            if (anim.done) continue;

            const cx = anim.fromX + (anim.toX - anim.fromX) * anim.progress;
            const cy = anim.fromY + (anim.toY - anim.fromY) * anim.progress;
            const size = 8 + 12 * anim.progress;
            const alpha = 1 - anim.progress * 0.3;

            const grad = ctx.createRadialGradient(cx, cy, 0, cx, cy, size);
            grad.addColorStop(0, anim.color);
            grad.addColorStop(0.6, anim.color);
            grad.addColorStop(1, 'rgba(255,255,255,0)');
            ctx.globalAlpha = alpha * 0.8;
            ctx.shadowColor = anim.glowColor;
            ctx.shadowBlur = 20;
            ctx.beginPath();
            ctx.arc(cx, cy, size, 0, Math.PI * 2);
            ctx.fillStyle = grad;
            ctx.fill();
            ctx.shadowBlur = 0;

            for (let i = 0; i < anim.particles; i++) {
                const angle = (i / anim.particles) * Math.PI * 2 + anim.progress * 3;
                const dist = size * 0.5 + anim.progress * 15;
                const px = cx + Math.cos(angle) * dist;
                const py = cy + Math.sin(angle) * dist;
                const pSize = 2 + 3 * (1 - anim.progress);
                ctx.globalAlpha = alpha * 0.5 * (1 - anim.progress);
                ctx.beginPath();
                ctx.arc(px, py, pSize, 0, Math.PI * 2);
                ctx.fillStyle = anim.color;
                ctx.fill();
            }
            ctx.globalAlpha = 1;

            if (anim.progress > 0.85) {
                const flash = (anim.progress - 0.85) / 0.15;
                ctx.globalAlpha = flash * 0.4;
                ctx.shadowColor = '#ffffff';
                ctx.shadowBlur = 40;
                ctx.beginPath();
                ctx.arc(anim.toX, anim.toY, 10 + flash * 20, 0, Math.PI * 2);
                ctx.fillStyle = '#ffffff';
                ctx.fill();
                ctx.shadowBlur = 0;
                ctx.globalAlpha = 1;
            }
        }
    }

    // ============================================================
    //  ИГРОВАЯ МЕХАНИКА
    // ============================================================

    function growPlayerCells() {
        if (playerUpgradedThisTurn) return;

        for (let r = 0; r < ROWS; r++) {
            for (let c = 0; c < COLS; c++) {
                if (grid[r][c] !== null && grid[r][c].owner === PLAYER) {
                    grid[r][c].power = Math.min(grid[r][c].power + 1, 20);
                }
            }
        }
    }

    function executeAttack(fromCol, fromRow, toCol, toRow) {
        const attacker = grid[fromRow][fromCol];
        const defender = grid[toRow][toCol];

        if (!attacker || !defender) return false;
        if (attacker.owner === defender.owner) return false;
        if (attacker.power <= 1) return false;

        const neighbors = getNeighbors(fromCol, fromRow);
        const isNeighbor = neighbors.some(n => n.col === toCol && n.row === toRow);
        if (!isNeighbor) return false;

        const diff = attacker.power - defender.power;
        const attackerOwner = attacker.owner;

        if (diff > 0) {
            defender.owner = attacker.owner;
            defender.power = Math.max(1, diff);
            attacker.power = 1;
        } else if (diff === 0) {
            if (Math.random() < 0.5) {
                defender.owner = attacker.owner;
                defender.power = 1;
                attacker.power = 1;
            } else {
                attacker.power = 1;
                defender.power = 1;
            }
        } else {
            attacker.power = 1;
            defender.power = Math.max(1, Math.abs(diff));
        }

        attacker.power = Math.min(attacker.power, 20);
        defender.power = Math.min(defender.power, 20);

        if (defender.owner === attackerOwner) {
            addCaptureAnimation(fromCol, fromRow, toCol, toRow, attackerOwner);
        }

        return true;
    }

    function upgradeCell(col, row) {
        if (grid[row][col] === null) return false;
        if (grid[row][col].owner !== currentPlayer) return false;
        if (upgradePoints <= 0) return false;
        if (grid[row][col].power >= 20) {
            document.getElementById('message').textContent = '⚠️ Эта клетка уже имеет максимальную силу (20)!';
            return false;
        }
        if (gameOver) return false;
        if (aiThinking) return false;
        if (!skipPressed || !canUpgradeAfterSkip) {
            document.getElementById('message').textContent = '⚠️ Сначала нажмите "Пропустить"!';
            return false;
        }

        let pointsToSpend = 1;
        if (maxModeActive) {
            const maxPossible = 20 - grid[row][col].power;
            pointsToSpend = Math.min(upgradePoints, maxPossible);
        }

        grid[row][col].power = Math.min(grid[row][col].power + pointsToSpend, 20);
        upgradePoints -= pointsToSpend;
        usedUpgrades += pointsToSpend;
        playerUpgradedThisTurn = true;

        updateUI();
        draw();

        if (pointsToSpend > 1) {
            document.getElementById('message').textContent = `⚡ MAX прокачка +${pointsToSpend}! Сила: ${grid[row][col].power} (осталось ${upgradePoints} очков)`;
        } else {
            document.getElementById('message').textContent = `⚡ Прокачка +1! Сила: ${grid[row][col].power} (осталось ${upgradePoints} очков)`;
        }

        if (maxModeActive && grid[row][col].power >= 20) {
            maxModeActive = false;
            document.getElementById('maxBtn').classList.remove('btn-gold');
            document.getElementById('maxBtn').textContent = 'MAX';
            document.getElementById('message').textContent += ' MAX режим отключён (клетка достигла 20)';
        }

        if (upgradePoints === 0) {
            document.getElementById('distributeBtn').disabled = true;
            skipPressed = false;
            canUpgradeAfterSkip = false;
            document.getElementById('skipBtn').disabled = true;
            document.getElementById('maxBtn').disabled = true;
            if (maxModeActive) {
                maxModeActive = false;
                document.getElementById('maxBtn').classList.remove('btn-gold');
                document.getElementById('maxBtn').textContent = 'MAX';
            }

            setTimeout(() => {
                if (!gameOver && currentPlayer === PLAYER && !aiThinking) {
                    endPlayerTurn();
                }
            }, 500);
        }

        return true;
    }

    // ============================================================
    //  РАСПРЕДЕЛЕНИЕ ОЧКОВ
    // ============================================================
    function distributePoints() {
        if (currentPlayer !== PLAYER || gameOver || aiThinking) {
            document.getElementById('message').textContent = '⏳ Нельзя сейчас!';
            return;
        }
        if (upgradePoints <= 0) {
            document.getElementById('message').textContent = '❌ Нет очков прокачки!';
            return;
        }
        if (!skipPressed || !canUpgradeAfterSkip) {
            document.getElementById('message').textContent = '⚠️ Сначала нажмите "Пропустить"!';
            return;
        }

        if (maxModeActive) {
            maxModeActive = false;
            document.getElementById('maxBtn').classList.remove('btn-gold');
            document.getElementById('maxBtn').textContent = 'MAX';
        }

        let playerCells = [];
        for (let r = 0; r < ROWS; r++) {
            for (let c = 0; c < COLS; c++) {
                if (grid[r][c] !== null && grid[r][c].owner === PLAYER) {
                    playerCells.push({ col: c, row: r, power: grid[r][c].power });
                }
            }
        }

        if (playerCells.length === 0) {
            document.getElementById('message').textContent = '❌ Нет клеток для прокачки!';
            return;
        }

        playerCells.sort((a, b) => a.power - b.power);

        let points = upgradePoints;
        let upgraded = 0;
        let attempts = 0;

        while (points > 0 && attempts < 100) {
            attempts++;
            let distributed = false;

            for (let cell of playerCells) {
                if (points <= 0) break;
                if (grid[cell.row][cell.col] !== null && grid[cell.row][cell.col].owner === PLAYER) {
                    if (grid[cell.row][cell.col].power < 20) {
                        grid[cell.row][cell.col].power = Math.min(grid[cell.row][cell.col].power + 1, 20);
                        points--;
                        upgraded++;
                        usedUpgrades++;
                        playerUpgradedThisTurn = true;
                        distributed = true;
                    }
                }
            }

            if (!distributed) break;
        }

        upgradePoints = points;
        document.getElementById('message').textContent = `✅ Распределено: +${upgraded} силы (осталось ${upgradePoints} очков)`;
        updateUI();
        draw();

        if (upgradePoints === 0) {
            document.getElementById('distributeBtn').disabled = true;
            skipPressed = false;
            canUpgradeAfterSkip = false;
            document.getElementById('skipBtn').disabled = true;
            document.getElementById('maxBtn').disabled = true;

            setTimeout(() => {
                if (!gameOver && currentPlayer === PLAYER && !aiThinking) {
                    endPlayerTurn();
                }
            }, 500);
        }
    }

    // ============================================================
    //  УПРАВЛЕНИЕ ХОДАМИ
    // ============================================================

    function startPlayerTurn() {
        if (gameOver) return;

        currentPlayer = PLAYER;

        if (!isFirstTurn) {
            growPlayerCells();
        }
        isFirstTurn = false;

        playerUpgradedThisTurn = false;

        let playerCount = 0;
        for (let r = 0; r < ROWS; r++) {
            for (let c = 0; c < COLS; c++) {
                if (grid[r][c] !== null && grid[r][c].owner === PLAYER) {
                    playerCount++;
                }
            }
        }
        totalUpgrades = playerCount;
        upgradePoints = playerCount;
        usedUpgrades = 0;
        selectedCell = null;

        skipPressed = false;
        canUpgradeAfterSkip = false;
        maxModeActive = false;
        document.getElementById('maxBtn').classList.remove('btn-gold');
        document.getElementById('maxBtn').textContent = 'MAX';
        document.getElementById('maxBtn').disabled = true;

        document.getElementById('distributeBtn').disabled = true;
        document.getElementById('skipBtn').disabled = false;
        document.getElementById('turnIndicator').textContent = `🔴 Ваш ход (${turnNumber})`;
        document.getElementById('turnIndicator').style.color = '#ff6b6b';
        document.getElementById('message').textContent = `⚡ У вас ${upgradePoints} очков прокачки. Нажмите "Пропустить", чтобы начать прокачку`;
        updateUI();
        draw();
    }

    function endPlayerTurn() {
        if (gameOver) return;

        skipPressed = false;
        canUpgradeAfterSkip = false;
        document.getElementById('distributeBtn').disabled = true;
        document.getElementById('skipBtn').disabled = true;
        document.getElementById('maxBtn').disabled = true;
        if (maxModeActive) {
            maxModeActive = false;
            document.getElementById('maxBtn').classList.remove('btn-gold');
            document.getElementById('maxBtn').textContent = 'MAX';
        }

        if (checkGameOver()) return;

        setTimeout(() => {
            startAITurn();
        }, 300);
    }

    function startAITurn() {
        if (gameOver) return;

        currentPlayer = AI;
        document.getElementById('turnIndicator').textContent = `🟢 Ход ИИ (${turnNumber})`;
        document.getElementById('turnIndicator').style.color = '#4ecca3';
        document.getElementById('skipBtn').disabled = true;
        aiThinking = true;

        setTimeout(() => {
            aiTurn();
        }, 400);
    }

    function endAITurn() {
        if (gameOver) return;

        aiThinking = false;
        if (checkGameOver()) return;

        turnNumber++;

        setTimeout(() => {
            startPlayerTurn();
        }, 300);
    }

    // ============================================================
    //  КНОПКА MAX
    // ============================================================
    function toggleMaxMode() {
        if (gameOver || aiThinking || currentPlayer !== PLAYER || !skipPressed || !canUpgradeAfterSkip) {
            return;
        }
        if (upgradePoints <= 0) {
            document.getElementById('message').textContent = '❌ Нет очков прокачки!';
            return;
        }

        maxModeActive = !maxModeActive;
        if (maxModeActive) {
            document.getElementById('maxBtn').classList.add('btn-gold');
            document.getElementById('maxBtn').textContent = 'MAX ✓';
            document.getElementById('message').textContent = `🔱 MAX режим включён! Кликните по клетке чтобы вкинуть все очки (до 20 силы)`;
        } else {
            document.getElementById('maxBtn').classList.remove('btn-gold');
            document.getElementById('maxBtn').textContent = 'MAX';
            document.getElementById('message').textContent = `📤 Режим прокачки! Кликайте по своим клеткам (${upgradePoints} очков) ИЛИ нажмите "Распределить"`;
        }
    }

    // ============================================================
    //  КНОПКА ПРОПУСТИТЬ
    // ============================================================
    function skipTurn() {
        if (gameOver) {
            document.getElementById('message').textContent = '⏳ Игра уже окончена!';
            return;
        }
        if (aiThinking) {
            document.getElementById('message').textContent = '⏳ Подождите, ИИ думает...';
            return;
        }
        if (currentPlayer !== PLAYER) {
            document.getElementById('message').textContent = '⏳ Сейчас не ваш ход!';
            return;
        }

        if (upgradePoints > 0) {
            skipPressed = true;
            canUpgradeAfterSkip = true;
            document.getElementById('distributeBtn').disabled = false;
            document.getElementById('maxBtn').disabled = false;
            document.getElementById('message').textContent = `📤 Режим прокачки! Кликайте по своим клеткам (${upgradePoints} очков) ИЛИ нажмите "Распределить"`;
            document.getElementById('skipBtn').disabled = true;
            selectedCell = null;
            draw();
            return;
        }

        document.getElementById('message').textContent = '⏭ Ход пропущен (нет очков прокачки)';
        endPlayerTurn();
    }

    // ============================================================
    //  ХОД ИИ
    // ============================================================
    function aiTurn() {
        let aiCells = [];
        for (let r = 0; r < ROWS; r++) {
            for (let c = 0; c < COLS; c++) {
                if (grid[r][c] !== null && grid[r][c].owner === AI) {
                    aiCells.push({ col: c, row: r, power: grid[r][c].power });
                }
            }
        }

        let aiUpgradePoints = aiCells.length;
        let pointsToDistribute = aiUpgradePoints;

        if (difficulty === 1) {
            pointsToDistribute = Math.floor(aiUpgradePoints * 0.4);
        } else if (difficulty === 2) {
            pointsToDistribute = aiUpgradePoints;
        } else if (difficulty === 3) {
            pointsToDistribute = aiUpgradePoints;
        } else if (difficulty === 4) {
            pointsToDistribute = aiUpgradePoints + Math.floor(aiUpgradePoints * 0.8);
        }

        let attempts = 0;
        while (pointsToDistribute > 0 && attempts < 100) {
            attempts++;
            let distributed = false;
            aiCells.sort((a, b) => a.power - b.power);
            for (let cell of aiCells) {
                if (pointsToDistribute <= 0) break;
                if (grid[cell.row][cell.col] !== null && grid[cell.row][cell.col].owner === AI) {
                    if (grid[cell.row][cell.col].power < 20) {
                        grid[cell.row][cell.col].power++;
                        pointsToDistribute--;
                        distributed = true;
                    }
                }
            }
            if (!distributed) break;
        }

        aiCells = [];
        for (let r = 0; r < ROWS; r++) {
            for (let c = 0; c < COLS; c++) {
                if (grid[r][c] !== null && grid[r][c].owner === AI) {
                    aiCells.push({ col: c, row: r, power: grid[r][c].power });
                }
            }
        }

        let totalAttacks = 0;
        let maxAttacks = 0;

        if (difficulty === 1) {
            maxAttacks = 1;
        } else if (difficulty === 2) {
            maxAttacks = 3;
        } else if (difficulty === 3) {
            maxAttacks = 4;
        } else if (difficulty === 4) {
            maxAttacks = 10;
        }

        aiCells.sort((a, b) => b.power - a.power);

        for (let attackRound = 0; attackRound < maxAttacks && totalAttacks < maxAttacks; attackRound++) {
            let attackedThisRound = false;

            for (let cell of aiCells) {
                if (totalAttacks >= maxAttacks) break;
                if (grid[cell.row][cell.col] === null || grid[cell.row][cell.col].owner !== AI) continue;
                if (grid[cell.row][cell.col].power <= 1) continue;

                if (difficulty === 1 && Math.random() > 0.35) continue;

                const neighbors = getNeighbors(cell.col, cell.row);
                let enemies = [];
                let neutrals = [];

                for (let n of neighbors) {
                    if (grid[n.row][n.col] !== null) {
                        if (grid[n.row][n.col].owner !== AI) {
                            enemies.push({
                                col: n.col,
                                row: n.row,
                                power: grid[n.row][n.col].power,
                                owner: grid[n.row][n.col].owner
                            });
                        } else if (grid[n.row][n.col].owner === null) {
                            neutrals.push({
                                col: n.col,
                                row: n.row,
                                power: grid[n.row][n.col].power
                            });
                        }
                    }
                }

                if (enemies.length > 0) {
                    enemies.sort((a, b) => a.power - b.power);
                    let target = null;

                    if (difficulty === 1) {
                        for (let enemy of enemies) {
                            const diff = cell.power - enemy.power;
                            if (diff > 2) {
                                target = enemy;
                                break;
                            }
                        }
                    } else if (difficulty === 2) {
                        for (let enemy of enemies) {
                            const diff = cell.power - enemy.power;
                            if (diff > -1) {
                                target = enemy;
                                break;
                            }
                        }
                    } else if (difficulty === 3) {
                        for (let enemy of enemies) {
                            const diff = cell.power - enemy.power;
                            if (diff > -2) {
                                target = enemy;
                                break;
                            }
                        }
                        if (!target && enemies.length > 0) {
                            target = enemies[0];
                        }
                    } else if (difficulty === 4) {
                        for (let enemy of enemies) {
                            const diff = cell.power - enemy.power;
                            if (diff > -4) {
                                target = enemy;
                                break;
                            }
                        }
                        if (!target && enemies.length > 0) {
                            target = enemies[0];
                        }
                    }

                    if (target) {
                        const result = executeAttack(cell.col, cell.row, target.col, target.row);
                        if (result) {
                            totalAttacks++;
                            attackedThisRound = true;
                            document.getElementById('message').textContent = `💥 ИИ атакует! (${totalAttacks}/${maxAttacks})`;
                            if (grid[cell.row][cell.col] !== null) {
                                cell.power = grid[cell.row][cell.col].power;
                            }
                            continue;
                        }
                    }
                }

                if (!attackedThisRound && difficulty >= 2 && neutrals.length > 0) {
                    for (let neutral of neutrals) {
                        if (totalAttacks >= maxAttacks) break;
                        if (grid[neutral.row][neutral.col] !== null && grid[neutral.row][neutral.col].owner === null) {
                            if (cell.power > 1) {
                                grid[neutral.row][neutral.col].owner = AI;
                                grid[neutral.row][neutral.col].power = Math.min(cell.power - 1, 20);
                                cell.power = 1;
                                totalAttacks++;
                                attackedThisRound = true;
                                document.getElementById('message').textContent = `🌱 ИИ захватывает клетку! (${totalAttacks}/${maxAttacks})`;
                                addCaptureAnimation(cell.col, cell.row, neutral.col, neutral.row, AI);
                                break;
                            }
                        }
                    }
                }
            }

            if (!attackedThisRound) break;

            aiCells = [];
            for (let r = 0; r < ROWS; r++) {
                for (let c = 0; c < COLS; c++) {
                    if (grid[r][c] !== null && grid[r][c].owner === AI) {
                        aiCells.push({ col: c, row: r, power: grid[r][c].power });
                    }
                }
            }
            aiCells.sort((a, b) => b.power - a.power);
        }

        if (difficulty === 4 && totalAttacks < maxAttacks) {
            aiCells = [];
            for (let r = 0; r < ROWS; r++) {
                for (let c = 0; c < COLS; c++) {
                    if (grid[r][c] !== null && grid[r][c].owner === AI) {
                        aiCells.push({ col: c, row: r, power: grid[r][c].power });
                    }
                }
            }
            aiCells.sort((a, b) => b.power - a.power);

            for (let cell of aiCells) {
                if (totalAttacks >= maxAttacks) break;
                if (grid[cell.row][cell.col] === null || grid[cell.row][cell.col].owner !== AI) continue;
                if (grid[cell.row][cell.col].power <= 2) continue;

                const neighbors = getNeighbors(cell.col, cell.row);
                for (let n of neighbors) {
                    if (totalAttacks >= maxAttacks) break;
                    if (grid[n.row][n.col] !== null && grid[n.row][n.col].owner !== AI) {
                        const diff = cell.power - grid[n.row][n.col].power;
                        if (diff > -3) {
                            const result = executeAttack(cell.col, cell.row, n.col, n.row);
                            if (result) {
                                totalAttacks++;
                                document.getElementById('message').textContent = `💥 ИИ продолжает атаку! (${totalAttacks}/${maxAttacks})`;
                                if (grid[cell.row][cell.col] !== null) {
                                    cell.power = grid[cell.row][cell.col].power;
                                }
                            }
                        }
                    }
                }
            }
        }

        aiThinking = false;

        if (totalAttacks === 0) {
            document.getElementById('message').textContent = '🤖 ИИ пропускает атаку';
        } else {
            document.getElementById('message').textContent = `🤖 ИИ совершил ${totalAttacks} атак!`;
        }

        if (!gameOver) {
            endAITurn();
        }
    }

    // ============================================================
    //  ПРОВЕРКА ОКОНЧАНИЯ
    // ============================================================
    function checkGameOver() {
        let playerCount = 0;
        let aiCount = 0;

        for (let r = 0; r < ROWS; r++) {
            for (let c = 0; c < COLS; c++) {
                if (grid[r][c] !== null) {
                    if (grid[r][c].owner === PLAYER) playerCount++;
                    else if (grid[r][c].owner === AI) aiCount++;
                }
            }
        }

        if (playerCount === 0 || aiCount === 0) {
            gameOver = true;
            let winner = '';
            if (playerCount > aiCount) winner = '🏆 Вы победили!';
            else if (aiCount > playerCount) winner = '💻 ИИ победил!';
            else winner = '🤝 Ничья!';
            document.getElementById('message').textContent = `Игра окончена! ${winner}`;
            document.getElementById('turnIndicator').textContent = 'Игра завершена';
            document.getElementById('distributeBtn').disabled = true;
            document.getElementById('skipBtn').disabled = true;
            document.getElementById('maxBtn').disabled = true;
            if (maxModeActive) {
                maxModeActive = false;
                document.getElementById('maxBtn').classList.remove('btn-gold');
                document.getElementById('maxBtn').textContent = 'MAX';
            }
            updateUI();
            draw();
            return true;
        }
        return false;
    }

    // ============================================================
    //  UI
    // ============================================================
    function updateUI() {
        let playerCount = 0;
        let aiCount = 0;
        for (let r = 0; r < ROWS; r++) {
            for (let c = 0; c < COLS; c++) {
                if (grid[r][c] !== null) {
                    if (grid[r][c].owner === PLAYER) playerCount++;
                    else if (grid[r][c].owner === AI) aiCount++;
                }
            }
        }
        document.getElementById('playerScore').textContent = playerCount;
        document.getElementById('aiScore').textContent = aiCount;
        document.getElementById('turnNum').textContent = turnNumber;
        document.getElementById('upgradePoints').textContent = upgradePoints;
        document.getElementById('usedUpgrades').textContent = usedUpgrades;
        document.getElementById('totalUpgrades').textContent = totalUpgrades;
    }

    // ============================================================
    //  ОТРИСОВКА
    // ============================================================
    function draw() {
        ctx.clearRect(0, 0, W, H);

        const gradient = ctx.createRadialGradient(W/2, H/2, 0, W/2, H/2, W/2);
        gradient.addColorStop(0, '#0f1a2e');
        gradient.addColorStop(1, '#060a15');
        ctx.fillStyle = gradient;
        ctx.fillRect(0, 0, W, H);

        for (let r = 0; r < ROWS; r++) {
            for (let c = 0; c < COLS; c++) {
                if (grid[r][c] === null) {
                    const hex = getHexCenter(c, r);
                    drawHex(ctx, hex.x, hex.y, HEX_SIZE - 2, COLORS.water, null, false);
                    continue;
                }

                const hex = getHexCenter(c, r);
                const cell = grid[r][c];
                const isSelected = selectedCell && selectedCell.col === c && selectedCell.row === r;
                const isMaxLevel = cell.power >= 20;

                let color = COLORS.neutral;
                let glow = COLORS.neutralGlow;
                let powerColor = '#8aa';
                let borderColor = 'rgba(255,255,255,0.05)';

                if (cell.owner === PLAYER) {
                    if (isMaxLevel) {
                        color = '#8B0000';
                        glow = 'rgba(255,215,0,0.5)';
                        powerColor = '#ffd700';
                        borderColor = 'rgba(255,215,0,0.4)';
                    } else {
                        color = COLORS.player;
                        glow = COLORS.playerGlow;
                        powerColor = '#fff';
                        borderColor = 'rgba(255,107,107,0.25)';
                    }
                } else if (cell.owner === AI) {
                    if (isMaxLevel) {
                        color = '#006400';
                        glow = 'rgba(255,215,0,0.5)';
                        powerColor = '#ffd700';
                        borderColor = 'rgba(255,215,0,0.4)';
                    } else {
                        color = COLORS.ai;
                        glow = COLORS.aiGlow;
                        powerColor = '#fff';
                        borderColor = 'rgba(78,204,163,0.25)';
                    }
                }

                ctx.shadowColor = isSelected ? COLORS.selectedGlow : glow;
                ctx.shadowBlur = isSelected ? 30 : 16;

                const grad = ctx.createRadialGradient(
                    hex.x - HEX_SIZE * 0.2, hex.y - HEX_SIZE * 0.2, 2,
                    hex.x, hex.y, HEX_SIZE * 0.9
                );
                grad.addColorStop(0, lightenColor(color, 30));
                grad.addColorStop(1, color);

                drawHex(ctx, hex.x, hex.y, HEX_SIZE - 2, grad, isSelected ? COLORS.selected : borderColor, false, true);

                ctx.shadowBlur = 0;

                const innerGlow = ctx.createRadialGradient(
                    hex.x - HEX_SIZE * 0.15, hex.y - HEX_SIZE * 0.15, 0,
                    hex.x, hex.y, HEX_SIZE * 0.5
                );
                innerGlow.addColorStop(0, 'rgba(255,255,255,0.08)');
                innerGlow.addColorStop(1, 'rgba(255,255,255,0)');
                drawHex(ctx, hex.x, hex.y, HEX_SIZE - 4, innerGlow, null, false);

                ctx.fillStyle = powerColor;
                ctx.font = 'bold 16px "Segoe UI", Arial, sans-serif';
                ctx.textAlign = 'center';
                ctx.textBaseline = 'middle';
                ctx.shadowColor = 'rgba(0,0,0,0.5)';
                ctx.shadowBlur = 8;
                ctx.fillText(cell.power, hex.x + 1, hex.y + 1);

                if (isMaxLevel) {
                    ctx.shadowBlur = 0;
                    ctx.strokeStyle = COLORS.maxLevel;
                    ctx.lineWidth = 2.5;
                    ctx.shadowColor = 'rgba(255,215,0,0.4)';
                    ctx.shadowBlur = 12;
                    drawHex(ctx, hex.x, hex.y, HEX_SIZE - 2, null, COLORS.maxLevel, false);
                    ctx.shadowBlur = 0;
                }

                if (isSelected) {
                    ctx.shadowBlur = 0;
                    ctx.strokeStyle = 'rgba(255,215,0,0.6)';
                    ctx.lineWidth = 2;
                    ctx.setLineDash([4, 4]);
                    drawHex(ctx, hex.x, hex.y, HEX_SIZE - 2, null, 'rgba(255,215,0,0.4)', false);
                    ctx.setLineDash([]);
                }
            }
        }

        if (selectedCell) {
            const sel = selectedCell;
            if (grid[sel.row][sel.col] && grid[sel.row][sel.col].owner === PLAYER && grid[sel.row][sel.col].power > 1) {
                const neighbors = getNeighbors(sel.col, sel.row);
                for (let n of neighbors) {
                    if (grid[n.row][n.col] !== null && grid[n.row][n.col].owner !== PLAYER) {
                        const pos = getHexCenter(n.col, n.row);
                        ctx.beginPath();
                        ctx.arc(pos.x, pos.y, 6, 0, Math.PI * 2);
                        ctx.fillStyle = 'rgba(255,68,68,0.25)';
                        ctx.fill();
                        ctx.strokeStyle = 'rgba(255,68,68,0.5)';
                        ctx.lineWidth = 2;
                        ctx.stroke();
                    }
                }
            }
        }

        drawAnimations();
    }

    function lightenColor(hex, percent) {
        const num = parseInt(hex.replace('#', ''), 16);
        const amt = Math.round(2.55 * percent);
        const R = Math.min(255, (num >> 16) + amt);
        const G = Math.min(255, ((num >> 8) & 0x00FF) + amt);
        const B = Math.min(255, (num & 0x0000FF) + amt);
        return `#${(1 << 24 | R << 16 | G << 8 | B).toString(16).slice(1)}`;
    }

    function getHexCenter(col, row) {
        const x = HEX_SIZE + col * SPACING + (row % 2 === 0 ? 0 : SPACING / 2);
        const y = HEX_SIZE + row * (HEX_SIZE * 1.5);
        return { x, y };
    }

    function drawHex(ctx, x, y, size, fill, stroke, borderOnly = false, hasGradient = false) {
        ctx.beginPath();
        for (let i = 0; i < 6; i++) {
            const angle = Math.PI / 180 * (60 * i - 30);
            const px = x + size * Math.cos(angle);
            const py = y + size * Math.sin(angle);
            if (i === 0) ctx.moveTo(px, py);
            else ctx.lineTo(px, py);
        }
        ctx.closePath();

        if (!borderOnly) {
            if (fill) {
                ctx.fillStyle = fill;
                ctx.fill();
            }
            if (stroke) {
                ctx.strokeStyle = stroke;
                ctx.lineWidth = 1.8;
                ctx.stroke();
            }
        } else {
            ctx.strokeStyle = 'rgba(255,255,255,0.04)';
            ctx.lineWidth = 0.5;
            ctx.stroke();
        }
    }

    // ============================================================
    //  ОБРАБОТКА КЛИКОВ
    // ============================================================
    canvas.addEventListener('click', handleClick);
    canvas.addEventListener('touchstart', handleTouch);

    function handleClick(e) {
        if (!gameStarted) {
            document.getElementById('message').textContent = '⏳ Сначала начните игру через меню!';
            return;
        }
        const rect = canvas.getBoundingClientRect();
        const scaleX = canvas.width / rect.width;
        const scaleY = canvas.height / rect.height;

        const mouseX = (e.clientX - rect.left) * scaleX;
        const mouseY = (e.clientY - rect.top) * scaleY;
        handleCellClick(mouseX, mouseY);
    }

    function handleTouch(e) {
        if (!gameStarted) {
            document.getElementById('message').textContent = '⏳ Сначала начните игру через меню!';
            return;
        }
        e.preventDefault();
        const touch = e.touches[0];
        const rect = canvas.getBoundingClientRect();
        const scaleX = canvas.width / rect.width;
        const scaleY = canvas.height / rect.height;

        const mouseX = (touch.clientX - rect.left) * scaleX;
        const mouseY = (touch.clientY - rect.top) * scaleY;
        handleCellClick(mouseX, mouseY);
    }

    function handleCellClick(mouseX, mouseY) {
        let bestDist = Infinity;
        let bestCell = null;
        for (let r = 0; r < ROWS; r++) {
            for (let c = 0; c < COLS; c++) {
                if (grid[r][c] === null) continue;
                const pos = getHexCenter(c, r);
                const dist = Math.hypot(mouseX - pos.x, mouseY - pos.y);
                if (dist < bestDist && dist < HEX_SIZE * 1.1) {
                    bestDist = dist;
                    bestCell = { col: c, row: r };
                }
            }
        }

        if (!bestCell) {
            document.getElementById('message').textContent = '❌ Кликните по клетке!';
            return;
        }

        const { col, row } = bestCell;

        if (gameOver) {
            document.getElementById('message').textContent = '⏳ Игра окончена!';
            return;
        }
        if (aiThinking) {
            document.getElementById('message').textContent = '⏳ Подождите, ИИ думает...';
            return;
        }
        if (currentPlayer !== PLAYER) {
            document.getElementById('message').textContent = '⏳ Сейчас не ваш ход!';
            return;
        }

        const cell = grid[row][col];
        if (cell === null) {
            document.getElementById('message').textContent = '❌ Это вода!';
            return;
        }

        if (skipPressed && canUpgradeAfterSkip) {
            if (cell.owner === PLAYER) {
                if (cell.power >= 20) {
                    document.getElementById('message').textContent = '⚠️ Эта клетка уже имеет максимальную силу (20)!';
                    return;
                }
                if (upgradePoints > 0) {
                    upgradeCell(col, row);
                    return;
                } else {
                    document.getElementById('message').textContent = '❌ Нет очков прокачки!';
                    return;
                }
            } else {
                document.getElementById('message').textContent = '⚠️ Сейчас можно только прокачивать свои клетки!';
                return;
            }
        }

        if (selectedCell) {
            const sel = selectedCell;
            const neighbors = getNeighbors(sel.col, sel.row);
            const isNeighbor = neighbors.some(n => n.col === col && n.row === row);

            if (isNeighbor && grid[sel.row][sel.col] !== null && grid[sel.row][sel.col].owner === PLAYER) {
                if (cell.owner !== PLAYER && grid[sel.row][sel.col].power > 1) {
                    const result = executeAttack(sel.col, sel.row, col, row);
                    if (result) {
                        selectedCell = null;
                        document.getElementById('message').textContent = '💥 Атака выполнена!';
                        updateUI();
                        draw();
                        return;
                    }
                } else if (cell.owner === PLAYER) {
                    selectedCell = { col, row };
                    draw();
                    return;
                } else if (grid[sel.row][sel.col].power <= 1) {
                    document.getElementById('message').textContent = '⚠️ Нельзя атаковать с силой 1!';
                    selectedCell = null;
                    draw();
                    return;
                }
            }

            if (cell.owner === PLAYER) {
                selectedCell = { col, row };
                draw();
                return;
            }

            selectedCell = null;
            draw();
            return;
        }

        if (cell.owner === PLAYER && cell.power > 1) {
            selectedCell = { col, row };
            draw();
            return;
        } else if (cell.owner === PLAYER && cell.power <= 1) {
            document.getElementById('message').textContent = '⚠️ Нельзя атаковать с силой 1! Нажмите "Пропустить", чтобы прокачаться';
            return;
        }

        if (cell.owner !== PLAYER) {
            const neighbors = getNeighbors(col, row);
            let attackFrom = null;
            for (let n of neighbors) {
                if (grid[n.row][n.col] !== null && grid[n.row][n.col].owner === PLAYER && grid[n.row][n.col].power > 1) {
                    attackFrom = n;
                    break;
                }
            }
            if (attackFrom) {
                const result = executeAttack(attackFrom.col, attackFrom.row, col, row);
                if (result) {
                    document.getElementById('message').textContent = '💥 Атака выполнена!';
                    updateUI();
                    draw();
                    return;
                }
            } else {
                document.getElementById('message').textContent = '❌ Нет своей клетки с силой > 1 рядом!';
            }
        }
    }

    // ============================================================
    //  ОБУЧЕНИЕ (TUTORIAL) — только отдельная версия
    // ============================================================
    let tutorialStep2 = 0;
    const totalTutorialSteps = 6;

    function initTutorialDots() {
        const container = document.getElementById('tutDots2');
        if (!container) return;
        container.innerHTML = '';
        for (let i = 0; i < totalTutorialSteps; i++) {
            const dot = document.createElement('span');
            dot.className = 'dot' + (i === 0 ? ' active' : '');
            dot.dataset.index = i;
            dot.onclick = function() {
                tutorialStep2 = i;
                updateTutorialUI();
            };
            container.appendChild(dot);
        }
    }

    function updateTutorialUI() {
        const container = document.getElementById('tutorialContainer2');
        if (!container) return;
        
        // Находим все слайды внутри контейнера
        const slides = container.querySelectorAll('.tutorial-slide');
        slides.forEach((slide, i) => {
            slide.classList.toggle('active', i === tutorialStep2);
        });

        // Обновляем точки
        const dots = document.getElementById('tutDots2');
        if (dots) {
            const dotElements = dots.querySelectorAll('.dot');
            dotElements.forEach((dot, i) => {
                dot.classList.toggle('active', i === tutorialStep2);
            });
        }

        // Обновляем кнопки
        const prevBtn = document.getElementById('tutPrev2');
        const nextBtn = document.getElementById('tutNext2');
        if (prevBtn) prevBtn.disabled = tutorialStep2 === 0;
        if (nextBtn) {
            nextBtn.textContent = tutorialStep2 === totalTutorialSteps - 1 ? '✅ Завершить' : 'Далее →';
        }
    }

    function tutorialNext2() {
        if (tutorialStep2 < totalTutorialSteps - 1) {
            tutorialStep2++;
            updateTutorialUI();
        } else {
            // Завершаем обучение
            document.getElementById('message').textContent = '📖 Обучение завершено! Теперь выберите сложность и карту в меню "Играть".';
            showMainMenu();
        }
    }

    function tutorialPrev2() {
        if (tutorialStep2 > 0) {
            tutorialStep2--;
            updateTutorialUI();
        }
    }

    // ============================================================
    //  НАВИГАЦИЯ ПО МЕНЮ
    // ============================================================
    function showMenu() {
        document.getElementById('menuOverlay').classList.add('active');
        document.getElementById('mainMenu').classList.add('active');
        showMainMenu();
        document.querySelectorAll('.map-btn').forEach(btn => {
            btn.classList.toggle('active', parseInt(btn.dataset.map) === currentMap);
        });
    }

    function showMainMenu() {
        document.getElementById('menuMain').style.display = 'flex';
        document.getElementById('menuSubPlay').classList.remove('active');
        document.getElementById('menuSubPlay').style.display = 'none';
        document.getElementById('menuSubTutorial').classList.remove('active');
        document.getElementById('menuSubTutorial').style.display = 'none';
        document.getElementById('menuSubSettings').classList.remove('active');
        document.getElementById('menuSubSettings').style.display = 'none';
        // Сбрасываем обучение
        tutorialStep2 = 0;
        updateTutorialUI();
    }

    function showSubMenu(type) {
        document.getElementById('menuMain').style.display = 'none';
        
        if (type === 'play') {
            const sub = document.getElementById('menuSubPlay');
            sub.style.display = 'flex';
            setTimeout(() => sub.classList.add('active'), 10);
            document.querySelectorAll('.map-btn').forEach(btn => {
                btn.classList.toggle('active', parseInt(btn.dataset.map) === currentMap);
            });
            document.getElementById('message').textContent = '🎮 Выберите сложность и карту, чтобы начать!';
        } else if (type === 'tutorial') {
            const sub = document.getElementById('menuSubTutorial');
            sub.style.display = 'flex';
            setTimeout(() => sub.classList.add('active'), 10);
            tutorialStep2 = 0;
            initTutorialDots();
            updateTutorialUI();
            document.getElementById('message').textContent = '📖 Обучение — изучайте механику игры';
        } else if (type === 'settings') {
            const sub = document.getElementById('menuSubSettings');
            sub.style.display = 'flex';
            setTimeout(() => sub.classList.add('active'), 10);
        }
    }

    function selectMap(mapType) {
        currentMap = mapType;
        document.querySelectorAll('.map-btn').forEach(btn => {
            btn.classList.toggle('active', parseInt(btn.dataset.map) === mapType);
        });
    }

    function startGame(diff) {
        difficulty = diff;
        document.getElementById('menuOverlay').classList.remove('active');
        document.getElementById('mainMenu').classList.remove('active');

        gameStarted = true;
        resetGame();

        const diffNames = ['', '🌱 Лёгкий', '⚡ Средний', '🔥 Сложный', '💀 Невозможный'];
        const mapNames = ['', 'Острова', 'Долина', 'Пустыня', 'Нагорье'];
        document.getElementById('message').textContent = `🎮 Игра начата! Сложность: ${diffNames[diff]}, Карта: ${mapNames[currentMap]}`;
    }

    // ============================================================
    //  СБРОС
    // ============================================================
    function resetGame() {
        if (animFrameId) {
            cancelAnimationFrame(animFrameId);
            animFrameId = null;
        }
        animations = [];

        initGrid(currentMap);
        currentPlayer = PLAYER;
        turnNumber = 1;
        selectedCell = null;
        gameOver = false;
        aiThinking = false;
        skipPressed = false;
        canUpgradeAfterSkip = false;
        usedUpgrades = 0;
        isFirstTurn = true;
        playerUpgradedThisTurn = false;
        maxModeActive = false;
        document.getElementById('maxBtn').classList.remove('btn-gold');
        document.getElementById('maxBtn').textContent = 'MAX';
        document.getElementById('maxBtn').disabled = true;
        document.getElementById('distributeBtn').disabled = true;
        document.getElementById('skipBtn').disabled = false;

        document.getElementById('message').textContent = '🔄 Новая игра!';
        document.getElementById('turnIndicator').textContent = '🔴 Ваш ход';
        document.getElementById('turnIndicator').style.color = '#ff6b6b';
        updateUI();
        draw();

        setTimeout(() => {
            startPlayerTurn();
        }, 200);
    }

    // ============================================================
    //  ЗАПУСК
    // ============================================================
    // Инициализируем сетку для отображения в меню
    initGrid(1);
    updateUI();
    draw();

    // Меню открыто по умолчанию
    document.getElementById('menuOverlay').classList.add('active');
    document.getElementById('mainMenu').classList.add('active');
    showMainMenu();
    document.querySelector('.map-btn[data-map="1"]').classList.add('active');

    // Инициализируем обучение
    initTutorialDots();
    updateTutorialUI();
    document.getElementById('message').textContent = '📖 Добро пожаловать!';

    console.log('✦ HEXAGONIC — 4 УРОВНЯ СЛОЖНОСТИ, 4 КАРТЫ С РАЗНООБРАЗИЕМ');
    console.log('📖 Обучение вынесено в отдельную кнопку.');
    console.log('🎮 Игра начинается только после выбора сложности и карты в меню.');
</script>
</body>
</html>

Game Source: Hexagonic

Creator: NeonFlare13

Libraries: none

Complexity: complex (2536 lines, 100.2 KB)

The full source code is displayed above on this page.

Remix Instructions

To remix this game, copy the source code above and modify it. Add a ARCADELAB header at the top with "remix_of: hexagonic-neonflare13" to link back to the original. Then publish at arcadelab.ai/publish.