Created
July 23, 2015 11:56
-
-
Save ZeekDaGeek/527b71fea87cec4953f4 to your computer and use it in GitHub Desktop.
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
-- Very specifically created script to build a circle. | |
-- Would probably have to be tweaked for your own operations. | |
-- By: ZeekDaGeek | |
local component = require("component") | |
local gpu = component.getPrimary("gpu") | |
local keyboard = require("keyboard") | |
local computer = require("computer") | |
local robot = require("robot") | |
local navi = component.getPrimary("navigation") | |
local sides = require("sides") | |
local fs = require("filesystem") | |
local ser = require("serialization") | |
-- Accept arguments | |
local args = { ... } | |
if #args == 0 or (args[1] ~= "resume" and tonumber(args[1]) <= 0) then | |
print("Usage: buildCircle [resume / radius]") | |
return false | |
end | |
-- Circle save | |
fileCircleCoords = "/home/circleCoords.dat" | |
-- Define types | |
circleFillType = 1 | |
circleFillAltType = 1 | |
circleBorderType = 2 | |
completeType = 3 | |
-- Center the robot | |
local curX, curY, curZ, posError = navi.getPosition() | |
local curX = math.floor(curX) | |
local curY = math.floor(curY) | |
local curZ = math.floor(curZ) | |
-- Integers to plug into equation, | |
local intX, intY = 0, 0 | |
-- Track robot | |
worker = { | |
coords = { | |
x = curX, | |
y = curY, | |
z = curZ | |
}, | |
facing = navi.getFacing() | |
} | |
-- Circle information | |
local radius = args[1] | |
local centerPoint = true | |
local circleCoords = {} | |
if centerPoint == true then | |
offsetQ1x = 2 | |
offsetQ3y = -2 | |
offsetQ4x = 2 | |
offsetQ4y = -2 | |
else | |
offsetQ1x = 0 | |
offsetQ3y = 0 | |
offsetQ4x = 0 | |
offsetQ4y = 0 | |
end | |
-- Equation | |
-- (x - a)^2 + (y - b)^2 = r^2 | |
if args[1] ~= "resume" then | |
local genCircle = true | |
while genCircle == true do | |
intX = 0 | |
local testX = true | |
if (intY ^ 2 > radius ^ 2) then | |
intY = intY - 1 | |
currentPalette = circleBorderType | |
genCircle = false | |
break | |
else | |
while testX == true do | |
if ((intX ^ 2 + intY ^ 2) < radius ^ 2) then | |
if false then | |
if (math.fmod(intX, 2) == 0) and (currentPalette ~= circleBorderType) then | |
currentPalette = circleFillType | |
else | |
currentPalette = circleFillAltType | |
end | |
local tmpX, tmpY, tmpZ = curX + intX + offsetQ1x, curY, curZ + intY | |
tmpIndex = string.format("%i,%i,%i", tmpX, tmpY, tmpZ) | |
circleCoords[tmpIndex] = { | |
coords = { x = tmpX, y = tmpY, z = tmpZ }, | |
type = currentPalette, | |
} | |
local tmpX, tmpY, tmpZ = curX - intX , curY, curZ + intY | |
tmpIndex = string.format("%i,%i,%i", tmpX, tmpY, tmpZ) | |
circleCoords[tmpIndex] = { | |
coords = { x = tmpX, y = tmpY, z = tmpZ }, | |
type = currentPalette, | |
} | |
local tmpX, tmpY, tmpZ = curX + intX + offsetQ4x, curY, curZ - intY + offsetQ4y | |
tmpIndex = string.format("%i,%i,%i", tmpX, tmpY, tmpZ) | |
circleCoords[tmpIndex] = { | |
coords = { x = tmpX, y = tmpY, z = tmpZ }, | |
type = currentPalette, | |
} | |
local tmpX, tmpY, tmpZ = curX - intX , curY, curZ - intY + offsetQ3y | |
tmpIndex = string.format("%i,%i,%i", tmpX, tmpY, tmpZ) | |
circleCoords[tmpIndex] = { | |
coords = { x = tmpX, y = tmpY, z = tmpZ }, | |
type = currentPalette, | |
} | |
end | |
else | |
intX = intX - 1 | |
currentPalette = circleBorderType | |
local tmpX, tmpY, tmpZ = curX + intX + offsetQ1x, curY, curZ + intY | |
tmpIndex = string.format("%i,%i,%i", tmpX, tmpY, tmpZ) | |
circleCoords[tmpIndex] = { | |
coords = { x = tmpX, y = tmpY, z = tmpZ }, | |
type = currentPalette, | |
} | |
local tmpX, tmpY, tmpZ = curX - intX , curY, curZ + intY | |
tmpIndex = string.format("%i,%i,%i", tmpX, tmpY, tmpZ) | |
circleCoords[tmpIndex] = { | |
coords = { x = tmpX, y = tmpY, z = tmpZ }, | |
type = currentPalette, | |
} | |
local tmpX, tmpY, tmpZ = curX + intX + offsetQ4x, curY, curZ - intY + offsetQ4y | |
tmpIndex = string.format("%i,%i,%i", tmpX, tmpY, tmpZ) | |
circleCoords[tmpIndex] = { | |
coords = { x = tmpX, y = tmpY, z = tmpZ }, | |
type = currentPalette, | |
} | |
local tmpX, tmpY, tmpZ = curX - intX , curY, curZ - intY + offsetQ3y | |
tmpIndex = string.format("%i,%i,%i", tmpX, tmpY, tmpZ) | |
circleCoords[tmpIndex] = { | |
coords = { x = tmpX, y = tmpY, z = tmpZ }, | |
type = currentPalette, | |
} | |
intY = intY - 1 | |
testSubX = true | |
while testSubX == true and intY > 0 do | |
if ((intX ^ 2 + intY ^ 2) < radius ^ 2) then | |
local tmpX, tmpY, tmpZ = curX + intX + offsetQ1x, curY, curZ + intY | |
tmpIndex = string.format("%i,%i,%i", tmpX, tmpY, tmpZ) | |
circleCoords[tmpIndex] = { | |
coords = { x = tmpX, y = tmpY, z = tmpZ }, | |
type = currentPalette, | |
} | |
local tmpX, tmpY, tmpZ = curX - intX , curY, curZ + intY | |
tmpIndex = string.format("%i,%i,%i", tmpX, tmpY, tmpZ) | |
circleCoords[tmpIndex] = { | |
coords = { x = tmpX, y = tmpY, z = tmpZ }, | |
type = currentPalette, | |
} | |
local tmpX, tmpY, tmpZ = curX + intX + offsetQ4x, curY, curZ - intY + offsetQ4y | |
tmpIndex = string.format("%i,%i,%i", tmpX, tmpY, tmpZ) | |
circleCoords[tmpIndex] = { | |
coords = { x = tmpX, y = tmpY, z = tmpZ }, | |
type = currentPalette, | |
} | |
local tmpX, tmpY, tmpZ = curX - intX , curY, curZ - intY + offsetQ3y | |
tmpIndex = string.format("%i,%i,%i", tmpX, tmpY, tmpZ) | |
circleCoords[tmpIndex] = { | |
coords = { x = tmpX, y = tmpY, z = tmpZ }, | |
type = currentPalette, | |
} | |
else | |
testSubX = false | |
end | |
intX = intX + 1 | |
end | |
intY = intY + 1 | |
currentPalette = circleFillType | |
testX = false | |
end | |
intX = intX + 1 | |
end | |
end | |
currentPalette = circleFillType | |
intY = intY + 1 | |
end | |
else | |
local fh = fs.open(fileCircleCoords, "r") | |
local fContents = fh:read(32768) | |
circleCoords = ser.unserialize(fContents) | |
fh:close() | |
end | |
function saveCircle() | |
local fh = fs.open(fileCircleCoords, "w") | |
fh:write(ser.serialize(circleCoords)) | |
fh:close() | |
end | |
-- worker movements. | |
function worker:moveUp() | |
local newCoords = {} | |
newCoords.x = self.coords.x | |
newCoords.y = self.coords.y + 1 | |
newCoords.z = self.coords.z | |
if (robot.up()) then | |
-- Change the coords. | |
self.coords.x = newCoords.x | |
self.coords.y = newCoords.y | |
self.coords.z = newCoords.z | |
-- print(string.format(" Moved UP to %i,%i,%i", newCoords.x, newCoords.y, newCoords.z)) | |
return true | |
else | |
return false | |
end | |
end | |
function worker:moveDown() | |
local newCoords = {} | |
newCoords.x = self.coords.x | |
newCoords.y = self.coords.y - 1 | |
newCoords.z = self.coords.z | |
if (robot.down()) then | |
-- Change the coords. | |
self.coords.x = newCoords.x | |
self.coords.y = newCoords.y | |
self.coords.z = newCoords.z | |
-- print(string.format(" Moved DOWN to %i,%i,%i", newCoords.x, newCoords.y, newCoords.z)) | |
return true | |
else | |
return false | |
end | |
end | |
function worker:moveNorth() | |
local newCoords = {} | |
newCoords.x = self.coords.x | |
newCoords.y = self.coords.y | |
newCoords.z = self.coords.z - 1 | |
if worker.facing == sides.north then | |
-- Just move forward | |
elseif worker.facing == sides.east then | |
robot.turnLeft() | |
elseif worker.facing == sides.south then | |
robot.turnLeft() | |
robot.turnLeft() | |
elseif worker.facing == sides.west then | |
robot.turnRight() | |
end | |
self.facing = sides.north | |
if (robot.forward()) then | |
-- Change the coords. | |
self.coords.x = newCoords.x | |
self.coords.y = newCoords.y | |
self.coords.z = newCoords.z | |
-- print(string.format(" Moved NORTH to %i,%i,%i", newCoords.x, newCoords.y, newCoords.z)) | |
return true | |
else | |
return false | |
end | |
end | |
function worker:moveSouth() | |
local newCoords = {} | |
newCoords.x = self.coords.x | |
newCoords.y = self.coords.y | |
newCoords.z = self.coords.z + 1 | |
if worker.facing == sides.north then | |
robot.turnRight() | |
robot.turnRight() | |
elseif worker.facing == sides.east then | |
robot.turnRight() | |
elseif worker.facing == sides.south then | |
-- Just move forward | |
elseif worker.facing == sides.west then | |
robot.turnLeft() | |
end | |
self.facing = sides.south | |
if (robot.forward()) then | |
-- Change the coords. | |
self.coords.x = newCoords.x | |
self.coords.y = newCoords.y | |
self.coords.z = newCoords.z | |
-- print(string.format(" Moved SOUTH to %i,%i,%i", newCoords.x, newCoords.y, newCoords.z)) | |
return true | |
else | |
return false | |
end | |
end | |
function worker:moveEast() | |
local newCoords = {} | |
newCoords.x = self.coords.x + 1 | |
newCoords.y = self.coords.y | |
newCoords.z = self.coords.z | |
if worker.facing == sides.north then | |
robot.turnRight() | |
elseif worker.facing == sides.east then | |
-- Just move forward | |
elseif worker.facing == sides.south then | |
robot.turnLeft() | |
elseif worker.facing == sides.west then | |
robot.turnLeft() | |
robot.turnLeft() | |
end | |
self.facing = sides.east | |
if (robot.forward()) then | |
-- Change the coords. | |
self.coords.x = newCoords.x | |
self.coords.y = newCoords.y | |
self.coords.z = newCoords.z | |
-- print(string.format(" Moved EAST to %i,%i,%i", newCoords.x, newCoords.y, newCoords.z)) | |
return true | |
else | |
return false | |
end | |
end | |
function worker:moveWest() | |
local newCoords = {} | |
newCoords.x = self.coords.x - 1 | |
newCoords.y = self.coords.y | |
newCoords.z = self.coords.z | |
if worker.facing == sides.north then | |
robot.turnLeft() | |
elseif worker.facing == sides.east then | |
robot.turnRight() | |
robot.turnRight() | |
elseif worker.facing == sides.south then | |
robot.turnRight() | |
elseif worker.facing == sides.west then | |
-- Just move forward | |
end | |
self.facing = sides.west | |
if (robot.forward()) then | |
-- Change the coords. | |
self.coords.x = newCoords.x | |
self.coords.y = newCoords.y | |
self.coords.z = newCoords.z | |
-- print(string.format(" Moved WEST to %i,%i,%i", newCoords.x, newCoords.y, newCoords.z)) | |
return true | |
else | |
return false | |
end | |
end | |
function worker:moveto (toLoc) | |
-- Track state of movement. | |
workerStuck = false | |
workerArrived = false | |
-- Keep track of failed attempts at movement in a row | |
-- If this happens too much then we're stuck | |
failedMoves = 0 | |
-- Main loop of movement | |
while failedMoves <= 10 and workerArrived == false do | |
if self.coords.x == toLoc.coords.x and self.coords.y == toLoc.coords.y and self.coords.z == toLoc.coords.z then | |
workerArrived = true | |
return true | |
end | |
-- Match height first. | |
while self.coords.y ~= toLoc.coords.y do | |
if self.coords.y > toLoc.coords.y then | |
if worker:moveDown() == false then | |
failedMoves = failedMoves + 1 | |
break | |
else | |
failedMoves = 0 | |
end | |
elseif self.coords.y < toLoc.coords.y then | |
if worker:moveUp() == false then | |
failedMoves = failedMoves + 1 | |
break | |
else | |
failedMoves = 0 | |
end | |
end | |
end | |
-- Then match X next. | |
while self.coords.x ~= toLoc.coords.x do | |
if self.coords.x > toLoc.coords.x then | |
if worker:moveWest() == false then | |
failedMoves = failedMoves + 1 | |
break | |
else | |
failedMoves = 0 | |
end | |
elseif self.coords.x < toLoc.coords.x then | |
if worker:moveEast() == false then | |
failedMoves = failedMoves + 1 | |
break | |
else | |
failedMoves = 0 | |
end | |
end | |
end | |
-- Then match Z next. | |
while self.coords.z ~= toLoc.coords.z do | |
if self.coords.z > toLoc.coords.z then | |
if worker:moveNorth() == false then | |
failedMoves = failedMoves + 1 | |
break | |
else | |
failedMoves = 0 | |
end | |
elseif self.coords.z < toLoc.coords.z then | |
if worker:moveSouth() == false then | |
failedMoves = failedMoves + 1 | |
break | |
else | |
failedMoves = 0 | |
end | |
end | |
end | |
end | |
return false | |
end | |
function worker:repair() | |
print("Repairs needed.") | |
worker:moveto({ coords = { x = -75, y = 90, z = -15 }}) | |
worker:moveWest() | |
print(" Emptying inventory") | |
slotSelect = 1 | |
while slotSelect <= 16 and robot.detect() do | |
robot.select(slotSelect) | |
while robot.drop() == false and robot.count() > 0 do | |
if robot.down() then | |
self.coords.y = self.coords.y - 1 | |
end | |
end | |
slotSelect = slotSelect + 1 | |
end | |
print(" Moving to charge station") | |
-- Move to the bottom of the stack of chests | |
while robot.down() do | |
-- Do nothing, the robot is just moving down | |
self.coords.y = self.coords.y - 1 | |
end | |
print(" Charging to full") | |
-- Charge the robot | |
while ((computer.energy() / computer.maxEnergy()) <= 0.9) do | |
os.sleep(10) | |
end | |
return true | |
end | |
function worker:digDown(forceDown) | |
local targetCoords = {} | |
targetCoords.x = self.coords.x | |
targetCoords.y = self.coords.y - 1 | |
targetCoords.z = self.coords.z | |
if forceDown == true or robot.detectDown() then | |
-- Attempt to mind down to bedrock. | |
while self.coords.y > 6 do | |
-- Check if the robot needs charging | |
if computer.energy() <= 10000 then | |
worker:repair() | |
end | |
-- Check if there's any room for additonal blocks. | |
slotCheck = 1 | |
slotSpace = false | |
while slotCheck <= 16 and slotSpace == false do | |
if robot.count(slotCheck) == 0 then | |
slotSpace = true | |
end | |
slotCheck = slotCheck + 1 | |
end | |
-- No space so do the repair action | |
if slotSpace == false then | |
worker:repair() | |
-- Go back to previous place and force a dig | |
local moveCoords = { coords = { x = targetCoords.x, y = targetCoords.y + 1, z = targetCoords.z } } | |
worker:moveto(moveCoords) | |
worker:digDown(true) | |
return false | |
end | |
if robot.down() then | |
self.coords.y = self.coords.y - 1 | |
end | |
if robot.detectDown() then | |
if robot.swingDown() then | |
-- Continue mining | |
else | |
worker:repair() | |
-- Go back to previous place and force a dig | |
local moveCoords = { coords = { x = targetCoords.x, y = targetCoords.y + 1, z = targetCoords.z } } | |
worker:moveto(moveCoords) | |
worker:digDown(true) | |
return false | |
end | |
end | |
end | |
end | |
tmpCoordsString = string.format("%i,%i,%i", targetCoords.x, targetCoords.y, targetCoords.z) | |
if (type(circleCoords[tmpCoordsString].type) ~= "nil") then | |
circleCoords[tmpCoordsString].type = completeType | |
end | |
return true | |
end | |
saveCircle() | |
-- Process the circle with the robot. | |
local processingCircle = true | |
while processingCircle == true do | |
local closestCoord = { coords = { x = 0, y = 0, z = 0 }, distance = -1 } | |
-- Find the nearest point. | |
for coordString,coordData in pairs(circleCoords) do | |
local tmpDistance = math.sqrt( | |
(worker.coords.x - coordData.coords.x)^2 + | |
(worker.coords.y - coordData.coords.y)^2 + | |
(worker.coords.z - coordData.coords.z)^2 | |
) | |
if (closestCoord.distance == -1 or tmpDistance < closestCoord.distance) and coordData.type == circleBorderType then | |
closestCoord.coords.x = coordData.coords.x | |
closestCoord.coords.y = coordData.coords.y + 1 | |
closestCoord.coords.z = coordData.coords.z | |
closestCoord.distance = tmpDistance | |
end | |
end | |
print(string.format("Moving to %i, %i, %i (%f)", closestCoord.coords.x, closestCoord.coords.y, closestCoord.coords.z, closestCoord.distance)) | |
if worker:moveto(closestCoord) then | |
worker:digDown(false) | |
else | |
print(string.format(" Failed to move to %i, %i, %i (%f)", closestCoord.coords.x, closestCoord.coords.y, closestCoord.coords.z, closestCoord.distance)) | |
end | |
if closestCoord.distance == -1 then | |
processingCircle = false | |
end | |
saveCircle() | |
if keyboard.isKeyDown(keyboard.keys.w) and keyboard.isControlDown() then | |
os.exit() | |
end | |
end | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment