added turtleInstructionParser
This commit is contained in:
parent
b40e293d6e
commit
aca39ea46f
126
src/lib/turtle/TurtleInstructionParser.hx
Normal file
126
src/lib/turtle/TurtleInstructionParser.hx
Normal file
@ -0,0 +1,126 @@
|
|||||||
|
package lib.turtle;
|
||||||
|
|
||||||
|
// Check usage of NativeStringTools
|
||||||
|
// here https://api.haxe.org/lua/NativeStringTools.html
|
||||||
|
// and here http://lua-users.org/wiki/StringLibraryTutorial
|
||||||
|
|
||||||
|
import kernel.turtle.Types.TurtleSlot;
|
||||||
|
import kernel.turtle.Turtle;
|
||||||
|
import lua.NativeStringTools;
|
||||||
|
|
||||||
|
using tink.CoreApi;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
Save a set of turtle instructions to a string and execute them.
|
||||||
|
**/
|
||||||
|
class TurtleInstructionParser {
|
||||||
|
|
||||||
|
public function new() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public function encode(instructions: Array<TurtleInstruction>): String {
|
||||||
|
var s = "";
|
||||||
|
|
||||||
|
var times = 0;
|
||||||
|
var lastInstruction: TurtleInstruction = null;
|
||||||
|
|
||||||
|
for (inst in instructions){
|
||||||
|
if (inst == lastInstruction){
|
||||||
|
times++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lastInstruction != null){
|
||||||
|
var encoded = encodeInstruction(lastInstruction);
|
||||||
|
s = s + '${times + 1}$encoded';
|
||||||
|
}
|
||||||
|
|
||||||
|
times = 0;
|
||||||
|
lastInstruction = inst;
|
||||||
|
}
|
||||||
|
|
||||||
|
var encoded = encodeInstruction(lastInstruction);
|
||||||
|
s = s + '${times + 1}$encoded';
|
||||||
|
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function encodeInstruction(inst: TurtleInstruction): String {
|
||||||
|
for (k => v in cmdMap){
|
||||||
|
if (v == inst){
|
||||||
|
return k;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
switch inst {
|
||||||
|
case Select(slot):
|
||||||
|
return "m" + encodeSlot(slot);
|
||||||
|
default:
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
private function encodeSlot(slot: TurtleSlot): String {
|
||||||
|
return String.fromCharCode(slot + 97);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function parse(instructionsString: String): Array<TurtleInstruction> {
|
||||||
|
var rtn: Array<TurtleInstruction> = [];
|
||||||
|
var mfunc = NativeStringTools.gmatch(instructionsString,"%d+%D+");
|
||||||
|
|
||||||
|
while(true){
|
||||||
|
var found = mfunc();
|
||||||
|
|
||||||
|
if (found == null) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
var times = Std.parseInt(NativeStringTools.match(found, "%d+"));
|
||||||
|
var command = NativeStringTools.match(found, "%D+");
|
||||||
|
|
||||||
|
var cmd = cmdMap.get(command);
|
||||||
|
if (cmd != null){
|
||||||
|
rtn = rtn.concat([for (i in 0...times) cmd]);
|
||||||
|
}
|
||||||
|
|
||||||
|
switch command.charAt(0) {
|
||||||
|
case "m": // select
|
||||||
|
var slot = parseSlot(command.charAt(1));
|
||||||
|
rtn = rtn.concat([for (i in 0...times) Select(slot)]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return rtn;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static function parseSlot(slot: String): TurtleSlot {
|
||||||
|
var slot = slot.charCodeAt(0) - 97;
|
||||||
|
|
||||||
|
if (slot < 0 || slot > Turtle.MAX_SLOTS) {
|
||||||
|
// TODO: better error handling
|
||||||
|
throw new Error("Invalid slot: " + slot);
|
||||||
|
}
|
||||||
|
|
||||||
|
return slot;
|
||||||
|
}
|
||||||
|
|
||||||
|
private var cmdMap:Map<String,TurtleInstruction> = [
|
||||||
|
"a" => Forward,
|
||||||
|
"b" => Back,
|
||||||
|
"c" => TurnLeft,
|
||||||
|
"d" => TurnRight,
|
||||||
|
"e" => Up,
|
||||||
|
"f" => Down,
|
||||||
|
"g" => Dig(Front),
|
||||||
|
"h" => Dig(Up),
|
||||||
|
"i" => Dig(Down),
|
||||||
|
"j" => Place(Front),
|
||||||
|
"k" => Place(Up),
|
||||||
|
"l" => Place(Down),
|
||||||
|
];
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user