package lib.turtle; import lib.Pos; import lib.Pos3; import kernel.turtle.Turtle; using tink.CoreApi; class TurtleExecuter { private var instructions:Array; public function new(instructions:Array) { this.instructions = instructions; } public function getRequiredFuel():Int { var fuel = 0; for (inst in instructions) { if (inst == Forward || inst == Back || inst == Up || inst == Down) { fuel++; } } return fuel; } public function getRequiredBlocks():Int { var blocks = 0; for (inst in instructions) { switch inst { case Place(_): blocks++; default: } } return blocks; } /** Return the offset of the turtle after executing the instructions. The origin is the starting position of the turtle. **/ public function getFinalOffset():{offset:Pos3, faceing:Pos} { var pos:Pos3 = {x: 0, y: 0, z: 0}; var forwardVec:Pos3 = {x: 1, y: 0, z: 0}; for (inst in instructions) { switch inst { case Forward: pos = pos + forwardVec; case Back: pos = pos - forwardVec; case TurnRight: forwardVec = {x: -forwardVec.z, z: forwardVec.x, y: forwardVec.y}; case TurnLeft: forwardVec = {x: forwardVec.z, z: -forwardVec.x, y: forwardVec.y}; default: } } return {offset: pos, faceing: new Pos({x: forwardVec.x, y: forwardVec.z})}; } public function execute() { for (inst in instructions) { executeInst(inst); } } private function executeInst(instruction:TurtleInstruction):Outcome { switch instruction { case Forward: return Turtle.forward(); case Back: return Turtle.back(); case Up: return Turtle.up(); case Down: return Turtle.down(); case TurnLeft: return Turtle.turnLeft(); case TurnRight: return Turtle.turnRight(); case Dig(dir): return Turtle.dig(dir); case Place(dir): return Turtle.place(dir); case PlacseSign(dir, text): return Turtle.placeSign(dir, text); case Select(slot): var r = Turtle.selectSlot(slot); if (r.isSuccess()) { return Outcome.Success(null); } else { return Outcome.Failure("Failed to select slot"); } } return Outcome.Failure("Unknown instruction: " + instruction); } }