added turtleInstructionParser

This commit is contained in:
Djeeberjr 2022-04-13 21:40:57 +02:00
parent b40e293d6e
commit aca39ea46f

View 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),
];
}