Python Libtcod: как выполнить поиск пути с переменной стоимостью перемещения?

Я создаю пошаговую стратегическую игру, используя Libtcod и Python. Игровая карта имеет переменный рельеф и каждый тайл может быть 1 из 5 типов:

  • Равнины - Перемещение стоит 1
  • Лес - Стоимость 2
  • Река - стоит 4
  • Холм - стоит 3
  • Гора - Непроходимая

Каждый тип имеет свою стоимость передвижения, так что для перемещения по равнине требуется меньше «очков движения», чем, например, по лесу. Я хочу отобразить все квадраты, на которые может двигаться юнит, учитывая его диапазон движения / начальные точки движения.

Libtcod имеет функцию поиска пути, встроенную как для A *, так и для Dijtskra, и отобразить все квадраты в заданном диапазоне тривиально, без учета рельефа местности.

Однако я не могу понять, как я могу реализовать стоимость местности, не написав свой собственный алгоритм поиска пути. Глядя на документы, я знаю, что это как-то связано с:

def path_func(xFrom,yFrom,xTo,yTo,userData) : ... path_new_using_function(width, height, path_func, user_data=0, diagonalCost=1.41) dijkstra_new_using_function(width, height, path_func, user_data=0, diagonalCost=1.41)

но я не могу понять, что должна делать пользовательская функция. Согласно документам, он должен

...возвратить стоимость прогулки из координат xFrom,yFrom в координаты xTo,yTo. Стоимость должна быть > 0.0f, если по ячейке xTo,yTo можно пройти. Он должен быть равен 0.0f, если это не так.

но разве не в этом суть алгоритма Дейцкры? То есть алгоритм должен учитывать переменную стоимость каждой плитки, а затем соответственно строить путь.

На самой карте уже есть ландшафт и затраты на перемещение, мне просто нужен способ связать эти данные с поиском пути.


person Dider    schedule 23.05.2015    source источник


Ответы (2)


Я сделал свою собственную реализацию алгоритма A* для создания эстетической дорожки ходьбы; которые включали мосты, которые были размещены только тогда, когда они могли, в соответствии с A *, с учетом дополнительного количества шагов:

https://github.com/lillian-lemmer/sshrpg/blob/master/plotbrush/mapgen.py#L622

Как вы можете видеть, все, что вам нужно сделать, это манипулировать алгоритмом A *, чтобы увеличить предварительную оценку (стоимость от начала) для определенных типов / атрибутов тайлов / точек на карте.

Если вы посмотрите на строку 660, я увеличу tentative_g_score (стоимость от начала) на восемь для воды, так что это все равно, что сказать «постройте мост только в том случае, если альтернативой будет пройти 8~ шагов, чтобы обойти его». Включение данных плитки в ваш алгоритм A*, а не только декартовых координат, — отличный способ внести коррективы в алгоритм на основе атрибутов карты.

person Lillian Seabreeze    schedule 23.05.2015
comment
Это здорово, но вы говорите, что нет другого пути, кроме как построить свой собственный алгоритм? Я в первую очередь спрашиваю, могу ли я использовать предоставленные функции libtcod для этого (и если да, то как) - person Dider; 23.05.2015
comment
Сейчас вам нужно ввести 70 строк, но это даст вам большую гибкость в будущем. - person Lillian Seabreeze; 23.05.2015
comment
Я проверил документацию и исходный код функций поиска пути libtcod, и они по умолчанию не обрабатывают значения переменной стоимости для ландшафта. Так что это должно быть то, что вам нужно. Если вы хотите хорошо интегрировать его, вы можете включить его в качестве обратного вызова для поиска пути и следовать инструкциям здесь: doryen.eptalys.net/data/libtcod/doc/1.5.1/html2/ - person Lillian Seabreeze; 23.05.2015

Насколько я понимаю, то, чего вы хотите достичь, вполне возможно с помощью встроенной в tcod функции поиска пути.

path_new_using_function вызовет ваш path_func с соседними ячейками, поэтому вы можете просто вернуть значения, указанные выше, в зависимости от местности ниже (xFrom, yFrom) и/или (xTo, yTo).

person Iziminza    schedule 04.03.2019