feat!: persist miner state

This commit is contained in:
Guillaume ARM 2024-05-11 14:56:15 +02:00
parent 3d9a1b9b94
commit bedd5adbcb

116
miner.lua
View File

@ -4,8 +4,6 @@ local config = require('config-miner')
local LOWER_SIZE_LIMIT = 2;
local HIGHER_SIZE_LIMIT = 128;
local FUEL_NEEDED_MULTIPLIER = 4
local ADDITIONAL_FUEL_NEEDED = 1024
local INITIAL_TARGET_Y = config.targetY - config.startY
local TARGET_Z = config.size - 1
@ -15,18 +13,60 @@ local MAX_X = TARGET_X
local MAX_Y = INITIAL_TARGET_Y + (config.height - 1)
local MAX_Z = TARGET_Z
local robot = robotApi.create()
local MIN_PERCENTAGE_NEEDED = 10
local miner = {
robot = robot,
robot = robotApi.create(),
mission = 'unload', -- "unload" | "refuel" | "mine" | "return-home" | "return-mine" | nil
finished = false,
lastPositionState = nil, -- { x, y, z, dir }
targetY = INITIAL_TARGET_Y
}
local function saveMinerState()
local minerState = {
robotState = miner.robot.getState(),
mission = miner.mission,
finished = miner.finished,
lastPositionState = miner.lastPositionState,
targetY = miner.targetY
}
local file = fs.open('.minerstate', 'w')
if not file then
error('saveMinerState: cannot open .minerstate file!')
end
file.write(textutils.serialize(minerState))
file.close()
end
local function loadMinerState()
local file = fs.open('.minerstate', 'r')
if not file then
return
end
local serializedMinerState = file.readAll()
file.close()
local minerState = unserialize(serializedMinerState)
miner = {
robot = robotApi.create(minerState.robotState),
mission = minerState.mission,
finished = minerState.finished,
lastPositionState = minerState.lastPositionState,
targetY = minerState.targetY
}
end
local function cleanupMinerState()
fs.delete('.minerstate')
end
local function isOdd(x)
return (x % 2) == 1
end
@ -43,6 +83,30 @@ local function robotForceForward()
return miner.robot.forward()
end
local function robotForceDown()
local ok = miner.robot.down()
if ok then
return ok
end
turtle.digDown()
return miner.robot.down()
end
local function robotForceUp()
local ok = miner.robot.up()
if ok then
return ok
end
turtle.digUp()
return miner.robot.up()
end
local function checkConfig()
if config.targetY >= config.startY then
error('targetY should be lower than startY')
@ -65,8 +129,16 @@ local function checkConfig()
end
end
local function prepareTurtle()
local function minerStarted()
checkConfig()
turtle.select(1)
loadMinerState()
print("> Miner program started, minimum percentgae fuel needed: " .. MIN_PERCENTAGE_NEEDED)
end
local function minerFinished()
cleanupMinerState()
print("> Miner program finished!")
end
local function isProgramFinished()
@ -119,11 +191,11 @@ local function returnMineProcedure()
return
end
if robot.lastPositionState then
if miner.robot.lastPositionState then
local robotState = miner.robot.getState()
if robotState.y > miner.lastPositionState.y then
miner.robot.down()
robotForceDown()
elseif robotState.z < miner.lastPositionState.z then
robotForceForward()
else
@ -131,10 +203,12 @@ local function returnMineProcedure()
for i=1, miner.lastPositionState.x, 1 do
robotForceForward()
saveMinerState()
end
while miner.robot.getState().dir ~= miner.lastPositionState.dir do
miner.robot.turnRight()
saveMinerState()
end
miner.mission = 'mine'
@ -144,6 +218,8 @@ local function returnMineProcedure()
miner.mission = 'mine'
print('> Starting mining procedure...')
end
saveMinerState()
end
local function mineProcedure()
@ -154,7 +230,7 @@ local function mineProcedure()
-- 1. Move
if robotState.y > targetY then
turtle.digDown()
miner.robot.down()
robotForceDown()
elseif robotState.dir == 'FORWARD' and robotState.z < targetZ then
turtleUtils.digAll()
robotForceForward()
@ -185,11 +261,12 @@ local function mineProcedure()
for i=1, config.size - 1, 1 do
robotForceForward()
saveMinerState()
end
miner.robot.turnRight()
-- mine the next stage
miner.robot.up()
robotForceUp()
miner.targetY = miner.targetY + 1
end
@ -197,7 +274,13 @@ local function mineProcedure()
print('> Starting return home procedure because inventory is almost full...')
miner.mission = 'return-home'
miner.lastPositionState = miner.robot.getState()
elseif turtleUtils.getFuelPercentage() <= 1 then
print('> Starting return home procedure because there is less than 1% of fuel...')
miner.mission = 'return-home'
miner.lastPositionState = miner.robot.getState()
end
saveMinerState()
end
local function returnHomeProcedure()
@ -210,7 +293,7 @@ local function returnHomeProcedure()
miner.robot.turnRight()
end
miner.robot.up()
robotForceUp()
elseif robotState.x > 0 then
if robotState.dir == 'FORWARD' then
miner.robot.turnLeft()
@ -220,6 +303,7 @@ local function returnHomeProcedure()
for i=1, robotState.x, 1 do
robotForceForward()
saveMinerState()
end
miner.robot.turnLeft()
@ -231,13 +315,11 @@ local function returnHomeProcedure()
miner.robot.turnLeft()
miner.robot.turnLeft()
end
saveMinerState()
end
checkConfig()
prepareTurtle()
print("> Miner program started, minimum percentgae fuel needed: " .. MIN_PERCENTAGE_NEEDED)
minerStarted()
while not isProgramFinished() do
if miner.mission == 'unload' then
@ -253,4 +335,4 @@ while not isProgramFinished() do
end
end
print("> Miner program finished!")
minerFinished()