first implementation of turtle plans
This commit is contained in:
parent
249a48807a
commit
8546659ae0
15
src/lib/turtle/planner/Action.hx
Normal file
15
src/lib/turtle/planner/Action.hx
Normal file
@ -0,0 +1,15 @@
|
||||
package lib.turtle.planner;
|
||||
|
||||
import kernel.turtle.Types.InteractDirections;
|
||||
|
||||
enum Action {
|
||||
Forward;
|
||||
Back;
|
||||
Up;
|
||||
Down;
|
||||
TurnLeft;
|
||||
TurnRight;
|
||||
Clear(dir:InteractDirections); // Digs in the direction. Does not fail if nothing to dig. Trys again if still blocked.
|
||||
FullTunnel; // Digs front, move forward, dig down. Like a tunnel for a player.
|
||||
HalfTunnel; // Just clears s 1x2 tunnel infront of it. Like FullTunnel but without moving.
|
||||
}
|
41
src/lib/turtle/planner/Executer.hx
Normal file
41
src/lib/turtle/planner/Executer.hx
Normal file
@ -0,0 +1,41 @@
|
||||
package lib.turtle.planner;
|
||||
|
||||
import kernel.turtle.Turtle;
|
||||
|
||||
using tink.CoreApi;
|
||||
|
||||
class Executer {
|
||||
public function new() {}
|
||||
|
||||
public function execute(action:Action) {
|
||||
var r = translate(action);
|
||||
switch r {
|
||||
case Failure(failure):
|
||||
throw new Error(failure); // I think that this a valid place to use exeptions.
|
||||
default:
|
||||
}
|
||||
}
|
||||
|
||||
private function translate(action:Action):Outcome<Noise, String> {
|
||||
switch (action) {
|
||||
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 Clear(dir):
|
||||
return Turtle.digEmpty(dir);
|
||||
case FullTunnel:
|
||||
return Helper.combine([Turtle.digEmpty.bind(Front), Turtle.forward, Turtle.digEmpty.bind(Down)]);
|
||||
case HalfTunnel:
|
||||
return Helper.combine([Turtle.digEmpty.bind(Front), Turtle.down, Turtle.digEmpty.bind(Front), Turtle.up]);
|
||||
}
|
||||
}
|
||||
}
|
142
src/lib/turtle/planner/Plan.hx
Normal file
142
src/lib/turtle/planner/Plan.hx
Normal file
@ -0,0 +1,142 @@
|
||||
package lib.turtle.planner;
|
||||
|
||||
import kernel.turtle.TurtleMutex;
|
||||
import kernel.ps.ProcessHandle;
|
||||
|
||||
using tink.CoreApi;
|
||||
|
||||
/**
|
||||
A plan repesents a pice of a squence of turtle commands.
|
||||
It acts like node in a linked list.
|
||||
It also has no interal state and can be reused.
|
||||
Once a plan has been setup it (should be) is immutable.
|
||||
**/
|
||||
class Plan {
|
||||
private var prev:Null<Plan>;
|
||||
private var delegate:(Executer) -> Void;
|
||||
|
||||
public static function newPlan():Plan {
|
||||
return new Plan();
|
||||
}
|
||||
|
||||
private function new() {}
|
||||
|
||||
/**
|
||||
Do a sequence of actions
|
||||
**/
|
||||
public function act(actions:Array<Action>):Plan {
|
||||
#if debug
|
||||
if (this.delegate != null) {
|
||||
throw new Error("Can't reuse plans");
|
||||
}
|
||||
#end
|
||||
this.delegate = (ex) -> {
|
||||
trace('Act: $actions');
|
||||
for (a in actions) {
|
||||
ex.execute(a);
|
||||
}
|
||||
};
|
||||
|
||||
var next = new Plan();
|
||||
next.prev = this;
|
||||
return next;
|
||||
}
|
||||
|
||||
/**
|
||||
Do a sequence of actions multiple times.
|
||||
**/
|
||||
public function repeat(actions:Array<Action>, times:Int):Plan {
|
||||
#if debug
|
||||
if (this.delegate != null) {
|
||||
throw new Error("Can't reuse plans");
|
||||
}
|
||||
#end
|
||||
this.delegate = (ex) -> {
|
||||
trace('Rep: $actions');
|
||||
for (i in 0...times) {
|
||||
for (a in actions) {
|
||||
ex.execute(a);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
var next = new Plan();
|
||||
next.prev = this;
|
||||
return next;
|
||||
}
|
||||
|
||||
/**
|
||||
Append a plan to the current chain.
|
||||
**/
|
||||
public function subplan(plan:Plan):Plan {
|
||||
#if debug
|
||||
if (this.delegate != null) {
|
||||
throw new Error("Can't reuse plans");
|
||||
}
|
||||
#end
|
||||
this.delegate = (ex) -> {
|
||||
trace('Subplan');
|
||||
plan.execute(ex);
|
||||
};
|
||||
|
||||
var next = new Plan();
|
||||
next.prev = this;
|
||||
return next;
|
||||
}
|
||||
|
||||
/**
|
||||
Execute a plan mutiple times.
|
||||
**/
|
||||
public function repateSubplan(plan:Plan, times:Int):Plan {
|
||||
#if debug
|
||||
if (this.delegate != null) {
|
||||
throw new Error("Can't reuse plans");
|
||||
}
|
||||
#end
|
||||
this.delegate = (ex) -> {
|
||||
trace('Subplan repeat');
|
||||
for (_ in 0...times) {
|
||||
plan.execute(ex);
|
||||
}
|
||||
};
|
||||
|
||||
var next = new Plan();
|
||||
next.prev = this;
|
||||
return next;
|
||||
}
|
||||
|
||||
private function execute(ex:Executer) {
|
||||
if (this.prev == null) {
|
||||
this.delegate(ex);
|
||||
return;
|
||||
}
|
||||
|
||||
this.prev.execute(ex);
|
||||
|
||||
if (this.delegate != null) { // The last plan in a line does not have a delegate
|
||||
this.delegate(ex);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
public function begin(handle:ProcessHandle) {
|
||||
trace("begin plan");
|
||||
if (!handle.claimTurtleMutex()) {
|
||||
handle.writeLine("Failed to claim turtle mutex");
|
||||
handle.close();
|
||||
return;
|
||||
}
|
||||
|
||||
var ex = new Executer();
|
||||
|
||||
TurtleMutex.runInTThread(() -> {
|
||||
try {
|
||||
this.execute(ex);
|
||||
} catch (e) {
|
||||
handle.writeLine(e.message);
|
||||
}
|
||||
handle.close(true);
|
||||
});
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user