# План: Автономные игроки и ИИ (M3) **Цель:** Реализовать автономных игроков с ролевым и зональным ИИ, которые двигаются плавно и соблюдают тактические позиции. **Архитектура:** Разделение данных игрока (`Player` entity) и логики поведения. Использование steering-подхода для плавного движения. **Стек:** Go, Ebitengine. **Спека:** [docs/specs/2026-05-09-players-ai-design.md](../specs/2026-05-09-players-ai-design.md) --- ## Файловая структура - `internal/entities/player.go` — новая сущность игрока, типы `Team` и `Role`. - `internal/game/world.go` — интеграция игроков в мир, логика AI, физика движения. - `internal/game/world_test.go` — тесты поведения AI. --- ## Задачи ### Задача 1: Сущность Игрока **Файлы:** - Создать: `internal/entities/player.go` - [ ] **Шаг 1: Определить типы и структуру** - Создать `Team` (Red, Blue) и `Role` (Striker, Defender). - Создать структуру `Player` с полями: `Position`, `Velocity`, `Radius`, `Team`, `Role`, `HomePosition`, `MaxSpeed`, `Acceleration`. - [ ] **Шаг 2: Коммит** `git add internal/entities/player.go && git commit -m "feat(entities): add player entity"` ### Задача 2: Интеграция игроков в World **Файлы:** - Изменить: `internal/game/world.go` - [ ] **Шаг 1: Добавить константы ворот и список игроков** - Добавить `GoalLeft` и `GoalRight` (точки в центре левого и правого краев). - Добавить `Players []*Player` в структуру `World`. - [ ] **Шаг 2: Инициализация игроков** - В `NewWorld` создать по 2 игрока для каждой команды (1 защитник, 1 нападающий) и расставить их по начальным позициям. - [ ] **Шаг 3: Коммит** `git add internal/game/world.go && git commit -m "feat(game): integrate players into world"` ### Задача 3: Реализация AI и Steering **Файлы:** - Изменить: `internal/game/world.go` - [ ] **Шаг 1: Реализовать расчет Target Point** - Создать метод `calculateTarget(p *Player, puckPos Vector2D) Vector2D`. - Логика для Защитника: если шайба на чужой половине -> `HomePosition`, иначе -> точка между шайбой и воротами. - Логика для Нападающего: если шайба в зоне -> позиция шайбы, иначе -> центр/позиция между центром и чужими воротами. - [ ] **Шаг 2: Реализовать Steering-физику** - В `World.Update` для каждого игрока: 1. Вычислить `Target Point`. 2. Вычислить `Desired Velocity` (нормализованный вектор к цели * `MaxSpeed`). 3. Применить ускорение: `Velocity += (DesiredVelocity - Velocity) * factor`, ограничив по `Acceleration`. 4. Обновить `Position += Velocity`. 5. Добавить clamping по границам экрана. - [ ] **Шаг 3: Добавить Anti-Clumping и Dead Zone** - Добавить небольшое отталкивание между игроками одной команды. - Добавить порог остановки, чтобы избежать дрожания. - [ ] **Шаг 4: Коммит** `git add internal/game/world.go && git commit -m "feat(game): implement player AI and steering physics"` ### Задача 4: Рендеринг игроков **Файлы:** - Изменить: `internal/game/world.go` (или там, где происходит отрисовка) - [ ] **Шаг 1: Отрисовка игроков** - В методе отрисовки добавить цикл по `World.Players`. - Рисовать круг: Красный для `TeamRed`, Синий для `TeamBlue`. - [ ] **Шаг 2: Коммит** `git add internal/game/world.go && git commit -m "feat(game): render players"` ### Задача 5: Тестирование и Полировка **Файлы:** - Изменить: `internal/game/world_test.go` - [ ] **Шаг 1: Написать тесты на AI** - Проверить, что защитник возвращается к воротам при удалении шайбы. - Проверить, что нападающий движется к шайбе. - [ ] **Шаг 2: Запустить тесты и убедиться, что проходят** `go test ./internal/game/... -v` - [ ] **Шаг 3: Коммит** `git add internal/game/world_test.go && git commit -m "test(game): add AI behavior tests"`