Files
football/docs/plans/2026-05-12-match-logic-impl.md
2026-05-12 10:54:09 +03:00

4.9 KiB
Raw Blame History

План: Game Rules & Match Logic (M5)

Цель: Реализовать систему судейства, подсчёт голов, таймер матча и управление состояниями игры (Playing, GoalPause, MatchEnded).

Архитектура: Введение MatchManager в качестве верхнего уровня управления. Он владеет World и контролирует, когда физика и ИИ мира должны обновляться, а когда игра должна быть заморожена.

Стек: Go.

Спека: docs/specs/2026-05-12-match-logic-design.md


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

  • internal/game/world.go — добавление методов для проверки гола и сброса позиций.
  • internal/game/match_manager.go — новый файл с логикой управления матчем, счетом и таймерами.
  • cmd/game/main.go — замена World на MatchManager в основном цикле игры.

Задачи

Задача 1: Методы управления состоянием мира

Файлы:

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

  • Шаг 1: Реализовать CheckGoal()

    • Метод должен проверять Puck.Position.X.
    • Если X < 0 \rightarrow возвращает (entities.TeamBlue, true).
    • Если X > WorldWidth \rightarrow возвращает (entities.TeamRed, true).
    • Иначе \rightarrow (entities.TeamRed, false).
  • Шаг 2: Реализовать ResetPositions()

    • Установить Puck.Position в центр поля, Puck.Velocity = 0.
    • Для каждого игрока в Players установить Position = HomePosition и Velocity = 0.
  • Шаг 3: Коммит git add internal/game/world.go && git commit -m "feat(game): add CheckGoal and ResetPositions to World"

Задача 2: Реализация MatchManager

Файлы:

  • Создать: internal/game/match_manager.go

  • Шаг 1: Определить типы и структуру

    • GameState (enum: Playing, GoalPause, MatchEnded).
    • MatchManager структура:
      • World *World
      • State GameState
      • ScoreRed, ScoreBlue int
      • MatchDuration float64 (в секундах)
      • CurrentTime float64
      • PauseDuration float64
      • PauseTimer float64
  • Шаг 2: Реализовать Update(dt float64)

    • Логика переключения состояний:
      • Если Playing:
        • Проверить World.CheckGoal(). Если гол \rightarrow State = GoalPause, обновить счет, PauseTimer = PauseDuration.
        • Если не гол \rightarrow вызвать World.Update(dt).
        • Обновить CurrentTime += dt. Если CurrentTime >= MatchDuration \rightarrow State = MatchEnded.
      • Если GoalPause:
        • PauseTimer -= dt.
        • Если PauseTimer <= 0 \rightarrow вызвать World.ResetPositions(), State = Playing.
      • Если MatchEnded:
        • Ничего не делать.
  • Шаг 3: Коммит git add internal/game/match_manager.go && git commit -m "feat(game): implement MatchManager for game rules"

Задача 3: Интеграция в Main Loop

Файлы:

  • Изменить: cmd/game/main.go

  • Шаг 1: Обновить структуру Game

    • Заменить world *game.World на matchManager *game.MatchManager.
  • Шаг 2: Обновить инициализацию в NewGame()

    • Создать world := game.NewWorld().
    • Создать matchManager := game.NewMatchManager(world).
  • Шаг 3: Обновить Update() и Draw()

    • В Update() вызывать g.matchManager.Update(dt).
    • В Draw() передавать g.matchManager.World в функцию отрисовки.
  • Шаг 4: Коммит git add cmd/game/main.go && git commit -m "feat(game): integrate MatchManager into main loop"

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

  • Шаг 1: Проверка сценария "Гол"

    • Запустить игру, забить гол.
    • Ожидание: Игра замирает, через несколько секунд все возвращаются в центр.
  • Шаг 2: Проверка сценария "Конец матча"

    • Установить короткий MatchDuration (например, 10 сек).
    • Ожидание: Через 10 секунд игра замирает навсегда.
  • Шаг 3: Коммит git commit -m "test(game): verify match logic flow"