From bedd5adbcbde16b2a1043704798c0772a06efe8c Mon Sep 17 00:00:00 2001 From: Guillaume ARM Date: Sat, 11 May 2024 14:56:15 +0200 Subject: [PATCH] feat!: persist miner state --- miner.lua | 116 ++++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 99 insertions(+), 17 deletions(-) diff --git a/miner.lua b/miner.lua index dc1074a..8446e4f 100644 --- a/miner.lua +++ b/miner.lua @@ -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!") \ No newline at end of file +minerFinished() \ No newline at end of file