Поиск пути

Доброго времени суток! Поговорим о такой вещи как поиск пути, чаще всего, конечно используемой в играх. В одних играх боты просто ходят взад-вперед по заранее предопределенному пути. В других юниты двигаются в определенном направлении, пока не встретят препятствие. Бывает что препятствия вообще не учитываются. Ну и наконец игры в которых юниты находят кратчайший путь до нужного им места в обход препятствий. Вот об этом и будет беседа.

Итак, как это работает. Алгоритмов поиска пути и их модификаций на самом деле достаточно много. Один из хорошо зарекомендовавших себя — AStar (А*), младший и более шустрый брат алгоритма Дейкстры. Его особенность в том, что он работает эвристически (грубо говоря интуитивно). Он обходит узел за узлом, переходя в теоретически наиболее ближний к цели узел, попутно корректируя путь, если это не так.

AStar

На сколько тот или иной узел близок к целевому определяется суммой расстояний от начального узла до текущего и от текущего до конечного. Например так:
2 3
g — стоимость пути от начального узла до текущего. Как видно на изображениях выше g складывается из стоимости всех пройденных узлов.
h — эвристическая стоимость пути от текущего узла до конечного. Мы не знаем ее наверняка, а рассчитываем, какова эта стоимость была бы если бы мы двигались по прямой.
На самом деле разные реализации алгоритма могут немного отличаться друг от друга. Здесь я рассчитываю h по теореме Пифагора, в других реализациях вы можете увидеть пересчет количества узлов до конечой точки или умножение вектора x на вектор y. Здесь всем заведует отношение скорости выполнения к возможной погрешности. Я же сейчас не ставлю перед собой задачи сделать наиболее быструю реализацию алгоритма, поэтому могу себе позволить более точные вычисления.

А теперь в коде:
Класс сетки/карты:

Класс узла:

И непосредственно класс поиска пути:

Использовать довольно просто:

Я привел вполне работоспособную, но в тоже время достаточно простую реализацию этого алгоритма. В реальных проектах вы вероятно захотите ввести еще стоимость клеток, ведь поверхность земли бывает неоднородной (лед, болота, зыбучие пески). Так же вы можете попробовать его ускорить, например, возможно положительно скажется на скорости работы замена пересортировки вектора открытого списка на сохранение индекса следующего узла. Или замена формулы вычисления стоимости h на более легкую. Вобщем желаю вам удачи в экспериментах!
И конечно же пример:
(клик — поиск пути и перемещение, Ctrl+клик — изменение проходимости узла)

Добавить комментарий