Php 行走十六进制地图时识别和处理两条有效路径
我正在编写一个用于六边形贴图的成本路径脚本。目前我正处于“学会走路”的发展阶段 一般来说,代码是有效的。我可以可靠地从A到B。但是,请考虑下面的地图: 序列Php 行走十六进制地图时识别和处理两条有效路径,php,map,hexagonal-tiles,Php,Map,Hexagonal Tiles,我正在编写一个用于六边形贴图的成本路径脚本。目前我正处于“学会走路”的发展阶段 一般来说,代码是有效的。我可以可靠地从A到B。但是,请考虑下面的地图: 序列0406->0405->0505和0406->0506->0505均有效。我想遍历并输出这两条路径 我的代码如下: public function walkMap($origCol, $origRow, $destCol, $destRow) { $curRow = $origRow; $curCol = $origCol;
0406->0405->0505
和0406->0506->0505
均有效。我想遍历并输出这两条路径
我的代码如下:
public function walkMap($origCol, $origRow, $destCol, $destRow) {
$curRow = $origRow;
$curCol = $origCol;
while (($curRow != $destRow) || ($curCol != $destCol)) {
$newRow = self::getNextMove($curRow,$destRow);
if ($newRow == $curRow) {
$curCol = self::getNextMove($curCol,$destCol);
} else {
$curRow = $newRow;
}
}
}
private function getNextMove($cur,$dest) {
if ($cur < $dest) {
++$cur;
} else if ($cur > $dest) {
--$cur;
}
return $cur;
}
public function walkMap($origCol、$origRow、$destCol、$destRow){
$curRow=$origRow;
$curCol=$origCol;
而($curRow!=$destRow)| |($curCol!=$destCol)){
$newRow=self::getNextMove($curRow,$destRow);
如果($newRow==$curRow){
$curCol=self::getNextMove($curCol,$destCol);
}否则{
$curRow=$newRow;
}
}
}
私有函数getNextMove($cur,$dest){
如果($cur<$dest){
++$cur;
}否则如果($cur>$dest){
--$cur;
}
返回$cur;
}
我想要的结果是一个数值数组step=>hexCoord
,显示所采用的路径。但我不确定如何采用上面的工作代码来智能地进行分支,并且在这样做之后,如何最好地形成输出数据结构
提前感谢。我使用了两个类:一个是有列和行号的六边形隔间,另一个是有顺序的隔间列表路径。隔间有一个功能分支,用于获取通往目的地的路径上“正确方向”的所有隔间。只需一步就能从隔间直接到达 然后,我从长度为1的路径开始(仅开始),并通过所有分支稳定地扩展该路径,为每个分支生成一条路径,比旧分支长1。如果它不能再扩展,我们在$dest,可以输出这个路径 希望能有帮助。调试花了一些时间。让我知道,如果它不适用于任何情况
<?php
class Cubicle
{
public $col;
public $row;
public function branch(Cubicle $dest)
{
$result = array();
// move up
if ($this->row > $dest->row)
$result[] = new Cubicle($this->col, $this->row - 1);
// move down
elseif ($this->row < $dest->row)
$result[] = new Cubicle($this->col, $this->row + 1);
// move right
if ($this->col < $dest->col)
{
// right-up
if ($this->row >= $dest->row)
$result[] = new Cubicle($this->col + 1, $this->row);
// right-down
else
$result[] = new Cubicle($this->col + 1, $this->row - 1);
}
// move left
elseif ($this->col > $dest->col)
{
// left-up
if ($this->row > $dest->row)
$result[] = new Cubicle($this->col - 1, $this->row - 1);
// left-down
else
$result[] = new Cubicle($this->col - 1, $this->row);
}
return $result;
}
public function __construct($col, $row)
{
$this->col = $col;
$this->row = $row;
}
}
class Path
{
public $cubicles = array();
public function __construct(Cubicle $start)
{
$this->cubicles[] = $start;
}
public function getLast()
{
return $this->cubicles[count($this->cubicles)-1];
}
public function append($nextCubicle)
{
$clone = clone $this;
$clone->cubicles[] = $nextCubicle;
return $clone;
}
}
function walk(Cubicle $start, Cubicle $dest) {
$process = array(new Path($start));
$output = array();
while(count($process) > 0)
{
$currentPath = array_pop($process);
$branches = $currentPath->getLast()->branch($dest);
if (count($branches) == 0)
$output[] = $currentPath;
foreach ($branches as $branch)
$process[] = $currentPath->append($branch);
}
return $output;
}
$start = new Cubicle(4, 6);
$dest = new Cubicle(5, 5);
$paths = walk($start, $dest);
var_dump($paths);
?>
这是一种非常低效的方法,因为如果有重叠的路径,算法将为每个路径重新计算这些路径的一部分。如果您想要一个性能良好的算法,您将需要创建某种图形,它只包含有效路径,并且深度优先搜索它以输出所有可能的路径 我使用了两类:一类是有列和行号的六边形隔间,另一类是有顺序的隔间列表路径。隔间有一个功能分支,用于获取通往目的地的路径上“正确方向”的所有隔间。只需一步就能从隔间直接到达 然后,我从长度为1的路径开始(仅开始),并通过所有分支稳定地扩展该路径,为每个分支生成一条路径,比旧分支长1。如果它不能再扩展,我们在$dest,可以输出这个路径 希望能有帮助。调试花了一些时间。让我知道,如果它不适用于任何情况
<?php
class Cubicle
{
public $col;
public $row;
public function branch(Cubicle $dest)
{
$result = array();
// move up
if ($this->row > $dest->row)
$result[] = new Cubicle($this->col, $this->row - 1);
// move down
elseif ($this->row < $dest->row)
$result[] = new Cubicle($this->col, $this->row + 1);
// move right
if ($this->col < $dest->col)
{
// right-up
if ($this->row >= $dest->row)
$result[] = new Cubicle($this->col + 1, $this->row);
// right-down
else
$result[] = new Cubicle($this->col + 1, $this->row - 1);
}
// move left
elseif ($this->col > $dest->col)
{
// left-up
if ($this->row > $dest->row)
$result[] = new Cubicle($this->col - 1, $this->row - 1);
// left-down
else
$result[] = new Cubicle($this->col - 1, $this->row);
}
return $result;
}
public function __construct($col, $row)
{
$this->col = $col;
$this->row = $row;
}
}
class Path
{
public $cubicles = array();
public function __construct(Cubicle $start)
{
$this->cubicles[] = $start;
}
public function getLast()
{
return $this->cubicles[count($this->cubicles)-1];
}
public function append($nextCubicle)
{
$clone = clone $this;
$clone->cubicles[] = $nextCubicle;
return $clone;
}
}
function walk(Cubicle $start, Cubicle $dest) {
$process = array(new Path($start));
$output = array();
while(count($process) > 0)
{
$currentPath = array_pop($process);
$branches = $currentPath->getLast()->branch($dest);
if (count($branches) == 0)
$output[] = $currentPath;
foreach ($branches as $branch)
$process[] = $currentPath->append($branch);
}
return $output;
}
$start = new Cubicle(4, 6);
$dest = new Cubicle(5, 5);
$paths = walk($start, $dest);
var_dump($paths);
?>
这是一种非常低效的方法,因为如果有重叠的路径,算法将为每个路径重新计算这些路径的一部分。如果您想要一个性能良好的算法,您将需要创建某种图形,它只包含有效路径,并且深度优先搜索它以输出所有可能的路径 我注意到,目前,您的路径选择只是“到达正确的行,然后到达正确的列”。我意识到您仍在起步,但您可能希望提前考虑如何将成本计算到路径中,并让它告诉您的数据结构
例如,您可以使用标记地图上从该点到给定目的地的每个点,以最小的成本标记该点。然后,找到一条路径就是选择一个原点,并以最小的代价重复移动到相邻的十六进制,在移动过程中构建所需的路径数组。如果在任何一点上有两条最优路径,您将看到它是一个十六进制,有两个最便宜的邻居——您将为每个路径数组创建一个新副本,并独立完成它们。采用这种方法,您将使用(并返回)一个路径数组数组。我注意到,目前,您的路径选择只是“到达正确的行,然后到达正确的列”。我意识到您仍在开始,但是,您可能希望提前考虑如何将成本分摊到路径中,并让它告诉您有关数据结构的信息
例如,您可以使用标记地图上从该点到给定目的地的每个点,以最小的成本标记该点。然后,找到一条路径就是选择一个原点,并以最小的代价重复移动到相邻的十六进制,在移动过程中构建所需的路径数组。如果在任何一点上有两条最优路径,您将看到它是一个十六进制,有两个最便宜的邻居——您将为每个路径数组创建一个新副本,并独立完成它们。采用这种方法,您将使用(并返回)一个路径数组数组。路径
0406->0507->0506->0505
是否因为比其他路径长而无效?你只想搜索最短路径吗?@Basti-是的,总是最短路径。路径0406->0507->0506->0505
是否因为比其他路径长而无效?你只想搜索最短路径吗?@Basti-是的,总是最短路径。