Last active
December 1, 2020 14:23
-
-
Save lilmuckers/4f78bb9ccde229a44f6de58435a5e4fd to your computer and use it in GitHub Desktop.
Compact Claustrophobia - Simplified robot builder lib for the shrrinking projector field
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-- This was written for shrinking field automation in Compact Claustrophobia modpack | |
-- This modpack has disabled the navigation upgrade, so navigation is done relative | |
-- to the starting point, and waypoints are handled with keyed in | |
-- Starting point is x,y,z - 0,0,0 | |
-- This does not use the minecraft coordinate paradigm because i don't find that intuitive | |
-- and it kept tripping me up when writing the code. | |
-- therefore - relative the robots starting position: | |
-- X -> +ve forward, -ve backwards | |
-- Y -> +ve left, -ve right | |
-- Z -> +ve up, -ve down | |
-- facing -> NORTH | |
local directions = { | |
NORTH = { left="WEST", right="EAST", back="SOUTH", modifier={x=1} }, | |
SOUTH = { left="EAST", right="WEST", back="NORTH", modifier={x=-1} }, | |
EAST = { left="NORTH", right="SOUTH", back="WEST", modifier={y=-1} },, | |
WEST = { left="SOUTH", right="NORTH", back="EAST", modifier={y=1} }, | |
UP = { modifier={z=1} }, | |
DOWN = { modifier={z=-1}} | |
} | |
local currentPosition = { x=0, y=0, z=0, facing="NORTH" } | |
local robot = require("robot") | |
local component = require("component") | |
local sides = require("sides") | |
-- Movement is handled by using modification tables. This is a helper to add the tables together | |
function _addTables(direction) | |
local modifier = direction["modifier"] | |
for k,v in pairs(modifier) do currentPosition[k] = currentPosition[k] + v end | |
return ending | |
end | |
-- This will try {attempts} times to run the robot.{operator} function. If it fails it will try again. | |
-- If it runs out of attempts; it will await the user to eeither cancel the script or to continue the script | |
function tryMove(operator, attempts) | |
local loop = 0 | |
local hasMoved = nil | |
local retry | |
repeat | |
loop = loop + 1 | |
hasMoved, reason = operator() | |
if hasMoved == nil then | |
os.sleep(5) | |
end | |
until hasMoved == true or loop == attempts | |
if hasMoved == nil then | |
io.write("Unable to move: " .. reason) | |
io.write("continue with this operation (Y/n)? ") | |
retry=io.read() | |
if retry == "n" then | |
os.exit() | |
else | |
return tryMove(operator, attempts) | |
end | |
end | |
end | |
function forward(squares) | |
local loop = 0 | |
repeat | |
tryMove(robot.forward, 5) | |
_addTables(directions[currentPosition["facing"]]) | |
loop = loop + 1 | |
until loop == squares | |
end | |
function back(squares) | |
local loop = 0 | |
local backDir = directions[currentPosition["facing"]]["back"] | |
repeat | |
tryMove(robot.back, 5) | |
_addTables(directions[backDir]) | |
loop = loop + 1 | |
until loop == squares | |
end | |
function up(squares) | |
local loop = 0 | |
repeat | |
tryMove(robot.up, 5) | |
_addTables(directions["UP"]) | |
loop = loop + 1 | |
until loop == squares | |
end | |
function down(squares) | |
local loop = 0 | |
repeat | |
tryMove(robot.down, 5) | |
_addTables(directions["DOWN"]) | |
loop = loop + 1 | |
until loop == squares | |
end | |
function turnLeft() | |
local leftDir = directions[currentPosition["facing"]]["left"] | |
robot.turnLeft() | |
currentPosition["facing"] = leftDir | |
end | |
function turnRight() | |
local rightDir = directions[currentPosition["facing"]]["right"] | |
robot.turnRight() | |
currentPosition["facing"] = rightDir | |
end | |
function left(squares) | |
turnLeft() | |
forward(squares) | |
turnRight() | |
end | |
function right(squares) | |
turnRight() | |
forward(squares) | |
turnLeft() | |
end | |
function _getMin(t) | |
local key = next(t) | |
local min = t[key] | |
for k, v in pairs(t) do | |
if t[k] < min then | |
key, min = k, v | |
end | |
end | |
return key, min | |
end | |
-- this assumes that up/down movement is always unblocked | |
function moveTo(coords) | |
-- calculate the displacement changes | |
local displacement, absDisplacement = {}, {} | |
displacement["x"] = coords["x"] - currentPosition["x"] | |
absDisplacement["x"] = math.abs(xDisplacement) | |
displacement["y"] = coords["y"] - currentPosition["y"] | |
absDisplacement["y"] = math.abs(yDisplacement) | |
displacement["z"] = coords["z"] - currentPosition["z"] | |
absDisplacement["z"] = math.abs(zDisplacement) | |
-- detect surroundings and move in "free" displacement first | |
-- all things being equal the smallest displacement is picked as a priority | |
-- if there is an entity in the way, it will wait and retry up to 5 times | |
-- if there is a block in the way, it will move in the next available displacement | |
-- and catch up later. | |
-- this is simple, and prone to errors in "wild" environments, but should work in a controlled CC machine | |
-- first find the minimum displacement direction | |
local key = next(absDisplacement) | |
local max = absDisplacement[key] | |
for k, v in pairs(t) do | |
if absDisplacement[k] > max then | |
key, max = k, v | |
end | |
end | |
end | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment