Inhalt | Code | Beispiel A* | |
Beispiel IDA* |
C | PHP | Kommentare | Zeilennummern | Midnight |
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 v ($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) ? 1 : 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 > 0 ) {
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) >= 0 ) {
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) != 0 ) {
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_made, OFFSET);
145
146 if ( !defined("SOLUTION_FOUND") )
147 answer_no_success();
148
149