define("PROGRAM_IS_CORRECT", "PROGRAM_IS_CORRECT");
define("PROGRAM_TAKES_TOO_MANY_EFFECTIVE_STEPS", "PROGRAM_TAKES_TOO_MANY_EFFECTIVE_STEPS");
define("PROGRAM_IS_WRONG", "PROGRAM_IS_WRONG");
define("SUCCESS", "SUCCESS");
define("FAIL", "FAIL");
error_reporting(E_ERROR | E_PARSE);
/* Initialize the program
* Count the effective program lines (without empty/labels)
*/
function init_program($arr_asm, $level, $passcode){
$back_to_editor = "
Gehe wieder zum Editor-Fenster zurück, um deinen Programm-Code zu verbessern. Viel Glück!";
$program = array();
// $inbox = array_reverse($inbox);
// echo("
");
$instruction_counter = 0;
$program_line_counter = 0;
$comments_counter = 0;
$labels_counter = 0;
foreach($arr_asm as $line){
$line = trim($line);
$line = preg_replace('!\s+!', ' ', $line); // Replacing multiple spaces with a single space
@list($cmd, $param) = explode(" ", $line);
// echo($program_line_counter + 1 . ": cmd = \"$cmd\", param = \"$param\"
\n");
$program_line_counter = $program_line_counter + 1;
switch($cmd){
case "inbox":
case "outbox":
case "jump":
case "jumpz":
case "jumpn":
case "copyto":
case "copyfrom":
case "add":
case "sub":
case "bumpup":
case "bumpdn":
array_push($program, ['cmd' => $cmd, 'param' => $param, 'instruction' => $instruction_counter]);
$instruction_counter = $instruction_counter + 1;
break;
default:
if(substr($cmd, 0, 2) == "--"){ //comment
$comments_counter = $comments_counter + 1;
array_push($program, ['cmd' => "comment", 'comment' => $line]);
}
else if(strlen($cmd) == 0){ //empty line
//nothing to do
}
else if(substr($cmd, -1, 1) == ":"){ //label, cutting off appending character (":")
$label = substr(trim("$cmd"), 0, -1);
// echo "Label: $label
";
if(!preg_match("/^[a-zA-Z]+$/", $label)){ //found invalid character in label
// echo("Parse error on line $program_line_counter: $line!\n");
$program_summary = "
Fehler in Programm-Code, Zeile $program_line_counter: $line! $back_to_editor";
array_push($program, ['cmd' => $cmd, 'param' => $param, 'instruction' => $instruction_counter]);
return array(0, $program, $program_summary, $instruction_counter, $labels_counter, ($comments_counter - 1));
}
$labels_counter = $labels_counter + 1;
array_push($program, ['cmd' => "label", 'label' => "$label"]);
}
else{ //error
// echo("Parse error on line $program_line_counter: $line!\n");
$program_summary = "
Fehler in Programm-Code, Zeile $program_line_counter: $line! $back_to_editor";
array_push($program, ['cmd' => $cmd, 'param' => $param, 'instruction' => $instruction_counter]);
return array(0, $program, $program_summary, $instruction_counter, $labels_counter, ($comments_counter - 1));
}
break;
}
}
$program_summary = "Total $program_line_counter Zeile(n) mit $instruction_counter Instruktion(en), $labels_counter Ziel(en) und $comments_counter Kommentar(en).";
return array(true, $program, $program_summary, $instruction_counter, $labels_counter, ($comments_counter - 1));
}
/* Tests the given program
*
*/
function test_program($program, $inbox, $expected_outbox, $hand, $data_registers, $max_allowed_steps){
// echo("$max_allowed_steps");
$outbox = array();
// $step_boxes = array();
$instructions_line_counter = 0;
$used_steps = 0;
$hand = "";
// print_r($program);
// echo("max_allowed_steps: $max_allowed_steps");
while($instructions_line_counter < count($program)){
// echo("($instructions_line_counter < ".count($program).") and (".count($outbox)." < ".count($inbox).")
");
$used_steps++;
/* Check if output is still correct
* todo: only run after a OUTPUT command
*/
// echo("Current Inbox: [");
// foreach($inbox as $element){ echo("$element, "); }; echo("]
");
// echo("Hand: $hand, Data registers: [");
// foreach($data_registers as $element){ echo("$element, "); }
// echo("]
");
// echo("Current Outbox: [");
// foreach($outbox as $element){ echo("$element, "); } echo("] , Expected Outbox: [");
// foreach($expected_outbox as $element){ echo("$element, "); }; echo("]
");
for($i = count($outbox) - 1; $i >= 0; $i--){
// echo($outbox[$i] . " <=> " . $expected_outbox[count($expected_outbox) - count($outbox) + $i] . " | ");
if($outbox[$i] != ($expected_outbox[count($expected_outbox)- count($outbox) + $i])){ //mismatch, outbox is wrong
// echo("
Program is incorrect
");
return [PROGRAM_IS_WRONG, $used_steps - 1];
}
}
// echo("
");
if(count($outbox) == count($expected_outbox)){ //outbox is full, program completed successfully
// echo("Program is correct
");
return [PROGRAM_IS_CORRECT, $used_steps - 1];
}
// array_push($step_boxes, $instructions_line_counter);
if($used_steps > $max_allowed_steps){
// echo("
Maximum steps reached (" . ($used_steps -1 ) . "/$max_allowed_steps)
");
return [PROGRAM_TAKES_TOO_MANY_EFFECTIVE_STEPS, $used_steps - 1];
}
$line = $program[$instructions_line_counter];
$cmd = $line['cmd'];
$param = $line['param'];
$label = $line['label'];
$comment = $line['comment'];
// echo("$used_steps: $cmd $param$label$comment
");
//--------------------------------------------------------------------------
switch($cmd){
case "inbox":
if(count($inbox) > 0){ //Check: Inbox is not empty
$hand = array_pop($inbox);
}
else{
// echo("
inbox: command is NOT valid with current registers/boxes
");
return [PROGRAM_IS_WRONG, $used_steps - 1];
}
break;
//--------------------------------------------------------------------------
case "outbox":
if($hand !== ""){ //Check: Hand is not empty
array_unshift($outbox, $hand);
$hand = "";
}
else{
// echo("
outbox: command is NOT valid with current registers/boxes
");
return [PROGRAM_IS_WRONG, $used_steps - 1];
}
break;
//--------------------------------------------------------------------------
case "jump":
$lable_is_on_line = "";
//find matching lable
foreach($program as $line_no => $line2){
if($line2['label'] == $param){
$lable_is_on_line = $line_no;
}
}
if($lable_is_on_line !== ""){ //Check: lable got found
$instructions_line_counter = $lable_is_on_line - 1; //set program counter to line containing the LABEL
}
else{
// echo("
: jumpcommand is NOT valid with current registers/boxes
");
return [PROGRAM_IS_WRONG, $used_steps - 1];
}
break;
//--------------------------------------------------------------------------
case "jumpz":
if($hand !== ""){ //Check: Hand is not empty;
$lable_is_on_line = "";
//find matching lable
foreach($program as $line_no => $line2){
if($line2['label'] == $param){
$lable_is_on_line = $line_no;
}
}
if($lable_is_on_line !== ""){ //Check: lable got found
if($hand == 0){ //hand is 0
$instructions_line_counter = $lable_is_on_line - 1; //set program counter to line containing the LABEL
}
else{ //continue on next line
//nothing to do
}
}
else{
// echo("
jumpz: command is NOT valid with current registers/boxes
");
return [PROGRAM_IS_WRONG, $used_steps - 1];
}
}
else{
// echo("
jumpz: command is NOT valid with current registers/boxes
");
return [PROGRAM_IS_WRONG, $used_steps - 1];
}
break;
//--------------------------------------------------------------------------
case "jumpn":
if($hand !== ""){ //Check: Hand is not empty;
$lable_is_on_line = "";
//find matching lable
foreach($program as $line_no => $line2){
if($line2['label'] == $param){
$lable_is_on_line = $line_no;
}
}
if($lable_is_on_line !== ""){ //Check: lable got found
if($hand < 0){ //hand is < 0
$instructions_line_counter = $lable_is_on_line - 1; //set program counter to line containing the LABEL
}
else{ //continue on next line
//nothing to do
}
}
else{
// echo("
jumpn: command is NOT valid with current registers/boxes
");
return [PROGRAM_IS_WRONG, $used_steps - 1];
}
}
else{
// echo("
command is NOT valid with current registers/boxes
");
return [PROGRAM_IS_WRONG, $used_steps - 1];
}
break;
//--------------------------------------------------------------------------
case "copyto":
if(($hand !== "") and (is_numeric($param)) and ($param >= 0) and ($param < count($data_registers))){ //Check: Hand is not empty;
$data_registers[$param] = $hand;
}
else{
// echo("
copyto: command is NOT valid with current registers/boxes
");
return [PROGRAM_IS_WRONG, $used_steps - 1];
}
break;
//--------------------------------------------------------------------------
case "copyfrom":
if(($data_registers[$param] !== "") and (is_numeric($param)) and ($param >= 0) and ($param < count($data_registers))){ //Check: Register is not empty
$hand = $data_registers[$param];
}
else{
// echo("
copyfrom: command is NOT valid with current registers/boxes
");
return [PROGRAM_IS_WRONG, $used_steps - 1];
}
break;
//--------------------------------------------------------------------------
case "add":
if(($hand !== "") and ($data_registers[$param] !== "") and (is_numeric($param)) and ($param >= 0) and ($param < count($data_registers))){ //Check: Hand and data register are not empty
$hand = $hand + $data_registers[$param];
}
else{
// echo("
add: command is NOT valid with current registers/boxes
");
return [PROGRAM_IS_WRONG, $used_steps - 1];
}
break;
//--------------------------------------------------------------------------
case "sub":
if(($hand !== "") and ($data_registers[$param] !== "") and (is_numeric($param)) and ($param >= 0) and ($param < count($data_registers))){ //Check: Hand and data register are not empty
$hand = $hand - $data_registers[$param];
}
else{
// echo("
: subcommand is NOT valid with current registers/boxes
");
return [PROGRAM_IS_WRONG, $used_steps - 1];
}
break;
//--------------------------------------------------------------------------
case "bumpup":
if(($data_registers[$param] !== "") and (is_numeric($param)) and ($param >= 0) and ($param < count($data_registers))){ //Check: Register is not empty
$data_registers[$param] = $data_registers[$param] + 1;
$hand = $data_registers[$param];
}
else{
// echo("
bumpup: command is NOT valid with current registers/boxes
");
return [PROGRAM_IS_WRONG, $used_steps - 1];
}
break;
//--------------------------------------------------------------------------
case "bumpdn":
if(($data_registers[$param] !== "") and (is_numeric($param)) and ($param >= 0) and ($param < count($data_registers))){ //Check: Register is not empty
$data_registers[$param] = $data_registers[$param] - 1;
$hand = $data_registers[$param];
}
else{
// echo("
bumpdn: command is NOT valid with current registers/boxes
");
return [PROGRAM_IS_WRONG, $used_steps - 1];
}
break;
//--------------------------------------------------------------------------
case "label": //label
$used_steps--; //A label doesn't count as a step real step, so decrement it again
break;
case "comment": //comment
$used_steps--; //A comment doesn't count as a step real step, so decrement it again
break;
//--------------------------------------------------------------------------
default: //unknown command
return [PROGRAM_IS_WRONG, $used_steps - 1];
}
$instructions_line_counter++;
}
}
function test_program_with_iterations($program, $level_configuration){
$average_used_steps = 0;
$max_used_steps = 0;
$test_iteration = 0;
while($test_iteration < $level_configuration['test_runs']){ // run many iterations of the users program to check if it works under all conditions
$test_iteration++;
$inbox = $level_configuration["inbox_preparation_function"]($level_configuration);
$expected_outbox = $level_configuration["reference_program"]($inbox, $level_configuration);
list($program_quality, $used_steps, $step_prints) = test_program(
$program,
$inbox,
$expected_outbox,
$level_configuration['hand'],
$level_configuration['data_registers'],
$level_configuration['max_allowed_steps']
);
// echo("
$used_steps
");
$average_used_steps = $average_used_steps + $used_steps;
If($used_steps > $max_used_steps) {
$max_used_steps = $used_steps;
}
if($program_quality != PROGRAM_IS_CORRECT){
return [FAIL, $inbox, $expected_outbox, round($average_used_steps / $test_iteration), $max_used_steps, $program_quality];
}
}
return [SUCCESS, $inbox, $expected_outbox, round($average_used_steps / $test_iteration), $max_used_steps];
}
function outbox_contains_no_errors($inbox, $expected_outbox, $outbox, $hand, $data_registers,$used_steps, $inbox_size, $outbox_size, $level, $passcode){
$back_to_editor = "
Gehe wieder zum Editor-Fenster
zurück, um deinen Programm-Code zu verbessern. Viel Glück!";
for($i = count($outbox) - 1; $i >= 0; $i--){
// echo($outbox[$i] . " != " . $expected_outbox[count($expected_outbox)- count($outbox) + $i] . "
");
if($outbox[$i] != $expected_outbox[count($expected_outbox)- count($outbox) + $i]){ //mismatch, outbox is wrong
print_step($hand, $data_registers, $inbox, $outbox, "Fehler nach Schritt ". ($used_steps - 1) .": Die Outbox enthält ein falsches Element
(Erwartet: ". box($expected_outbox[count($expected_outbox) - count($outbox)]) . ", Erhalten: ". box($outbox[0]) . ")! $back_to_editor", "DarkRed", $inbox_size, $outbox_size, $show_outbox_as_coordinate);
// echo("Die Outbox enthält ein falsches Element
");
return false;
}
}
return true;
}
function generate_program_steps($program, $inbox, $expected_outbox, $hand, $data_registers, $max_allowed_steps, $average_effective_steps, $maximum_allowed_instruction, $instruction_counter, $inbox_size, $outbox_size, $reward, $show_outbox_as_coordinate, $level, $passcode){
$back_to_editor = "
Gehe wieder zum Editor-Fenster
zurück, um deinen Programm-Code zu verbessern. Viel Glück!";
$outbox = array();
$step_boxes = array();
$instructions_line_counter = 0;
$visual_step = 0; //includes lables (since the target is also shown as a step point). It gets automatically incremented in print_step()
$used_steps = 0; //exclusive target since this is no real step
$hand = "";
while($instructions_line_counter < count($program)){
// echo("Visual Step: $visual_step: ($instructions_line_counter < ".count($program).") and (".count($outbox)." < ".count($inbox).")
");
$used_steps++;
if(outbox_contains_no_errors($inbox, $expected_outbox, $outbox, $hand, $data_registers, $used_steps, $inbox_size, $outbox_size, $level, $passcode) != true){
array_push($step_boxes, -4);
return $step_boxes;
}
if(count($outbox) == count($expected_outbox)){ //outbox is full, program completed successfully
goto PROGRAM_END;
}
// echo($instructions_line_counter);
array_push($step_boxes, $instructions_line_counter);
if($used_steps > $max_allowed_steps){
print_step($hand, $data_registers, $inbox, $outbox, "Schritt $used_steps: Fehler: Maximale Anzahl Schritte ($max_allowed_steps) erreicht! $back_to_editor", "DarkRed", $inbox_size, $outbox_size, $show_outbox_as_coordinate);
return $step_boxes;
}
$line = $program[$instructions_line_counter];
$cmd = $line['cmd'];
$param = $line['param'];
$label = $line['label'];
$comment = $line['comment'];
//--------------------------------------------------------------------------
switch($cmd){
case "inbox":
if(count($inbox) > 0){ //Check: Inbox is not empty
print_step($hand, $data_registers, $inbox, $outbox, "Schritt $used_steps:
$cmd", "black", $inbox_size, $outbox_size, $show_outbox_as_coordinate);
$hand = array_pop($inbox);
}
else{ //command is NOT valid with current registers/boxes
print_step($hand, $data_registers, $inbox, $outbox, "Schritt $used_steps:
$cmd
Fehler: Inbox ist leer! $back_to_editor", "DarkRed", $inbox_size, $outbox_size, $show_outbox_as_coordinate);
return $step_boxes;
}
break;
//--------------------------------------------------------------------------
case "outbox":
if($hand !== ""){ //Check: Hand is not empty
print_step($hand, $data_registers, $inbox, $outbox, "Schritt $used_steps:
$cmd", "black", $inbox_size, $outbox_size, $show_outbox_as_coordinate);
array_unshift($outbox, $hand);
$hand = "";
}
else{ //command is NOT valid with current registers/boxes
print_step($hand, $data_registers, $inbox, $outbox, "Schritt $used_steps:
$cmd
Fehler: Hand ist leer! $back_to_editor", "DarkRed", $inbox_size, $outbox_size, $show_outbox_as_coordinate);
return $step_boxes;
}
break;
//--------------------------------------------------------------------------
case "jump":
$lable_is_on_line = "";
//find matching lable
foreach($program as $line_no => $line2){
if($line2['label'] == $param){
$lable_is_on_line = $line_no;
}
}
if($lable_is_on_line !== ""){ //Check: lable got found
print_step($hand, $data_registers, $inbox, $outbox, "Schritt $used_steps:
$cmd $param", "black", $inbox_size, $outbox_size, $show_outbox_as_coordinate);
$instructions_line_counter = $lable_is_on_line - 1; //set program counter to line containing the LABEL
}
else{ //command is NOT valid with current registers/boxes
print_step($hand, $data_registers, $inbox, $outbox, "Schritt $used_steps:
$cmd $param
Fehler: Ziel existiert nicht! $back_to_editor", "DarkRed", $inbox_size, $outbox_size, $show_outbox_as_coordinate);
return $step_boxes;
}
break;
//--------------------------------------------------------------------------
case "jumpz":
if($hand !== ""){ //Check: Hand is not empty;
$lable_is_on_line = "";
//find matching lable
foreach($program as $line_no => $line2){
if($line2['label'] == $param){
$lable_is_on_line = $line_no;
}
}
if($lable_is_on_line !== ""){ //Check: lable got found
print_step($hand, $data_registers, $inbox, $outbox, "Schritt $used_steps:
$cmd $param", "black", $inbox_size, $outbox_size, $show_outbox_as_coordinate);
//
if($hand == 0){ //hand is 0
$instructions_line_counter = $lable_is_on_line - 1; //set program counter to line containing the LABEL
}
else{ //continue on next line
//nothing to do
}
}
else{ //command is NOT valid with current registers/boxes
print_step($hand, $data_registers, $inbox, $outbox, "Schritt $used_steps:
$cmd $param
Fehler: Ziel existiert nicht! $back_to_editor", "DarkRed", $inbox_size, $outbox_size, $show_outbox_as_coordinate);
return $step_boxes;
}
}
else{ //command is NOT valid with current registers/boxes
print_step($hand, $data_registers, $inbox, $outbox, "Schritt $used_steps:
$cmd
Fehler: Hand ist leer! $back_to_editor", "DarkRed", $inbox_size, $outbox_size, $show_outbox_as_coordinate);
return $step_boxes;
}
break;
//--------------------------------------------------------------------------
case "jumpn":
if($hand !== ""){ //Check: Hand is not empty;
$lable_is_on_line = "";
//find matching lable
foreach($program as $line_no => $line2){
if($line2['label'] == $param){
$lable_is_on_line = $line_no;
}
}
if($lable_is_on_line !== ""){ //Check: lable got found
print_step($hand, $data_registers, $inbox, $outbox, "Schritt $used_steps:
$cmd $param", "black", $inbox_size, $outbox_size, $show_outbox_as_coordinate);
//
if($hand < 0){ //hand is < 0
$instructions_line_counter = $lable_is_on_line - 1; //set program counter to line containing the LABEL
}
else{ //continue on next line
//nothing to do
}
}
else{ //command is NOT valid with current registers/boxes
print_step($hand, $data_registers, $inbox, $outbox, "Schritt $used_steps:
$cmd $param
Fehler: Ziel existiert nicht! $back_to_editor", "DarkRed", $inbox_size, $outbox_size, $show_outbox_as_coordinate);
return $step_boxes;
}
}
else{ //command is NOT valid with current registers/boxes
print_step($hand, $data_registers, $inbox, $outbox, "Schritt $used_steps:
$cmd
Fehler: Hand ist leer! $back_to_editor", "DarkRed", $inbox_size, $outbox_size, $show_outbox_as_coordinate);
return $step_boxes;
}
break;
//--------------------------------------------------------------------------
case "copyto":
if(($hand !== "") and (is_numeric($param)) and ($param >= 0) and ($param < count($data_registers))){ //Check: Hand is not empty
print_step($hand, $data_registers, $inbox, $outbox, "Schritt $used_steps:
$cmd $param", "black", $inbox_size, $outbox_size, $show_outbox_as_coordinate);
$data_registers[$param] = $hand;
}
else{ //command is NOT valid with current registers/boxes
print_step($hand, $data_registers, $inbox, $outbox, "Schritt $used_steps:
$cmd $param
Fehler: Hand ist leer oder das Daten-Register existiert nicht! $back_to_editor", "DarkRed", $inbox_size, $outbox_size, $show_outbox_as_coordinate);
return $step_boxes;
}
break;
//--------------------------------------------------------------------------
case "copyfrom":
if(($data_registers[$param] !== "") and (is_numeric($param)) and ($param >= 0) and ($param < count($data_registers))){ //Check: Register is not empty
print_step($hand, $data_registers, $inbox, $outbox, "Schritt $used_steps:
$cmd $param", "black", $inbox_size, $outbox_size, $show_outbox_as_coordinate);
$hand = $data_registers[$param];
}
else{ //command is NOT valid with current registers/boxes
print_step($hand, $data_registers, $inbox, $outbox, "Schritt $used_steps:
$cmd $param
Fehler: Data Register ist leer oder existiert nicht! $back_to_editor", "DarkRed", $inbox_size, $outbox_size, $show_outbox_as_coordinate);
return $step_boxes;
}
break;
//--------------------------------------------------------------------------
case "add":
if(($hand !== "") and ($data_registers[$param] !== "") and (is_numeric($param)) and ($param >= 0) and ($param < count($data_registers))){ //Check: Hand and data register are not empty
print_step($hand, $data_registers, $inbox, $outbox, "Schritt $used_steps:
$cmd $param", "black", $inbox_size, $outbox_size, $show_outbox_as_coordinate);
$hand = $hand + $data_registers[$param];
}
else{ //command is NOT valid with current registers/boxes
print_step($hand, $data_registers, $inbox, $outbox, "Schritt $used_steps:
$cmd $param
Fehler: Hand oder Data Register ist leer oder das Daten-Register existiert nicht! $back_to_editor", "DarkRed", $inbox_size, $outbox_size, $show_outbox_as_coordinate);
return $step_boxes;
}
break;
//--------------------------------------------------------------------------
case "sub":
if(($hand !== "") and ($data_registers[$param] !== "") and (is_numeric($param)) and ($param >= 0) and ($param < count($data_registers))){ //Check: Hand and data register are not empty
print_step($hand, $data_registers, $inbox, $outbox, "Schritt $used_steps:
$cmd $param", "black", $inbox_size, $outbox_size, $show_outbox_as_coordinate);
$hand = $hand - $data_registers[$param];
}
else{ //command is NOT valid with current registers/boxes
print_step($hand, $data_registers, $inbox, $outbox, "Schritt $used_steps:
$cmd $param
Fehler: Hand oder Data Register ist leer oder das Daten-Register existiert nicht! $back_to_editor", "DarkRed", $inbox_size, $outbox_size, $show_outbox_as_coordinate);
return $step_boxes;
}
break;
//--------------------------------------------------------------------------
case "bumpup":
if(($data_registers[$param] !== "") and (is_numeric($param)) and ($param >= 0) and ($param < count($data_registers))){ //Check: Register is not empty
print_step($hand, $data_registers, $inbox, $outbox, "Schritt $used_steps:
$cmd $param", "black", $inbox_size, $outbox_size, $show_outbox_as_coordinate);
$data_registers[$param] = $data_registers[$param] + 1;
$hand = $data_registers[$param];
}
else{ //command is NOT valid with current registers/boxes
print_step($hand, $data_registers, $inbox, $outbox, "Schritt $used_steps:
$cmd $param
Fehler: Data Register ist leer oder existiert nicht! $back_to_editor", "DarkRed", $inbox_size, $outbox_size, $show_outbox_as_coordinate);
return $step_boxes;
}
break;
//--------------------------------------------------------------------------
case "bumpdn":
if(($data_registers[$param] !== "") and (is_numeric($param)) and ($param >= 0) and ($param < count($data_registers))){ //Check: Register is not empty
print_step($hand, $data_registers, $inbox, $outbox, "Schritt $used_steps:
$cmd $param", "black", $inbox_size, $outbox_size, $show_outbox_as_coordinate);
$data_registers[$param] = $data_registers[$param] - 1;
$hand = $data_registers[$param];
}
else{ //command is NOT valid with current registers/boxes
print_step($hand, $data_registers, $inbox, $outbox, "Schritt $used_steps:
$cmd $param
Fehler: Data Register ist leer oder existiert nicht! $back_to_editor", "DarkRed", $inbox_size, $outbox_size, $show_outbox_as_coordinate);
return $step_boxes;
}
break;
//--------------------------------------------------------------------------
case "label": //label
print_step($hand, $data_registers, $inbox, $outbox, "Ziel
$label", "black", $inbox_size, $outbox_size, $show_outbox_as_coordinate);
$used_steps--; //A label doesn't count as a step real step, so decrement it again
break;
case "comment": //comment
array_pop($step_boxes); //remove step again from steps array, a comment is no instruction
$used_steps--; //A comment doesn't count as a step real step, so decrement it again
break;
//--------------------------------------------------------------------------
default: //unknown command
print_step($hand, $data_registers, $inbox, $outbox, "Schritt $used_steps:
$cmd $param
Fehler: Unbekannter Befehl auf Zeile $instructions_line_counter: \"$cmd $param$label$comment\"! $back_to_editor", "DarkRed", $inbox_size, $outbox_size, $show_outbox_as_coordinate);
return $step_boxes;
break;
}
$instructions_line_counter++;
}
/* Reached last line of program.
* Is the outbox as expected?
*/
if(count($outbox) != count($expected_outbox)){
array_push($step_boxes, -2);
print_step($hand, $data_registers, $inbox, $outbox, "Letzte Zeile des Programms erreicht, aber die Outbox ist nicht korrekt! $back_to_editor", "DarkRed", $inbox_size, $outbox_size, $show_outbox_as_coordinate);
// echo("End of program reached! but outbox incomplete
");
return $step_boxes;
}
PROGRAM_END:
if(($average_effective_steps <= $max_allowed_steps) and ($instruction_counter <= $maximum_allowed_instruction)){ //ok, meet one of both requirements
$text = "Programm erfolgreich abgearbeitet (Du hast " . ($used_steps - 1) . " Schritte benötigt).
$reward";
$color = "green";
}
else if($instruction_counter > $maximum_allowed_instruction){ //fail, used too many instructions
$text = "Programm erfolgreich abgearbeitet, aber Du hast zu viele Instruktionen ($instruction_counter) verwendet. Programm-Speicher ist sehr kostbar, daher muss die Programm-Grösse auf dem Minimum gehalten werden! Versuche mit $maximum_allowed_instruction Instruktionen auszukommen! $back_to_editor";
$color = "OrangeRed";
}
else{//fail, used too many steps
$text = "Programm erfolgreich abgearbeitet, aber Du hast im Durchschnitt zu viele Schritte ($average_effective_steps) benötigt. Je mehr Programm-Schritte ein Auftrag benötigt, desto mehr Zeit braucht das Programm. Und Zeit ist bekanntlich Geld. Versuche mit $max_allowed_steps Schritten auszukommen! $back_to_editor";
$color = "OrangeRed";
}
array_push($step_boxes, -3);
print_step($hand, $data_registers, $inbox, $outbox, $text, $color, $inbox_size, $outbox_size, $show_outbox_as_coordinate);
return $step_boxes;
}
/* This command is run before the execution of the instruction.
* It shows the situation the instruction is applied to!
*/
function print_step($hand, $data_registers, $inbox, $outbox, $text, $color, $inbox_size, $outbox_size, $show_outbox_as_coordinate){
global $visual_step;
$visual_step++;
?>
echo("$text"); ?>
print_inbox($inbox, $inbox_size);
echo("
\n");
print_registers($hand, $data_registers);
echo("
\n");
print_outbox($outbox, $outbox_size, $show_outbox_as_coordinate);
echo("\n");
?>
}
function box($value){
return "
$value ";
}
function print_box($value){
if($value !== ""){
echo("
" . box($value) . "
");
}
else{
echo("
");
}
}
function print_registers($hand, $data_registers){
?>
Daten-Register:
$i = 0;
foreach($data_registers as $item){
?>
print_box($item); ?>
echo($i);?>
$i++;
}
?>
}
function print_inbox($inbox, $inbox_size){
$inbox_size = 8; //limit
?>
Inbox =>
if(count($inbox) <= $inbox_size){
for($i = 0; $i < ($inbox_size - count($inbox)); $i++){ //less boxes than space, show as empty
print_box("");
}
foreach($inbox as $item){
print_box($item);
}
}
else{ //too many elements in the inbox, only print first ones
echo("
...
");
for($i = $inbox_size; $i > 0; $i--){
print_box($inbox[count($inbox) - $i]);
}
}
?>
}
function print_outbox($outbox, $outbox_size, $show_outbox_as_coordinate){
// $outbox_size = 8; //limit
?>
=> Outbox
if($show_outbox_as_coordinate != true){ //normal
foreach($outbox as $item){
print_box($item);
}
for($i = 0; $i < ($outbox_size - count($outbox)); $i++){ //less boxes than space, show as empty
print_box("");
}
}
else{ //coordinate
$position = 0;
echo("
N
");
foreach($outbox as $item){
print_box($item);
coordinate_formating($position);
$position++;
}
for($i = 0; $i < ($outbox_size - count($outbox)); $i++){ //less boxes than space, show as empty
print_box("");
coordinate_formating($position);
$position++;
}
}
?>
}
function coordinate_formating($position){
if(($position == 6)){ echo("
E
");}
elseif(($position == 1) or ($position == 9)){ echo("
°
");}
else if(($position == 3) or ($position == 11)){ echo("
,
");}
}
function cleanup_asm_array(&$value)
{
$value = trim($value);
if(substr($value, 0, 2) == "--"){ //comment
//nothing to do
}
else{ //all other commands/lables, change to upper case
$value = strtolower($value);
}
}
?>