001      /*    Author Malte Pagel    */
002      
003          
error_reporting(E_STRICT E_ALL);
004      
005          if ( !isset(
$_GET['puzzle']) || !$_GET['puzzle'] || !isset($_GET['speed']) || !$_GET['speed'] || !isset($_GET['offset']) )
006              die( 
"personal_debug( 'No vaild puzzle data' );" );
007      
008          
/**
009           * Human-readable vardump
010           * An invention of O. Schwarten, osdata.org
011           */
012          
function ($x) {
013              echo 
"<pre>";
014              
print_r($x);
015              echo 
"</pre>";
016          }
017          
018          
$sent_puzzle $_GET['puzzle'];
019          
$piece_line explode(";"$sent_puzzle);
020          for ( 
$i 0$i count($piece_line); $i++ ) {
021              if ( !
$piece_line[$i] ) {
022                  
$black_index $i;
023                  break;
024              }
025          }
026          
027          
define("COLS"sqrt(count($piece_line)));
028          
define("SPEED"$_GET['speed']);                                            // Does not really seem to be used
029          
define("OFFSET"$_GET['offset']);
030          
031          
032          function 
answer_no_success () {
033              if ( 
defined("ANSWERED") )
034                  return;
035              
036              
define("ANSWERED"1);
037              echo 
"next_try( " OFFSET " );";
038          }
039          function 
answer_success ($moves) {
040              if ( 
defined("ANSWERED") )
041                  return;
042              
043              
define("ANSWERED"1);
044              echo 
"solution_is_found( [" implode(", "$moves) . "], " OFFSET " );";
045          }
046          
047          function 
would_be_closer ($actual$eventual$wanted) {
048              
049              
$actual_horizontal abs(($actual COLS) - ($wanted COLS));
050              
$actual_vertical abs( (int) ($actual COLS) - (int) ($wanted COLS) );
051              
$actual_distance $actual_horizontal $actual_vertical;
052              
053              
$eventual_horizontal abs(($eventual COLS) - ($wanted COLS));
054              
$eventual_vertical abs( (int) ($eventual COLS) - (int) ($wanted COLS) );
055              
$eventual_distance $eventual_horizontal $eventual_vertical;
056              
057              return (
$eventual_distance $actual_distance) ? 0;
058          }
059          
060          function 
eventually_continue_search ($moves_made$situation$moving_piece_position$black_position$allowed_faults) {
061              if ( empty(
$moves_made) || $situation[$moving_piece_position] != $moves_made[count($moves_made) - 1] ) {
062                  
$better would_be_closer($moving_piece_position$black_position, ($situation[$moving_piece_position] - 1));
063                  if ( 
$better || $allowed_faults ) {
064                      
065                      
$tmp_moves_made $moves_made;
066                      
$tmp_moves_made[] = $situation[$moving_piece_position];
067                      
068                      
$tmp_situation $situation;
069                      
$tmp_situation[$black_position] = $situation[$moving_piece_position];
070                      
$tmp_situation[$moving_piece_position] = $situation[$black_position];
071                      
072                      if ( 
$better ) {
073                          
stack_search($tmp_situation$moving_piece_position$tmp_moves_made$allowed_faults);
074                          return 
1;
075                      }
076                      else
077                          
stack_search($tmp_situation$moving_piece_position$tmp_moves_made, --$allowed_faults);
078                  }
079              }
080              return 
0;
081          }
082          
083          function 
test_if_solved ($situation) {
084              for ( 
$i 0$i count($situation); $i++ )
085                  if ( 
$situation[$i] && ($situation[$i] - 1) != $i )
086                      return;
087              
088              
define("SOLUTION_FOUND"1);
089          }
090          
091          function 
stack_search ($situation$black_position$moves_made$allowed_faults) {
092              
093              if ( 
defined("SOLUTION_FOUND") || defined("ANSWERED") )
094                  return;
095              
096              
$found_something_good 0;
097              
098              
// move black piece up, other piece down
099              
if ( ($black_position COLS) >= ) {
100                  
$moving_piece_position $black_position COLS;
101                  
102                  if ( 
eventually_continue_search($moves_made$situation$moving_piece_position$black_position$allowed_faults) )
103                      
$found_something_good 1;
104              }
105              
106              
// move black piece to right, other piece to left
107              
if ( ($black_position COLS) != (COLS 1) ) {
108                  
$moving_piece_position $black_position 1;
109                  
110                  if ( 
eventually_continue_search($moves_made$situation$moving_piece_position$black_position$allowed_faults) )
111                      
$found_something_good 1;
112              }
113              
114              
// move black piece down, other piece up
115              
if ( ($black_position COLS) < (COLS COLS) ) {
116                  
$moving_piece_position $black_position COLS;
117                  
118                  if ( 
eventually_continue_search($moves_made$situation$moving_piece_position$black_position$allowed_faults) )
119                      
$found_something_good 1;
120              }
121              
122              
// move black piece to left, other piece to right
123              
if ( ($black_position COLS) != ) {
124                  
$moving_piece_position $black_position 1;
125                  
126                  if ( 
eventually_continue_search($moves_made$situation$moving_piece_position$black_position$allowed_faults) )
127                      
$found_something_good 1;
128              }
129              
130              if ( !
$found_something_good )
131                  
test_if_solved($situation);
132              
133              if ( 
defined("SOLUTION_FOUND") ) {
134                  
answer_success($moves_made);
135                  return;
136              }
137          }
138          
139          
140          
/*  */
141          
142      
143          
$moves_made = Array();
144          
stack_search($piece_line$black_index$moves_madeOFFSET);
145          
146          if ( !
defined("SOLUTION_FOUND") )
147              
answer_no_success();
148      

149