Hello all,
I have created a little maze with a robot and I use Blockly to generate code to try to solve it. I can move the robot using Javascript commands which are Blockly blocks. So far so good.
I am currently breaking my head over arguments of if-statements and while loops. Mainly, I have tried two things:
1. create a variable, 'not_goal_reached' which says whether or not the robot has reached the goal position (cross). Code:
function not_done() {
var goal_location = get_goal_position()
var goal_x = goal_location[0];
var goal_y = goal_location[1];
console.log('in not done');
//console.log(player.x!= goal_x || player.y != goal_y)
return (player.x!= goal_x || player.y != goal_y);
};
Blockly.Blocks['not_goal_reached'] = {
init: function() {
this.appendDummyInput()
.appendField("not at goal")
this.setOutput(true, "Boolean");
this.setColour(230);
this.setTooltip('');
this.setHelpUrl('');
}
};
Blockly.JavaScript['not_goal_reached'] = function(block) {
var code = 'not_done()';
// TODO: Change ORDER_NONE to the correct strength.
//console.log(code)
return [code, Blockly.JavaScript.ORDER_ATOMIC];
};
However, when using this block in an If or While statement. I always get a Javascript error that does not help me to find the solution:
TypeError: Cannot read property 'toBoolean' of undefined
at Interpreter.stepConditionalExpression (acorn_interpreter.js:148)
at Interpreter.step (acorn_interpreter.js:45)
at nextStep (index.html:79)
I use the Acorn js interpreter:
window.LoopTrap = 2000;
//Blockly.JavaScript.INFINITE_LOOP_TRAP = 'if(--window.LoopTrap == 0) throw "Infinite loop.";\n';
var code = Blockly.JavaScript.workspaceToCode(workspace);
console.log(code);
var myInterpreter = new Interpreter(code, initInterpreter);
//Blockly.JavaScript.INFINITE_LOOP_TRAP = null
var counter = 0;
function nextStep() {
try {
if (myInterpreter.step()) {
counter+=1;
console.log(counter);
if (counter < window.LoopTrap) {
window.setTimeout(nextStep, 30);
}
else {
throw "Infinite Loop!"
}
}
}
catch (e) {
//alert(e);
console.log(e)
}
}
nextStep();
Problem: javascript error I can not solve :(
2. I created my own While block that does not require input. This While block checks internally whether or not the robot has reached the goal and then processes the DO statements:
Blockly.Blocks['repeat_forever'] = {
init: function() {
this.appendDummyInput()
.appendField("While not at goal");
this.appendStatementInput("DO")
.appendField("Do");
this.setPreviousStatement(true);
this.setColour(230);
this.setTooltip('');
this.setHelpUrl('');
}
};
Blockly.JavaScript['repeat_forever'] = function(block) {
var branch = Blockly.JavaScript.statementToCode(block, 'DO');
// TODO: Assemble JavaScript into code variable.
//if (Blockly.JavaScript.INFINITE_LOOP_TRAP) {
// branch = Blockly.JavaScript.INFINITE_LOOP_TRAP.replace(/%1/g,
// '\'block_id_' +
block.id + '\'') + branch;
// console.log(branch);
//}
var code = 'while (' + 'not_done()' + ') {' + branch + '}';
console.log(code)
return [code, Blockly.JavaScript.ORDER_ATOMIC];
};
This works, BUT, here I have the problem that my internal function 'not_done' is only evaluated once (at code generation) to while(true) (since the first time the robot is of course not at the goal location yet). This block correctly applies the DO codes but does not halt (since while (true)). If I add quotes around 'not_done()' the function is evaluated once apparently, but then I receive the same Javascript error as above (Cannot read property 'toBoolean' of undefined)
Am I missing something here? Thanks a lot for your time!
Greetings
K