Zend - The PHP Company




Games

Add Code


Find the shortest path out of a maze  

Type: code fragment
Added by: codewalkers
Entered: 19/05/2002
Last modified: 05/12/2002
Rating: - (fewer than 3 votes)
Views: 8871
This is the winner of the Codewalkers.com coding contest. The challenge was the find the shortest path out of a maze in the shortest time. This code makes use of the GD library to present the path out of the maze.


<?php
/****************************************************************************
*****                                                                   *****
*****                             MAZE CONTEST                          *****
*****                        NAME: SCOTT A SOLOMKO                      *****
*****                                                                   *****
*****                                                                   *****
****************************************************************************/

function InitialLoad(){
echo 
"
<html>
<head>
  <title>Scott Solomko :: Maze Contest</title>
</head>
<body bgcolor="
#ffffff">
<center>
<
form method=post action="contestwinner.php?action=2" enctype="multipart/form-data">
<
input type=hidden name="MAX_FILE_SIZE" value="8192">
<
table width=75cellpadding=0 cellspacing=0 border=1>
  <
tr>
    <
td align=right>Upload file containing maze:</td>
    <
td><input type="file" size=20 name="iFile"></td>
  </
tr>
  <
tr>
    <
td align=right>Select the type of output:</td>
    <
td>
      <
input type=radio value=1 name=output>PNG File
      
<input type=radio value=2 name=output>HTML Table
      
<input type=radio value=3 name=output>Text File
    
</td>
  </
tr>
  <
tr>
    <
td align=center colspan=2><input type=submit></td>
  </
tr>
</
table>
</
form>
</
center>
</
body>
</
html>";
}

function FindRoute(
$iFile$output){

  
$row      = 0;
  
$col      = 0;
  
$c_count  = 1;
  
$fp       = fopen($iFile, "r");

  // fill the 2d array

  while (!feof(
$fp)){
    
$ch = fgetc($fp);
    if (!feof(
$fp)){
      if (
$ch == "W"){
        
$maze[$row][$col] = $ch;
        
$col++;
      } else if (
$ch == " "){
        
$maze[$row][$col] = -1;
        
$col++;
      } else if (
$ch == "n"){
        
$row++;
        
$col = 0;
      } else if (
$ch == "S" || $ch == "E"){
        
$maze[$row][$col] = $ch;
        if (
$ch == "S"){
          
$s_row = $row;
          
$s_col = $col;
        } else {
          
$e_row = $row;
          
$e_col = $col;
        }
        
$col++;
      }
    }
  }
  fclose(
$fp);

  // define boundries
  
$b_right  = sizeof($maze[0]);
  
$b_bottom = sizeof($maze);

  // start algorithm from 'E'. this will mark only one 'space' and record
  // its coordinates, which 'space' is determined by which side 'E' is
  // located. No need to check for 'E' in a corner.

  if (
$e_col == sizeof($maze[0]) - 1){
    
$maze[$e_row][$e_col - 1] = $c_count;
    
$c_count++;
    
$tmp_row = array($e_row);
    
$tmp_col = array($e_col - 1);
  } else if (
$e_col == 0){
    
$maze[$e_row][$e_col + 1] = $c_count;
    
$c_count++;
    
$tmp_row = array($e_row);
    
$tmp_col = array($e_col + 1);
  } else if (
$e_row == sizeof($maze) - 1){
    
$maze[$e_row - 1][$e_col] = $c_count;
    
$c_count++;
    
$tmp_row = array($e_row - 1);
    
$tmp_col = array($e_col);
  } else {
    
$maze[$e_row + 1][$e_col] = $c_count;
    
$c_count++;
    
$tmp_row = array($e_row + 1);
    
$tmp_col = array($e_col);
  }

  // goto the coordinate(s) that have been marked and mark its adjacent
  // 'spaces' if applicable (check for -1).

  while (sizeof(
$tmp_row) != 0){
    
$orig_size = sizeof($tmp_row);
    for (
$i = 0; $i < $orig_size$i++){
      // ckeck up
      if (
$tmp_row[0] - 1 > 0){
        if (
$maze[$tmp_row[0] - 1][$tmp_col[0]] == -1){
          
$maze[$tmp_row[0] - 1][$tmp_col[0]] = $c_count;
          array_push(
$tmp_row$tmp_row[0] - 1);
          array_push(
$tmp_col$tmp_col[0]);
        } else if (
$maze[$tmp_row[0] - 1][$tmp_col[0]] == "S"){
          break 2;
        }
      }
      // check down
      if (
$tmp_row[0] + 1 < $b_bottom - 1){
        if (
$maze[$tmp_row[0] + 1][$tmp_col[0]] == -1){
          
$maze[$tmp_row[0] + 1][$tmp_col[0]] = $c_count;
          array_push(
$tmp_row$tmp_row[0] + 1);
          array_push(
$tmp_col$tmp_col[0]);
        } else if (
$maze[$tmp_row[0] + 1][$tmp_col[0]] == "S"){
          break 2;
        }
      }
      // check left
      if (
$tmp_col[0] - 1 > 0){
        if (
$maze[$tmp_row[0]][$tmp_col[0] - 1] == -1){
          
$maze[$tmp_row[0]][$tmp_col[0] - 1] = $c_count;
          array_push(
$tmp_row$tmp_row[0]);
          array_push(
$tmp_col$tmp_col[0] - 1);
        } else if (
$maze[$tmp_row[0]][$tmp_col[0] - 1] == "S"){
          break 2;
        }
      }
      // check right
      if (
$tmp_col[0] + 1 < $b_right - 1){
        if (
$maze[$tmp_row[0]][$tmp_col[0] + 1] == -1){
          
$maze[$tmp_row[0]][$tmp_col[0] + 1] = $c_count;
          array_push(
$tmp_row$tmp_row[0]);
          array_push(
$tmp_col$tmp_col[0] + 1);
        } else if (
$maze[$tmp_row[0]][$tmp_col[0] + 1] == "S"){
          break 2;
        }
      }
      array_shift(
$tmp_row);
      array_shift(
$tmp_col);
    }
    
$c_count++;
  }

  echo "
<html>
        <
head>
          <
title>Scott Solomko :: Maze Contest</title>
        </
head>
        <
body bgcolor="#ffffff">
        
The shortest path possible is ".$c_count." steps including 'E'.<p>n";

  // map out shortest path with 'P'

  if (
$maze[$s_row - 1][$s_col] == $c_count - 1){
    
$maze[$s_row - 1][$s_col] = "P";
    
$t_row = $s_row - 1;
    
$t_col = $s_col;
    
$c_count--;
  } else if (
$maze[$s_row + 1][$s_col] == $c_count - 1){
    
$maze[$s_row + 1][$s_col] = "P";
    
$t_row = $s_row + 1;
    
$t_col = $s_col;
    
$c_count--;
  } else if (
$maze[$s_row][$s_col - 1] == $c_count - 1){
    
$maze[$s_row][$s_col - 1] = "P";
    
$t_row = $s_row;
    
$t_col = $s_col - 1;
    
$c_count--;
  } else {
    
$maze[$s_row][$s_col + 1] = "P";
    
$t_row = $s_row;
    
$t_col = $s_col + 1;
    
$c_count--;
  }

  for (
$i = 1; $i < $c_count$i++){
    if (
$maze[$t_row - 1][$t_col] == $c_count - $i){
      
$t_row--;
      
$maze[$t_row][$t_col] = "P";
    } else if (
$maze[$t_row + 1][$t_col] == $c_count - $i){
      
$t_row++;
      
$maze[$t_row][$t_col] = "P";
    } else if (
$maze[$t_row][$t_col - 1] == $c_count - $i){
      
$t_col--;
      
$maze[$t_row][$t_col] = "P";
    } else {
      
$t_col++;
      
$maze[$t_row][$t_col] = "P";
    }
  }

  // prep 2d array for output, clear all remaining numbers

  for (
$i = 0; $i < $b_bottom$i++){
    for(
$j = 0; $j < $b_right$j++){
      if (
$maze[$i][$j] != "W" && $maze[$i][$j] != "P" && $maze[$i][$j] != "S" && $maze[$i][$j] != "E"){
        
$maze[$i][$j] = " ";
      }
    }
  }

  // call appropriate output function

  switch(
$output){
    case 1:
      OutputPNG(
$maze$b_bottom$b_right);
      break;
    case 2:
      OutputHTML(
$maze$b_bottom$b_right);
      break;
    case 3:
      OutputTXT(
$maze$b_bottom$b_right);
      break;
  }

}

function OutputPNG(&
$maze, &$b_bottom, &$b_right){

  
$width  = $b_right * 10;
  
$height = $b_bottom * 10;

  
$img    = imagecreate($width + 10, $height + 10);
  
$bg     = imagecolorallocate($img, 0xFF, 0xFF, 0xFF);
  
$border = imagecolorallocate($img, 0x00, 0x00, 0x00);
  
$wall   = imagecolorallocate($img, 0xB2, 0x22, 0x22);
  
$path   = imagecolorallocate($img, 0x00, 0x00, 0x99);

  imagerectangle(
$img, 0, 0, $width$height$border);

  for(
$i = 10; $i <= $width$i += 10){
    imageline(
$img$i, 0, $i$height$border);
  }

  for(
$i = 0; $i <= $height$i += 10){
    imageline(
$img, 0, $i$width$i$border);
  }

  for(
$i = 0; $i < $b_bottom$i++){
    for(
$j = 0; $j < $b_right$j++){
      if (
$maze[$i][$j] == "W"){
        imagefilltoborder(
$img$j * 10 + 5, $i * 10 + 5, $border$wall);
      } else if (
$maze[$i][$j] == "P" || $maze[$i][$j] == "S" || $maze[$i][$j] == "E"){
        imagefilltoborder(
$img$j * 10 + 5, $i * 10 + 5, $border$path);
      }
    }
  }

  imagepng(
$img, "scottsolomko.png");
  imagedestroy(
$img);

  echo "
<img src="scottsolomko.png" border=0></body></html>";
}

function OutputHTML(&
$maze, &$b_bottom, &$b_right){
echo "
<table width=50cellpadding=0 cellspacing=0 border=1>";
  for (
$i = 0; $i < $b_bottom$i++){
    echo "
<tr>";
    for(
$j = 0; $j < $b_right$j++){
      if (
$maze[$i][$j] == "W"){
        echo "
<td bgcolor="#b22222"><font color="#b22222">W</font></td>";
      } else if (
$maze[$i][$j] == " "){
        echo "
<td bgcolor="#ffffff">&nbsp;</td>";
      } else {
        echo "
<td bgcolor="#000099">&nbsp;</td>";
      }
    }
    echo "
</tr>n";
  }
echo "
</table></body></html>";

}

function OutputTXT(&
$maze, &$b_bottom, &$b_right){
  
$fp = fopen("scottsolomko.txt", "w");
  for (
$i = 0; $i < $b_bottom$i++){
    for(
$j = 0; $j < $b_right$j++){
      fputs(
$fp$maze[$i][$j]);
    }
    fputs(
$fp, "n");
  }
  fclose(
$fp);

  echo "
To view the text file that was created click <a href="scottsolomko.txt">here</a></body></html>.";
}

if (empty(
$HTTP_GET_VARS["action"])){
  
$action = 1;
} else {
  
$action = $HTTP_GET_VARS["action"];
}

switch(
$action){
  case 1:
    InitialLoad();
    break;
  case 2:
    FindRoute(
$HTTP_POST_FILES["iFile"]["tmp_name"],$HTTP_POST_VARS["output"]);
    break;
  default:
    echo "
The page you requested does not exist.";
    break;
}

?>



Usage Example




Rate This Script





Search



This Category All Categories