Skip to content

Instantly share code, notes, and snippets.

@lilmuckers
Last active December 1, 2020 14:23
Show Gist options
  • Save lilmuckers/4f78bb9ccde229a44f6de58435a5e4fd to your computer and use it in GitHub Desktop.
Save lilmuckers/4f78bb9ccde229a44f6de58435a5e4fd to your computer and use it in GitHub Desktop.
Compact Claustrophobia - Simplified robot builder lib for the shrrinking projector field
-- 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