chore: save
This commit is contained in:
commit
fd40a52ddc
241
miner.lua
Normal file
241
miner.lua
Normal file
@ -0,0 +1,241 @@
|
|||||||
|
local robotApi = require('robot')
|
||||||
|
local turtleUtils = require('turtle-utils')
|
||||||
|
|
||||||
|
local config = {
|
||||||
|
startY = 109,
|
||||||
|
targetY = 109,
|
||||||
|
height = 1,
|
||||||
|
size = 4
|
||||||
|
}
|
||||||
|
|
||||||
|
local TARGET_Y = config.targetY - config.startY
|
||||||
|
local TARGET_Z = config.size - 1
|
||||||
|
local TARGET_X = config.size - 1
|
||||||
|
|
||||||
|
local MAX_X = TARGET_X
|
||||||
|
local MAX_Y = TARGET_Y + (config.height - 1)
|
||||||
|
local MAX_Z = TARGET_Z
|
||||||
|
|
||||||
|
local LOWER_LIMIT = 2;
|
||||||
|
local HIGHER_LIMIT = 128;
|
||||||
|
|
||||||
|
local robot = robotApi.create()
|
||||||
|
|
||||||
|
local MAX_INVENTORY_BLOCKS = 16 * 64
|
||||||
|
local ADDITIONAL_FUEL_NEEDED = 512
|
||||||
|
local MIN_FUEL_NEEDED = (size * 2) + TARGET_Y + MAX_INVENTORY_BLOCKS + ADDITIONAL_FUEL_NEEDED
|
||||||
|
|
||||||
|
local miner = {
|
||||||
|
robot = robot,
|
||||||
|
mission = 'unload', -- "unload" | "refuel" | "mine" | "return-home" | "return-mine" | nil
|
||||||
|
finished = false
|
||||||
|
lastPositionState = nil -- { x, y, z, dir }
|
||||||
|
}
|
||||||
|
|
||||||
|
local function isOdd(x)
|
||||||
|
return (x % 2) == 1
|
||||||
|
end
|
||||||
|
|
||||||
|
local function checkConfig()
|
||||||
|
if config.targetY > config.startY then
|
||||||
|
error('targetY cannot be higher that startY')
|
||||||
|
end
|
||||||
|
|
||||||
|
if config.height < 1 then
|
||||||
|
error('height cannot be lower than 1')
|
||||||
|
end
|
||||||
|
|
||||||
|
if config.size < LOWER_LIMIT then
|
||||||
|
error('size cannot be lower than ' .. LOWER_LIMIT)
|
||||||
|
end
|
||||||
|
|
||||||
|
if config.size > HIGHER_LIMIT then
|
||||||
|
error('size is too large (higher limit is ' .. HIGHER_LIMIT .. ')')
|
||||||
|
end
|
||||||
|
|
||||||
|
if isOdd(config.size) then
|
||||||
|
error('configured size should be even')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function prepareTurtle()
|
||||||
|
turtle.select(1)
|
||||||
|
end
|
||||||
|
|
||||||
|
local function isProgramFinished()
|
||||||
|
if miner.mission ~= nil then
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
local robotState = miner.robot.getSate()
|
||||||
|
|
||||||
|
return robotState.x == 0 and robotState.y == 0 and robotState.z == 0
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
local function unloadProcedure()
|
||||||
|
print('> Starting unload procedure...')
|
||||||
|
turtleUtils.waitForInventory('front')
|
||||||
|
|
||||||
|
for i=1, 16, 1 do
|
||||||
|
turtle.select(i)
|
||||||
|
turtleUtils.tryDrop()
|
||||||
|
end
|
||||||
|
|
||||||
|
turtle.select(1)
|
||||||
|
|
||||||
|
miner.mission = 'refuel'
|
||||||
|
end
|
||||||
|
|
||||||
|
local function refuelProcedure()
|
||||||
|
print('> Starting refuel procedure (' .. turtleUtils.getFuelPercentage() .. '%)')
|
||||||
|
turtleUtils.waitForInventory('top')
|
||||||
|
|
||||||
|
turtle.select(1)
|
||||||
|
|
||||||
|
while turtle.getFuelLevel() < MIN_FUEL_NEEDED do
|
||||||
|
turtleUtils.trySuckUp()
|
||||||
|
|
||||||
|
local ok = turtle.refuel()
|
||||||
|
if not ok then
|
||||||
|
turtleUtils.tryDrop()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
print('> Refuel done.')
|
||||||
|
miner.mission = 'return-mine'
|
||||||
|
end
|
||||||
|
|
||||||
|
local function returnMineProcedure()
|
||||||
|
if miner.robot.finished then
|
||||||
|
miner.mission = nil -- it will stop the loop
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
if robot.lastPositionState then
|
||||||
|
local robotState = miner.robot.getState()
|
||||||
|
|
||||||
|
if robotState.y > miner.lastPositionState.y then
|
||||||
|
miner.robot.down()
|
||||||
|
elseif robotState.z < miner.lastPositionState.z then
|
||||||
|
miner.robot.forward()
|
||||||
|
else
|
||||||
|
miner.robot.turnRight()
|
||||||
|
|
||||||
|
for i=1, miner.lastPositionState.x, 1 do
|
||||||
|
miner.robot.forward()
|
||||||
|
end
|
||||||
|
|
||||||
|
while miner.robot.getState().dir ~= miner.lastPositionState.dir do
|
||||||
|
miner.robot.turnRight()
|
||||||
|
end
|
||||||
|
|
||||||
|
miner.mission = 'mine'
|
||||||
|
end
|
||||||
|
else
|
||||||
|
miner.mission = 'mine'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function mineProcedure()
|
||||||
|
print('> Starting mine procedure...')
|
||||||
|
local robotState = miner.robot.getState()
|
||||||
|
local targetY = TARGET_Y
|
||||||
|
local targetZ = TARGET_Z
|
||||||
|
|
||||||
|
-- 1. Move
|
||||||
|
if robotState.y > targetY then
|
||||||
|
turtle.digDown()
|
||||||
|
miner.robot.down()
|
||||||
|
elseif robotState.dir == 'FORWARD' and robotState.z < targetZ then
|
||||||
|
turtleUtils.digAll()
|
||||||
|
miner.robot.forward()
|
||||||
|
elseif robotState.dir == 'FORWARD' and robotState.z == targetZ then
|
||||||
|
miner.robot.turnRight()
|
||||||
|
turtleUtils.digAll()
|
||||||
|
miner.robot.forward()
|
||||||
|
miner.robot.turnRight()
|
||||||
|
elseif robotState.dir == 'BACKWARD' and robotState.z > 0 then
|
||||||
|
turtleUtils.digAll()
|
||||||
|
miner.robot.forward()
|
||||||
|
elseif robotState.dir == 'BACKWARD' and robotState.z == 0 then
|
||||||
|
miner.robot.turnLeft()
|
||||||
|
turtleUtils.digAll()
|
||||||
|
miner.robot.forward()
|
||||||
|
miner.robot.turnLeft()
|
||||||
|
end
|
||||||
|
|
||||||
|
-- 2. Check
|
||||||
|
if robotState.x == MAX_X and robotState.y == MAX_Y and robotState.z == MAX_Z then
|
||||||
|
miner.finished = true
|
||||||
|
miner.mission = 'return-home'
|
||||||
|
miner.lastPositionState = miner.robot.getState()
|
||||||
|
elseif robotState.x == MAX_X and robotState.z == MAX_Z then
|
||||||
|
-- this part assume that the size of the mine is even
|
||||||
|
miner.robot.turnRight()
|
||||||
|
|
||||||
|
for i=1, config.size - 1, 1 do
|
||||||
|
miner.robot.forward()
|
||||||
|
end
|
||||||
|
|
||||||
|
miner.robot.turnRight()
|
||||||
|
miner.robot.up()
|
||||||
|
end
|
||||||
|
|
||||||
|
if turtleUtils.countFreeSlots() < 1 then
|
||||||
|
miner.mission = 'return-home'
|
||||||
|
miner.lastPositionState = miner.robot.getState()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function returnHomeProcedure()
|
||||||
|
print('> Starting return home procedure...')
|
||||||
|
local robotState = miner.robot.getState()
|
||||||
|
|
||||||
|
if robotState.x == 0 and robotState.y == 0 and robotState.z == 0 then
|
||||||
|
miner.mission = 'unload'
|
||||||
|
elseif robotState.x == 0 and robotState.z == 0 then
|
||||||
|
miner.robot.up()
|
||||||
|
elseif robotState.x > 0 then
|
||||||
|
if robotState.dir == 'FORWARD' then
|
||||||
|
miner.robot.turnLeft()
|
||||||
|
elseif robotState.dir == 'BACKWARD' then
|
||||||
|
miner.robot.turnRight()
|
||||||
|
end
|
||||||
|
|
||||||
|
for i=1, robotState.x, 1 do
|
||||||
|
miner.robot.forward()
|
||||||
|
end
|
||||||
|
|
||||||
|
miner.robot.turnLeft()
|
||||||
|
elseif robotState.z > 0 then
|
||||||
|
for i=1, robotState.z, 1 do
|
||||||
|
miner.robot.forward()
|
||||||
|
end
|
||||||
|
|
||||||
|
miner.robot.turnLeft()
|
||||||
|
miner.robot.turnLeft()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
checkConfig()
|
||||||
|
prepareTurtle()
|
||||||
|
|
||||||
|
print("> Miner program started, minimum fuel needed: " .. MIN_FUEL_NEEDED)
|
||||||
|
|
||||||
|
while not isProgramFinished() do
|
||||||
|
if miner.mission == 'unload' then
|
||||||
|
unloadProcedure()
|
||||||
|
elseif miner.mission == 'refuel' then
|
||||||
|
refuelProcedure()
|
||||||
|
elseif miner.mission == 'mine' then
|
||||||
|
mineProcedure()
|
||||||
|
elseif miner.mission == 'return-home' then
|
||||||
|
returnHomeProcedure()
|
||||||
|
elseif miner.mission == 'return-mine' then
|
||||||
|
returnMineProcedure()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
print("> Miner program finished!")
|
||||||
114
robot.lua
Normal file
114
robot.lua
Normal file
@ -0,0 +1,114 @@
|
|||||||
|
-- robot api
|
||||||
|
|
||||||
|
local api = {}
|
||||||
|
|
||||||
|
api.create = function()
|
||||||
|
local state = {
|
||||||
|
y = 0,
|
||||||
|
x = 0,
|
||||||
|
z = 0,
|
||||||
|
-- | BACKWARD | LEFT | RIGHT
|
||||||
|
dir = 'FORWARD'
|
||||||
|
}
|
||||||
|
|
||||||
|
local mutateRobotPosition = function(isBackward)
|
||||||
|
local incValue = 1
|
||||||
|
if isBackward then invValue = -1 end
|
||||||
|
|
||||||
|
if dir == 'FORWARD' then
|
||||||
|
state.z = state.z + incValue
|
||||||
|
elseif dir == 'BACKWARD' then
|
||||||
|
state.z = state.z - incValue
|
||||||
|
elseif dir == 'LEFT' then
|
||||||
|
state.x = state.x - incValue
|
||||||
|
elseif dir == 'RIGHT' then
|
||||||
|
state.x = state.x + incValue
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local robot = {}
|
||||||
|
|
||||||
|
robot.forward = function()
|
||||||
|
local ok, err = turtle.forward()
|
||||||
|
|
||||||
|
if ok then
|
||||||
|
mutateRobotPosition(false)
|
||||||
|
end
|
||||||
|
|
||||||
|
return ok, err
|
||||||
|
end
|
||||||
|
|
||||||
|
robot.backward = function()
|
||||||
|
local ok, err = turtle.back()
|
||||||
|
|
||||||
|
if ok then
|
||||||
|
mutateRobotPosition(true)
|
||||||
|
end
|
||||||
|
|
||||||
|
return ok, err
|
||||||
|
end
|
||||||
|
|
||||||
|
robot.up = function()
|
||||||
|
local ok, err = turtle.up()
|
||||||
|
|
||||||
|
if ok then
|
||||||
|
state.y = state.y + 1
|
||||||
|
end
|
||||||
|
|
||||||
|
return ok, err
|
||||||
|
end
|
||||||
|
|
||||||
|
robot.down = function()
|
||||||
|
local ok, err = turtle.down()
|
||||||
|
|
||||||
|
if ok then
|
||||||
|
state.y = state.y - 1
|
||||||
|
end
|
||||||
|
|
||||||
|
return ok, err
|
||||||
|
end
|
||||||
|
|
||||||
|
robot.turnLeft = function()
|
||||||
|
local ok, err = turtle.turnLeft()
|
||||||
|
|
||||||
|
if ok then
|
||||||
|
if state.dir == 'FORWARD' then
|
||||||
|
state.dir = 'LEFT'
|
||||||
|
elseif state.dir == 'LEFT' then
|
||||||
|
state.dir = 'BACKWARD'
|
||||||
|
elseif state.dir == 'RIGHT' then
|
||||||
|
state.dir = 'FORWARD'
|
||||||
|
elseif state.dir == 'BACKWARD' then
|
||||||
|
state.dir = 'RIGHT'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return ok, err
|
||||||
|
end
|
||||||
|
|
||||||
|
robot.turnRight = function()
|
||||||
|
local ok, err = turtle.turnRight()
|
||||||
|
|
||||||
|
if ok then
|
||||||
|
if state.dir == 'FORWARD' then
|
||||||
|
state.dir = 'RIGHT'
|
||||||
|
elseif state.dir == 'LEFT' then
|
||||||
|
state.dir = 'FORWARD'
|
||||||
|
elseif state.dir == 'RIGHT' then
|
||||||
|
state.dir = 'BACKWARD'
|
||||||
|
elseif state.dir == 'BACKWARD' then
|
||||||
|
state.dir = 'LEFT'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return ok, err
|
||||||
|
end
|
||||||
|
|
||||||
|
robot.getState = function()
|
||||||
|
return state
|
||||||
|
end
|
||||||
|
|
||||||
|
return robot
|
||||||
|
end
|
||||||
|
|
||||||
|
return api
|
||||||
53
turtle-utils.lua
Normal file
53
turtle-utils.lua
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
local turtleUtils = {}
|
||||||
|
|
||||||
|
local IDLE_TIME = 2
|
||||||
|
|
||||||
|
turtleUtils.waitForInventory = function(side)
|
||||||
|
local inv = nil
|
||||||
|
|
||||||
|
while true do
|
||||||
|
inv = peripheral.wrap(side)
|
||||||
|
|
||||||
|
if inv and peripheral.hasType(inv, 'inventory') then
|
||||||
|
break
|
||||||
|
end
|
||||||
|
|
||||||
|
os.sleep(IDLE_TIME)
|
||||||
|
end
|
||||||
|
|
||||||
|
return inv
|
||||||
|
end
|
||||||
|
|
||||||
|
turtleUtils.trySuckUp = function()
|
||||||
|
while not turtle.suckUp() do
|
||||||
|
os.sleep(IDLE_TIME)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
turtleUtils.tryDrop = function()
|
||||||
|
while not turtle.drop() do
|
||||||
|
os.sleep(IDLE_TIME)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
turtleUtils.digAll = function()
|
||||||
|
while turtle.dig() do end
|
||||||
|
end
|
||||||
|
|
||||||
|
turtleUtils.countFreeSlots = function()
|
||||||
|
local freeSlots = 0
|
||||||
|
|
||||||
|
for i=1, 16, 1 do
|
||||||
|
if turtle.getItemCount(i) == 0 then
|
||||||
|
freeSlots = freeSlots + 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return freeSlots
|
||||||
|
end
|
||||||
|
|
||||||
|
turtleUtils.getFuelPercentage = function()
|
||||||
|
return (turtle.getFuelLevel() / turtle.getFuelLimit()) * 100
|
||||||
|
end
|
||||||
|
|
||||||
|
return turtleUtils
|
||||||
Loading…
Reference in New Issue
Block a user