Я возился с написанием действительно плохой тактической RPG на C ++. Пока у меня есть 2D-карта тайлов, и я только что получил алгоритм A *, основанный на псевдокоде в википедии .
Но настоящие тактические РПГ не просто находят лучший путь на плоской плоскости и двигаются туда. Они обычно имеют ограниченные диапазоны перемещения и должны подниматься или опускаться. Если вы когда-либо играли в Final Fantasy Tactics, на них повлияла бы статистика Move и Jump. Это где я заблудился. Как я могу изменить алгоритм A *, чтобы он нашел лучший путь к цели, но этот путь занимает только столько плиток? Как я должен принимать во внимание разницу в высоте и прыгать статистику? Как мне реализовать перепрыгивание через пробел?
Если это поможет, сейчас моя карта представлена объектами Vector of Tile. Каждая плитка имеет указатели на плитку «Север», «Юг», «Восток» и «Запад», которые устанавливаются в nullptr, если там нет плитки, например, вдоль края карты или если мозаика установлена в непроходимую.
источник
Ответы:
Восхождение и разрывы - это просто разные функции стоимости. Для юнита, который может прыгнуть, разрыв имеет нормальную (?) Стоимость, в то время как для непрыгающего юнита он имеет произвольно высокую стоимость. Восхождение стоит дороже, так же как и сложный рельеф и т. Д. Алгоритм A * вполне способен обрабатывать функции стоимости, поэтому, если ваша реализация еще этого не делает, просто обратитесь к Google, чтобы узнать, как реализовать A * с помощью функции стоимости.
Сказав это, однако, я не думаю, что A * является особенно хорошим подходом для тактической RPG. Или, точнее, это не полная история. Вы не хотите, чтобы ваши отряды вслепую приближались к своей цели, вы хотите, чтобы они позиционировали себя, чтобы использовать укрытие, возвышенность, что угодно, при этом продвигаясь к конечной цели и стремясь обойти противников и так далее. Таким образом, тактическая ценность конечной точки каждого хода имеет огромное значение, а не только то, насколько близко она является целью. Это требует более глубокого решения проблем, чем просто поиск пути.
источник
Если вам нужны все возможные варианты движения юнита, используйте алгоритм Дейкстры .
Разница между A * и Dijkstra заключается в том, что Dijkstra предоставляет вам все возможные кратчайшие маршруты, достижимые при заданной стоимости, и, если ни один из них еще не достигает пункта назначения, он увеличивает стоимость на один и продолжается. A *, с другой стороны, предпочитает сначала рассчитывать те маршруты, которые имеют хороший шанс добраться до пункта назначения.
Поэтому, когда вы просто хотите кратчайший путь из точки А в точку Б, тогда A * - хороший выбор. Но если вам нужны все возможные варианты движения и кратчайший путь к каждому из них, то Dijkstra - именно то, что вам нужно.
Все, что вам нужно сделать, это запустить Алгоритм Дейкста без определенного узла назначения, но с максимальной стоимостью, которую нельзя превышать (диапазон движения юнита). При поездке на узел будет превышать максимальную стоимость, не посещайте его. Когда алгоритм завершается из-за отсутствия невидимых ребер, каждый узел в посещаемом наборе является возможным местом назначения, а маркеры предыдущих узлов узлов образуют связанный список, представляющий путь назад к начальному узлу.
Что касается прыжков: они могут быть представлены как еще одно ребро в A * и Dijkstra. Они могут иметь такую же стоимость, что и обход обычного ребра или другого. Вы также можете передать параметр «jump_height» в алгоритм, который указывает алгоритму игнорировать края перехода, превышающие заданную высоту.
источник
A*
на самом деле это просто обобщение Дейкстры, поэтому, если вы понимаете одно, не должно быть слишком сложно понять другое.Другие ответы содержат полезную информацию, поэтому обязательно прочитайте их.
Однако, чтобы ответить на ваш вопрос: на основе псевдокода, с которым вы связались, у вас есть какая-то функция, в
heuristic_cost_estimate
которой вы рассчитываете стоимость от tileA до tileB (при условии, что они смежны). Вместо того, чтобы использовать квартиру (1) для этой стоимости, вы должны будете настроить ее так, чтобы она включала статистику плиток и статистику юнитов и, возможно, статистику краев.Например:
Это даст вам ваш путь. Затем вы просто перемещаете юнит вдоль их пути, потребляя точки движения, и останавливаете его, когда оставшиеся точки <edgeCost. Обратите внимание, что это может быть не совсем оптимальным, если вы в конечном итоге с остаточным количеством очков = 1, но это должно быть достаточно для практической RPG. В действительности, вы бы хотели больше тактики, как указал Джек Эйдли!
Задача:
Если вы хотите стать более продвинутым, вы, вероятно, захотите использовать Djikstras, как предложено, чтобы найти все пробелы в пределах расстояния X, тогда вы хотите оценить каждый пробел в этом списке на «лучшее» место, основываясь на близости к цели, защите сила, вне зависимости от того, можете ли вы атаковать с этой позиции и т. д. На основании этой информации вы бы выбрали плитку, а затем переместились туда по пути, который вы только что рассчитали с помощью Djikstras.
источник
Восхождение и пропуски довольно тривиальны, так как они только изменяют стоимость. Поиск пути (и большая часть тактического ИИ) сводится к суммированию затрат на все посещаемые узлы и минимизации этого. Непроходимая скала будет стоить бесконечно (очень, очень дорого), склоны будут стоить дороже, чем обычно, и т. Д.
Это, однако, находит глобально оптимальный путь, который не лучшее решение, потому что реальные противники обычно не находят оптимальный путь. Это крайне нереально, иногда до такой степени, которая очевидна для игрока, и раздражает (особенно, когда ИИ как таковой в основном непобедим, потому что он тоже выбирает оптимальный).
Хорошие симуляции сознательно не находят лучшего пути. Гораздо лучшим алгоритмом может быть иерархическое нахождение пути - если ничто иное, путем рисования прямой линии на карте и выбора 4-5 путевых точек, затем нахождение пути от одной путевой точки к другой с учетом только тех весов узлов, которые находятся на данный момент. известный, и установка всех остальных весов узлов равнодушными. Кроме того, вы можете сначала запустить A * на более грубой сетке, а затем найти путь от одного большого узла к следующему (но я предполагаю, что рисование линии на карте тоже очень хорошо).
Это гораздо более реалистично (а также потребляет часть вычислительной мощности, потому что график намного меньше). Да, это может означать, что отряд движется к утесу только для того, чтобы узнать, что он не может пройти. Это нормально, это случается и с настоящими противниками. В следующий раз это больше не повторится (потому что теперь известны бесконечные затраты).
источник