Теперь, поправьте меня, если я ошибаюсь, но это похоже похоже на то, что, глядя на ваш другой код, вы хотите, чтобы операторы if в цикле for, который перебирает соседей текущего узла, выглядели какэто:
if (!closedset.Contains(neighbor)) continue;
if (map.Cells[neighbor.X, neighbor.Y].Walkable) continue;
Не так:
if (closedset.Contains(neighbor)) continue;
if (!map.Cells[neighbor.X, neighbor.Y].Walkable) continue;
Ваш исходный код оценивает соседа только в том случае, если он находится в закрытом списке, и он не доступен для прохождения, что я не думаю, что вы хотите,Обновленный код оценивает соседний узел только в том случае, если он не находится в замкнутом наборе и доступен для прохождения.
Для дальнейшего понимания алгоритма A * и подробного описания его работы, проверьте thisссылка .
РЕДАКТИРОВАТЬ: Вы сказали, что ваш код предоставил неточный путь, то есть путь, который не ведет весь путь до целевого квадрата.Если посмотреть на вашу ReconstructPathRecursive()
функцию, кажется, что вы совершили решающую ошибку.Поскольку ваш список содержит родительский элемент каждого пройденного узла, вы получите все, кроме целевого квадрата, потому что он не является родительским для всего.Целевой квадрат должен быть первым квадратом, добавленным в ваш список, прежде чем вы начнете работать в обратном направлении, восстанавливая путь от родителя текущего узла (который является целевым квадратом).
Чтобы исправить это поведение, я бы предложилКогда вы обнаружите, что текущий узел равен целевому узлу, вы сначала добавляете целевой узел в свой список путей, а после этого вызываете функцию ReconstructPathRecursive()
, чтобы получить окончательный список.