| 
<?php
 class PathFinder{
 
 var $map=array();
 var $origX=0;
 var $origY=0;
 var $destX=0;
 var $destY=0;
 var $path=array();
 var $weights=array();
 var $walked=array();
 var $steps=0;
 var $mapSquares=0;
 var $mapWidth=0;
 var $found=0;
 var $failSafe=0;
 var $diagonal=1;
 var $impassable=100.0;
 
 function __construct(){
 }
 
 function __destruct(){
 
 }
 
 function noDiagonalMovement(){
 $this->diagonal=0;
 }
 
 function setImpassable($impassable){
 $this->impassable=$impassable;
 }
 
 public function setMap($map){
 $this->map=$map;
 $this->mapSquares=count($this->map);
 $this->mapWidth=sqrt($this->mapSquares);
 }
 
 public function setOrigin($origX,$origY){
 $this->origX=$origX;
 $this->origY=$origY;
 
 }
 
 public function setDestination($destX,$destY){
 $this->destX=$destX;
 $this->destY=$destY;
 }
 
 public function returnPath(){
 $this->path=array();
 $this->weights=array();
 $this->walked=array();
 $this->steps=0;
 $this->found=0;
 $this->failsafe=0;
 if($this->origX!=0 && $this->origY!=0 && $this->destX!=0 && $this->destY!=0 && !empty($this->map)){
 $this->findPath($this->origX,$this->origY);
 return $this->path;
 } else {
 echo 'Insufficient data, please define origin and destination points and a map';
 die();
 }
 }
 
 public function returnWeights(){
 $return=array();
 if(!empty($this->weights)){
 $return=$this->weights;
 }
 return $return;
 }
 
 private function findPath($curX,$curY){
 $this->failSafe++;
 if($this->failSafe>=100){
 return false;
 }
 $lowestEstimatedCost=0;
 $shortestX=0;
 $shortestY=0;
 for($x=-1;$x<=1;$x++){
 if($this->found==0){
 for($y=-1;$y<=1;$y++){
 if($this->found==0){
 $checkX=$x+$curX;
 $checkY=$y+$curY;
 if($checkX>=1 && $checkY>=1 && $checkX<=$this->mapWidth && $checkY<=$this->mapWidth){
 if($checkX==$curX && $checkY==$curY){
 //not needed
 } else if($checkX==$this->destX && $checkY==$this->destY){
 if($this->diagonal==1 || !(($x==-1 && $y==-1) || ($x==-1 && $y==1) || ($x==1 && $y==-1) || ($x==1 && $y==1))){
 $this->found=1;
 $this->steps++;
 $this->path[]=$this->destX.'x'.$this->destY;
 $this->origX=$this->destX;
 $this->origY=$this->destY;
 $this->weights[]=(($x==-1 && $y==-1) || ($x==-1 && $y==1) || ($x==1 && $y==-1) || ($x==1 && $y==1))?$this->map[$checkX.'x'.$checkY]['weight']*1.4:$this->map[$checkX.'x'.$checkY]['weight'];
 }
 } else {
 if(!in_array($checkX.'x'.$checkY,$this->walked)){
 $weight=$this->map[$checkX.'x'.$checkY]['weight'];
 if($this->diagonal==1 || !(($x==-1 && $y==-1) || ($x==-1 && $y==1) || ($x==1 && $y==-1) || ($x==1 && $y==1)) && $weight<$this->impassable){
 $weight=(($x==-1 && $y==-1) || ($x==-1 && $y==1) || ($x==1 && $y==-1) || ($x==1 && $y==1))?$weight*1.4:$weight;
 $estimatedCost=$this->estimatedCost($checkX,$checkY,$weight);
 if($estimatedCost<$lowestEstimatedCost || $lowestEstimatedCost==0){
 $lowestEstimatedCost=$estimatedCost;
 $shortestX=$checkX;
 $shortestY=$checkY;
 $goodweight=$weight;
 }
 }
 }
 }
 }
 }
 }
 }
 }
 if($this->found!=1){
 if($shortestX==0 && $shortestY==0){
 $this->walked=array();
 $this->walked[]=$curX.'x'.$curY;
 $this->findPath($curX,$curY,$this->destX,$this->destY);
 } else {
 $this->steps++;
 $this->walked[]=$shortestX.'x'.$shortestY;
 $this->path[]=$shortestX.'x'.$shortestY;
 $this->origX=$shortestX;
 $this->origY=$shortestY;
 $this->weights[]=$goodweight;
 $this->findPath($shortestX,$shortestY,$this->destX,$this->destY);
 }
 }
 }
 private function estimatedCost($curX,$curY,$weight){
 $dx=$this->destX-$curX;
 $dy=$this->destY-$curY;
 $value=sqrt(($dx*$dx)+($dy*$dy));
 return $value*$weight;
 }
 
 }
 
 ?>
 |