Files
football/docs/plans/2026-05-09-tactical-ai.md
2026-05-12 10:54:09 +03:00

5.9 KiB
Raw Blame History

План: Тактический ИИ и Ролевая Логика (M4)

Цель: Реализовать роль Вратаря с логикой перекрытия углов и систему зонирования для нападающих и защитников.

Архитектура:

  • Введение RoleGoalie в перечисление ролей.
  • Реализация специализированного метода updateGoalieAI, который вычисляет целевую точку на векторе «Центр ворот -> Шайба» с ограничением по радиусу.
  • Внедрение системы зон (Защитная, Средняя, Атакующая) для динамического изменения агрессивности игроков.

Стек: Go

Спека: docs/specs/2026-05-09-tactical-ai-design.md


Файловая структура

  • internal/entities/player.go — добавление RoleGoalie.
  • internal/game/world.go — константы зон, логика ИИ вратаря и зонирования.
  • internal/game/world_test.go — тесты на поведение вратаря и смену зон.

Задачи

Задача 1: Расширение ролей и константы зон

Файлы:

  • Изменить: internal/entities/player.go

  • Изменить: internal/game/world.go

  • Шаг 1: Добавить RoleGoalie в PlayerRole

type PlayerRole int
const (
    RoleStriker PlayerRole = iota
    RoleDefender
    RoleGoalie // Добавить это
)
  • Шаг 2: Добавить константы зон в world.go
const (
    ZoneWidth = WorldWidth / 3
    GoalieMaxDistance = 80.0 // Максимальный выход вратаря из ворот
)
  • Шаг 3: Коммит git add internal/entities/player.go internal/game/world.go git commit -m "feat(ai): add RoleGoalie and zone constants"

Задача 2: Реализация ИИ Вратаря (Перехватчик)

Файлы:

  • Изменить: internal/game/world.go

  • Шаг 1: Реализовать updateGoalieAI Логика:

  1. Определить центр своих ворот (GoalLeft или GoalRight).
  2. Вычислить вектор от центра ворот к шайбе.
  3. Целевая точка = Центр ворот + (Нормализованный вектор * min(дистанция_доайбы, GoalieMaxDistance)).
  4. Ограничить Y в пределах ворот (например, +/- 100 пикселей от центра).
func (w *World) updateGoalieAI(p *entities.Player, puckPos entities.Vector2D) entities.Vector2D {
    goalPos := GoalLeft
    if p.Team == TeamRight {
        goalPos = GoalRight
    }

    // Вектор от ворот к шайбе
    dir := puckPos.Sub(goalPos)
    dist := dir.Len()
    
    // Ограничиваем выход из ворот
    moveDist := dist
    if moveDist > GoalieMaxDistance {
        moveDist = GoalieMaxDistance
    }
    
    target := goalPos.Add(dir.Normalize().Mul(moveDist))
    
    // Ограничение по Y (чтобы не уходил за пределы ворот)
    if target.Y < WorldCenterY-100 { target.Y = WorldCenterY-100 }
    if target.Y > WorldCenterY+100 { target.Y = WorldCenterY+100 }
    
    return target
}
  • Шаг 2: Интегрировать в updatePlayerAI
switch p.Role {
case entities.RoleGoalie:
    target = w.updateGoalieAI(p, puckPos)
// ... остальные роли
}
  • Шаг 3: Коммит git commit -m "feat(ai): implement goalie interceptor logic"

Задача 3: Система зонирования для полевых игроков

Файлы:

  • Изменить: internal/game/world.go

  • Шаг 1: Реализовать определение зоны

func (w *World) getPlayerZone(p *entities.Player) int {
    // 0: Защитная, 1: Средняя, 2: Атакующая
    // Для TeamLeft: X < ZoneWidth (Защитная), X < 2*ZoneWidth (Средняя), else (Атакующая)
    // Для TeamRight: X > 2*ZoneWidth (Защитная), X > ZoneWidth (Средняя), else (Атакующая)
    if p.Team == TeamLeft {
        if p.Pos.X < ZoneWidth { return 0 }
        if p.Pos.X < 2*ZoneWidth { return 1 }
        return 2
    } else {
        if p.Pos.X > 2*ZoneWidth { return 0 }
        if p.Pos.X > ZoneWidth { return 1 }
        return 2
    }
}
  • Шаг 2: Обновить логику Striker и Defender с учетом зон

  • Striker: В зоне 0 (защитной) стремится к центру поля, в зоне 2 (атакующей) — агрессивно к шайбе.

  • Defender: В зоне 0 — агрессивно к шайбе, в зоне 2 — возвращается к своим воротам.

  • Шаг 3: Коммит git commit -m "feat(ai): implement player zoning logic"

Задача 4: Тестирование и верификация

Файлы:

  • Изменить: internal/game/world_test.go

  • Шаг 1: Тест TestWorld_GoaliePositioning

  • Проверить, что вратарь TeamLeft при шайбе в центре поля стоит в районе GoalLeft и не уходит дальше GoalieMaxDistance.

  • Проверить, что вратарь смещается вслед за шайбой по Y.

  • Шаг 2: Тест TestWorld_ZoningBehavior

  • Проверить, что защитник в атакующей зоне стремится вернуться назад.

  • Шаг 3: Запуск тестов go test ./internal/game/ -v

  • Шаг 4: Коммит git commit -m "test(ai): add goalie and zoning tests"