getNode($startX, $startY); $endNode = $grid->getNode($endX, $endY); if ($startNode === null || $endNode === null) { return new Path($grid); } $startNode->setG(0.0); $startNode->setF(0.0); $startNode->setOpened(true); $openList = new Heap(function($node1, $node2) { return $node1->getF() - $node2->getF(); }); $openList->push($startNode); $node = null; while (!$openList->isEmpty()) { $node = $openList->pop(); $node->setClosed(true); if ($node->isEqual($endNode)) { break; } $neighbors = $grid->getNeighbors($node, $movement); $neighborsLength = \count($neighbors); for ($i = 0; $i < $neighborsLength; ++$i) { $neighbor = $neighbors[$i]; if ($neighbor->isClosed()) { continue; } $ng = $node->getG() + (($neighbor->getX() - $node->getX() === 0 || $neighbor->getY() - $node->getY() === 0) ? 1 : \sqrt(2)); if (!$neighbor->isOpened() || $ng < $neighbor->getG()) { $neighbor->setG($ng); $neighbor->setH($neighbor->getG() ?? $neighbor->getWeight() * Heuristic::heuristic($neighbor->getCoordinates(), $endNode->getCoordinates(), $heuristic)); $neighbor->setF($neighbor->getG() + $neighbor->getH()); $neighbor->setParent($node); if (!$neighbor->isOpened()) { $openList->push($neighbor); $neighbor->setOpened(true); } else { $openList->update($neighbor); } } } } $path = new Path($grid); while ($node !== null) { $path->addNode($node); $node = $node->getParent(); } return $path; } }