A* алгоритм поиска пути

🎯 Что такое A* и зачем он нужен?

Представь, что твой игровой персонаж должен найти самый короткий путь к сокровищу, обходя препятствия. Именно для этого и существует A* (произносится как "А-звезда") — это умный алгоритм поиска пути, который учитывает не только пройденное расстояние, но и примерное расстояние до цели.

💡 Главное преимущество A* — он не просто слепо ищет путь во всех направлениях, а целенаправленно движется к цели, что делает его очень эффективным.

🧭 Основные компоненты алгоритма

Чтобы понять, как работает A*, нужно знать три ключевые величины для каждой точки (ноды) на карте:

  • G-стоимость ➕ Реальная стоимость пути от старта до этой точки
  • H-стоимость ➕ Предполагаемая стоимость от этой точки до цели (эвристика)
  • F-стоимость ➕ Сумма G и H: F = G + H

Обозначение Значение Пример
G Пройденный путь 10
H Предполагаемый путь до цели 15
F Общая оценка 10 + 15 = 25

🎯 Эвристика (H) — это обоснованное предположение о расстоянии до цели. В играх часто используют манхэттенское расстояние или евклидово расстояние.

🔍 Как работает алгоритм шаг за шагом

Алгоритм использует два списка для отслеживания точек:

  1. Открытый список — точки, которые нужно исследовать
  2. Закрытый список — точки, которые уже исследованы

Процесс поиска пути:

  1. Добавляем начальную точку в открытый список
  2. Пока открытый список не пуст:
    • Находим точку с наименьшей F-стоимостью
    • Перемещаем ее в закрытый список
    • Для каждого соседа этой точки:
      • Если это цель — путь найден!
      • Если непроходимо или в закрытом списке — пропускаем
      • Рассчитываем новую G-стоимость
      • Если она лучше предыдущей — обновляем данные
  3. Если открытый список пуст, а цель не найдена — пути не существует


📐 Выбор эвристической функции

Эвристика помогает алгоритму "предугадывать" направление к цели. Вот основные типы:

Тип расстояния Формула Лучше всего подходит для
Манхэттенское |x1 - x2| + |y1 - y2| Сеток с движением по горизонтали/вертикали
Евклидово √((x1 - x2)² + (y1 - y2)²) Плавного движения в любом направлении
Диагональное max(|x1 - x2|, |y1 - y2|) Движения в 8 направлениях (как в шахматах)

⚡ Важно: эвристика никогда не должна завышать реальное расстояние, иначе A* может не найти оптимальный путь!

🧩 Практическая задача

Давай найдем путь от точки A до точки B на сетке 3x3. Препятствие в центре.

Сетка:

A . .
. X .
. . B

Координаты: A(0,0), B(2,2), препятствие на (1,1)

📝 Пошаговое решение:

Шаг 1: Начинаем с точки A(0,0). Добавляем в открытый список.

G = 0, H = |0-2| + |0-2| = 4, F = 0 + 4 = 4

Шаг 2: Исследуем соседей A — (0,1) и (1,0).

Для (0,1): G = 1, H = |0-2| + |1-2| = 3, F = 4

Для (1,0): G = 1, H = |1-2| + |0-2| = 3, F = 4

Шаг 3: Выбираем точку с минимальной F (любую из них). Допустим, (0,1).

Исследуем ее соседей: (0,2), (1,1) — но (1,1) непроходимо!

Для (0,2): G = 2, H = |0-2| + |2-2| = 2, F = 4

Шаг 4: Теперь из открытых точек минимальную F имеет (1,0) — F = 4.

Исследуем ее соседей: (2,0), (1,1) — пропускаем непроходимое.

Для (2,0): G = 2, H = |2-2| + |0-2| = 2, F = 4

Шаг 5: Теперь у нас есть (0,2) и (2,0) с F = 4. Выбираем (0,2).

Исследуем соседей: (1,2) — можно пройти!

Для (1,2): G = 3, H = |1-2| + |2-2| = 1, F = 4

Шаг 6: Из (1,2) переходим к цели (2,2)!

Найденный путь: A(0,0) → (0,1) → (0,2) → (1,2) → B(2,2)


💡 Советы по реализации в геймдеве

  • Используйте приоритетную очередь для открытого списка для эффективности
  • Для больших картин используйте бинарную кучу вместо простого списка
Скрыть рекламу навсегда

🧠 Учёба без воды и зубрёжки

Закрытый Boosty с наработками опытного преподавателя.

Объясняю сложное так, чтобы щелкнуло.

🚀 Забрать доступ к Boosty