Кто-нибудь пробовал внедрять JPS в Astar? не совсем понимаю логику, опишу пожалуй, как это понял, ознакомившись с теорией и на практике:
Создаем стартовый нод, присваиваем ему координаты начала и конца, кидаем его в открытый список.
Пока количество в открытом списке больше нуля, добавляем данный нод в закрытый список, поп в открытом, далее вызов функции индетификации соседей
в данной функции первым делом ищем соседей (без диагоналей), следующим образом
public List<PathFinderNode> findNeighbors(PathFinderNode node)
{
List<PathFinderNode> neighbors = new List<PathFinderNode>();
// directed pruning: can ignore most neighbors, unless forced.
int x = node.X;
int y = node.Y;
// get normalized direction of travel
int dx = (x - node.PX) / Math.Max(Math.Abs(x - node.PX), 1);
int dy = (y - node.PY) / Math.Max(Math.Abs(y - node.PY), 1);
// search horizontally/vertically
if (dx != 0)
{
if (walkable(x + dx, y))
neighbors.Add(new PathFinderNode(x + dx, y, x, y));
if (walkable(x, y + 1))
neighbors.Add(new PathFinderNode(x, y + 1, x, y));
if (walkable(x, y - 1))
neighbors.Add(new PathFinderNode(x, y - 1, x, y));
}
else if (dy != 0)
{
if (walkable(x, y + dy))
neighbors.Add(new PathFinderNode(x, y + dy, x, y));
if (walkable(x + 1, y))
neighbors.Add(new PathFinderNode(x + 1, y, x, y));
if (walkable(x - 1, y))
neighbors.Add(new PathFinderNode(x - 1, y, x, y));
}
else if (dx == 0 && dy == 0)
{
neighbors = getNeighborsOf(node);
}
return neighbors;
}
public List<PathFinderNode> getNeighborsOf(PathFinderNode node)
{
int x = node.X;
int y = node.Y;
List<PathFinderNode> neighbors = new List<PathFinderNode>();
bool n = false, s = false, e = false, w = false, ne = false, nw = false, se = false, sw = false;
// ?
if (walkable(x, y - 1))
{
neighbors.Add(new PathFinderNode(x, y - 1, x, y));
n = true;
}
// ?
if (walkable(x + 1, y))
{
neighbors.Add(new PathFinderNode(x + 1, y, x, y));
e = true;
}
// ?
if (walkable(x, y + 1))
{
neighbors.Add(new PathFinderNode(x, y + 1, x, y));
s = true;
}
// ?
if (walkable(x - 1, y))
{
neighbors.Add(new PathFinderNode(x - 1, y, x, y));
w = true;
}
return neighbors;
}
То есть мы сначала проходимся по соседу, если их не находим, идем по вертикали/горизонтали - в общем с этим гуд, соседей получается найти
Сам класс PathFinderNode состоит из текущей координаты и родительской ((X,Y);(PX,PY)), от нее и идут все расчеты dx и dy
А тут начинаются уже проблемы. Я начинаю перебирать список найденных соседей (коих 4, так как по диагоналям не хожу), и запускаю функцию прыжка
private PathFinderNode jump(PathFinderNode neighbor, PathFinderNode current, List goals) { if (neighbor.X == -1 || !walkable(neighbor.X, neighbor.Y)) { return null; } if (goals.Contains(neighbor)) return neighbor;
int dx = neighbor.X - current.X;
int dy = neighbor.Y - current.Y;
// check for forced neighbors
// check horizontally/vertically
if (dx != 0)
{
if ((walkable(neighbor.X, neighbor.Y + 1) && !walkable(neighbor.X - dx, neighbor.Y + 1)) ||
(walkable(neighbor.X, neighbor.Y - 1) && !walkable(neighbor.X - dx, neighbor.Y - 1)))
{
return neighbor;
}
}
else if (dy != 0)
{
if ((walkable(neighbor.X + 1, neighbor.Y) && !walkable(neighbor.X + 1, neighbor.Y - dy)) ||
(walkable(neighbor.X - 1, neighbor.Y) && !walkable(neighbor.X - 1, neighbor.Y - dy)))
{
return neighbor;
}
// when moving vertically check for horizontal jump points
PathFinderNode TestNeigbour1 = new PathFinderNode(neighbor.X + 1, neighbor.Y, neighbor.X,neighbor.Y);
PathFinderNode TestNeigbour2 = new PathFinderNode(neighbor.X - 1, neighbor.Y, neighbor.X, neighbor.Y);
if (jump(TestNeigbour1, neighbor, goals) != null ||jump(TestNeigbour2, neighbor,goals) != null)
{
return neighbor;
}
}
else
{
return null; //null
}
return jump(new PathFinderNode(neighbor.X + dx, neighbor.Y + dy, neighbor.PX, neighbor.PY), neighbor, goals);
}
По идее, какие-то объекты могут быть пустыми, но этот алгоритм прыгает до края сетки и скидывает всегда null (сетка - двумерный массив со 0 и 1 значением). Не могу понять, что упускаю. Буду благодарен, если поможете ответить. P.S. Сырцы на джаве тут (отсюда и прыгал) https://github.com/kevinsheehan/jps/tree/master/src/org/ksdev/jps
Сборка персонального компьютера от Artline: умный выбор для современных пользователей