# HEXO Учебный проект. Игра, клон [DiceWars](https://www.gamedesign.jp/games/dicewars/) ## Запуск игры ```bash npm run serve # Запустить веб-сервер (http://localhost:8080) npm test # Запустить тесты (88 тестов) npm start # Консольная версия карты ``` ## Экран запуска При запуске игры открывается экран настройки: 1. **Выберите количество игроков**: 2, 3 или 4 2. **Выберите размер карты**: - **Small (10×10)** — Быстрая игра на маленькой карте - **Medium (15×15)** — Сбалансированный размер - **Large (20×20)** — Стандартный размер (по умолчанию) - **Extra Large (25×25)** — Большая карта для длительных игр 3. **Настройте тип каждого игрока**: - **Human** — управление человеком (клики мышью) - **AI Bot** — управление компьютером 4. Нажмите **Start Game** для начала игры ### Комбинации игроков Можно создавать любые комбинации: - Все игроки — люди (Hotseat) - Все игроки — AI боты (наблюдение за игрой ИИ) - Смешанный режим (например, P1-Human, P2-AI, P3-Human, P4-AI) ## Цвета игроков | Игрок | Цвет | HEX | |-------|------|-----| | P1 | 🟢 Зелёный | `#4ecca3` | | P2 | 🔴 Красный | `#e94560` | | P3 | 🟡 Жёлтый | `#f9ed69` | | P4 | 🔵 Бирюзовый | `#00adb5` | ## AI Bot ### Как работает AI бот автоматически играет за выбранного игрока: 1. **Анализ поля** — бот оценивает все возможные ходы 2. **Приоритеты ходов**: - 🎯 Атака слабого противника (высокий шанс победы) — приоритет 100+ - 📈 Захват пустых клеток (расширение территории) — приоритет 50+ - 💪 Укрепление позиций (перемещение к сильным клеткам) 3. **Задержка мышления** — 1000 мс перед каждым ходом для естественности геймплея 4. **Несколько ходов за turn** — AI делает все возможные ходы подряд, затем завершает ход ### Индикаторы AI - В карточке игрока отображается метка **(AI)** - Во время хода AI в панели действий показано: *"AI is thinking..."* - Кнопки управления отключены во время хода AI ### Логика принятия решений ```javascript movePriority(move) { let priority = 0; // Атака слабого врага (высший приоритет) if (move.type === 'attack') { if (move.attackStrength > move.defenseStrength) { priority += 100; // Высокий шанс победы priority += move.attackStrength - move.defenseStrength; } else { priority -= 50; // Рискованная атака } } // Расширение на пустые клетки (средний приоритет) if (move.type === 'expand') { priority += 50; priority += move.attackStrength; } // Бонус за сильную позицию priority += move.attackStrength * 0.5; return priority; } ``` ## Правила игры ### 1. Карта - Гексагональная сетка **10×10**, **15×15**, **20×20** или **25×25** ячеек - Каждая ячейка может быть: - **Проходима** (пустая или принадлежит игроку) - **Непроходима** (заблокирована, серый цвет, ~15% карты) ### 2. Игровые единицы - **Кубик**: 6-гранный, значения 1-6 - На поле может быть до **8 кубиков** на клетку - **Сила юнита**: `F = (cnt-1) × 6 + current_dice` - `cnt` — количество кубиков - `current_dice` — значение верхнего кубика **Примеры расчёта силы:** | Кубики | Сила | |--------|------| | [4] | 4 | | [6] | 6 | | [6, 1] | 7 | | [6, 6, 2] | 14 | | [6, 6, 6, 6, 6, 6, 6, 6] | 48 (максимум) | ### 3. Ход игры #### Перемещение/Атака - Можно ходить, если **сила > 1** - На целевую клетку переходит `сила-1`, на исходной остаётся **1** - При атаке оба игрока бросают кости: - **Атакующий**: `attack_roll = rnd(1..сила-1)` - **Защищающийся**: `defense_roll = rnd(1..сила)` #### Результат боя | Условие | Результат | |---------|-----------| | `attack_roll > defense_roll` | Атакующий побеждает, занимает клетку с `attack_roll-1`. На исходной клетке остаётся **1** | | `attack_roll <= defense_roll` | Атака отбита. Атакующий уменьшается до **1**. Защитник остаётся с `defense_roll - attack_roll` (мин. **1**) | #### Снабжение После хода игрок получает снабжение: - **Снабжение = размер наибольшей непрерывной территории** - **Непрерывная территория** — связанные между собой клетки игрока - Если территория разорвана врагом — считается только наибольший кусок - Снабжение распределяется по **1 единице** случайным клеткам (не максимальным) - **Максимум на клетке**: 48 (8 кубиков × 6) ### 4. Победа **Последний игрок**, оставшийся с клетками на карте, побеждает. ## Управление | Действие | Управление | |----------|------------| | Выбрать клетку | Клик на свою клетку с кубиками | | Атаковать | Клик на соседнюю вражескую/пустую клетку | | Отменить выбор | Кнопка **Cancel** или клик на ту же клетку | | Завершить ход | Кнопка **End Turn** | | Вернуться в меню | Кнопка **Main Menu** | ### Индикаторы на экране - **Выделенная клетка** — красная подсветка - **Доступные цели** — зелёная подсветка соседних клеток - **Лог боёв** — правая панель с историей действий - **Инфо о клетке** — сила и количество кубиков выбранной клетки ## Настройки игры Игра поддерживает: - **2-4 игрока** (любая комбинация людей и AI) - **4 размера карты**: 10×10, 15×15, 20×20, 25×25 - **Случайная генерация карты** при каждом запуске - **Случайные стартовые позиции** для игроков ## Стартовые позиции Игроки размещаются в углах карты (позиции масштабируются с размером карты): | Игрок | Позиция | Описание | |-------|---------|----------| | P1 | (offset, offset) | Верхний-левый угол | | P2 | (size-1-offset, size-1-offset) | Нижний-правый угол | | P3 | (offset, size-1-offset) | Нижний-левый угол | | P4 | (size-1-offset, offset) | Верхний-правый угол | `offset = max(1, floor(size / 10))` Каждый игрок начинает с **силой 8** на своей стартовой позиции. ## Тестирование Проект покрыт **88 тестами**, проверяющими: - **Динамические размеры карт** (10×10, 15×15, 20×20, 25×25) - **HexCell**: создание, расчёт силы, максимальная сила, добавление кубиков - **HexMap**: генерация, соседи, снабжение, владение - **Логика выбора целей**: атака врагов, захват пустых клеток, блокировка своих клеток - **AIBot**: поиск ходов, приоритеты, выполнение ходов, завершение хода - **Интеграционные тесты**: 4 AI бота одновременно, разные размеры карт ```bash npm test ``` Все тесты проходят успешно ✅