PHP Classes

File: class.pathfinder.php

Recommend this page to a friend!
  Classes of Kristo Vaher   Path finder   class.pathfinder.php   Download  
File: class.pathfinder.php
Role: Class source
Content type: text/plain
Description: pathfinder class
Class: Path finder
Find the shortest path in a map
Author: By
Last change: Added option to track weights on paths as well as the ability to continue from previously left-off path (if path calculation has to have certain pre-determined checkpoints).
Date: 13 years ago
Size: 3,889 bytes
 

Contents

Class file image Download
<?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;
    }

}

?>