Compare commits
2 Commits
249a48807a
...
5f5e899f6e
| Author | SHA1 | Date | |
|---|---|---|---|
|
5f5e899f6e
|
|||
|
8546659ae0
|
56
src/bin/turtle/CircleMinePlan.hx
Normal file
56
src/bin/turtle/CircleMinePlan.hx
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
package bin.turtle;
|
||||||
|
|
||||||
|
import lib.turtle.planner.Plan;
|
||||||
|
import kernel.ps.ProcessHandle;
|
||||||
|
import kernel.ps.IProcess;
|
||||||
|
|
||||||
|
@:build(macros.Binstore.includeBin("Circle Mine Plan", ["cmp"]))
|
||||||
|
class CircleMinePlan implements IProcess {
|
||||||
|
public function new() {}
|
||||||
|
|
||||||
|
public function run(handle:ProcessHandle) {
|
||||||
|
var rings:Int = 3;
|
||||||
|
var skip:Int = 0;
|
||||||
|
|
||||||
|
var p = Plan.newPlan();
|
||||||
|
|
||||||
|
p = p.repeat([Forward], (skip * 3) - 1); // Move to outer ring or stay if none skiped
|
||||||
|
|
||||||
|
for (i in skip...(rings + skip)) {
|
||||||
|
if (i == 0) {
|
||||||
|
p = p.act([Clear(Down), Down, Clear(Down)]) // Move down a layer
|
||||||
|
.subplan(center());
|
||||||
|
} else {
|
||||||
|
p = p.subplan(circle(i * 3 + 1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
p.repeat([Back], (rings + skip) * 3 - 1);
|
||||||
|
|
||||||
|
p.begin(handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function circle(radius:Int):Plan {
|
||||||
|
return Plan.newPlan()
|
||||||
|
.act([FullTunnel, FullTunnel, HalfTunnel])
|
||||||
|
.act([TurnRight])
|
||||||
|
.repeat([FullTunnel], radius)
|
||||||
|
.repateSubplan(Plan.newPlan().act([TurnRight]).repeat([FullTunnel], radius).act([
|
||||||
|
TurnRight, Clear(Front), Down, Clear(Front), TurnLeft, TurnLeft, Clear(Front), Up, Clear(Front), TurnRight
|
||||||
|
]).repeat([FullTunnel], radius), 3)
|
||||||
|
.act([TurnRight])
|
||||||
|
.repeat([FullTunnel], radius)
|
||||||
|
.act([TurnLeft, Forward]);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function center():Plan {
|
||||||
|
return Plan.newPlan()
|
||||||
|
.act([Clear(Down)])
|
||||||
|
.act([FullTunnel])
|
||||||
|
.act([Clear(Front), Down, Clear(Front), Up])
|
||||||
|
.act([TurnRight])
|
||||||
|
.repeat([FullTunnel, TurnRight, FullTunnel, TurnLeft, HalfTunnel, TurnRight], 3)
|
||||||
|
.act([FullTunnel])
|
||||||
|
.act([TurnRight, Forward, TurnLeft, Forward]);
|
||||||
|
}
|
||||||
|
}
|
||||||
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);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user