From 5334ea824195247d5bc4e63587545637f1c49e4e Mon Sep 17 00:00:00 2001 From: Christoph Date: Sun, 5 Oct 2025 21:44:01 +0200 Subject: [PATCH] Improve turning logic in TurtleController and add edgecases in MoveToPosition when at the front/back of the mining area --- controller/turtle_controller.lua | 75 +++++++++++++++++++------------- 1 file changed, 45 insertions(+), 30 deletions(-) diff --git a/controller/turtle_controller.lua b/controller/turtle_controller.lua index 347794c..6ffc753 100644 --- a/controller/turtle_controller.lua +++ b/controller/turtle_controller.lua @@ -55,16 +55,20 @@ function TurtleController:TurnRelative(number_of_turns) return end - print(("Turtle is turning by %d..."):format(number_of_turns)) - self:RefuelIfEmpty() -- Turn turtle - for _ = 1,math.abs(number_of_turns) do - if number_of_turns > 0 then + local turns = number_of_turns % 4 + if turns == 3 then + print(("Turtle is turning by %d (shortened to %d)..."):format(number_of_turns, -1)) + + -- If we're rotating by 3, we could turn faster by rotating by 1 in the opposite direction + turtle.turnLeft() + else + print(("Turtle is turning by %d (shortened to %d)..."):format(number_of_turns, turns)) + + for _ = 1,turns do turtle.turnRight() - else - turtle.turnLeft() end end @@ -79,17 +83,7 @@ function TurtleController:TurnToDirection(direction) return end - print(("Turtle is turning to direction %d..."):format(direction)) - - self:RefuelIfEmpty() - - local rotation = direction - self.position.dir - if math.abs(rotation) == 3 then - -- If we're rotating by 3, we could turn faster by rotating by 1 in the opposite direction - rotation = -1 * (rotation - 1) - end - - self:TurnRelative(rotation) + self:TurnRelative(direction - self.position.dir) end @@ -133,9 +127,9 @@ function TurtleController:MoveRelative(number_of_blocks) end ----@param x number ----@param y number ----@param z number +---@param x number The EAST/WEST axis (grows from WEST to EAST) +---@param y number The UP/DOWN axis (grows from DOWN to UP) +---@param z number The NORTH/SOUTH axis (grows from SOUTH to NORTH) ---@param dir Direction function TurtleController:MoveToPosition(x, y, z, dir) print(("Turtle is moving to (%d, %d, %d)..."):format(x, y, z)) @@ -143,9 +137,16 @@ function TurtleController:MoveToPosition(x, y, z, dir) self:DisableMining() self.last_positions:Push(Position:Copy(self.position)) - -- Move south once (if possible) to not be blocked by the slice that is currently mined - self:TurnToDirection(Direction.SOUTH) - self:MoveRelative(1) + if self.position.z > 1 then + -- Move south once (if we're at the top) to not be blocked by the slice that is currently mined. + -- This assumes that we mine the full width back to front. + self:TurnToDirection(Direction.SOUTH) + self:MoveRelative(1) + elseif self.position.z == 0 then + -- Move north once (if we're at the bottom) to not be blocked by the chests + self:TurnToDirection(Direction.NORTH) + self:MoveRelative(1) + end -- EAST/WEST axis (do first to not interfere with chests or unmined walls) if self.position.x > x then @@ -176,8 +177,13 @@ end function TurtleController:MoveBack() local target_position = self.last_positions:Pop() - self:MoveToPosition(target_position.x, target_position.y, target_position.z, target_position.dir) - self.last_positions:Pop() + if target_position == nil then + shell.exit() + else + self:MoveToPosition(target_position.x, target_position.y, target_position.z, target_position.dir) + self.last_positions:Pop() + end + end @@ -228,8 +234,10 @@ function TurtleController:DropInventory() end -function TurtleController:UnstockIfFull() - if self:HasInventorySpace() then +---@param skip_inventory_check boolean | nil +function TurtleController:UnstockIfFull(skip_inventory_check) + skip_inventory_check = skip_inventory_check or false + if not skip_inventory_check and self:HasInventorySpace() then return end @@ -243,8 +251,10 @@ function TurtleController:UnstockIfFull() end -function TurtleController:RefuelIfEmpty() - if self:HasFuel() then +---@param skip_fuel_check boolean | nil +function TurtleController:RefuelIfEmpty(skip_fuel_check) + skip_fuel_check = skip_fuel_check or false + if not skip_fuel_check and self:HasFuel() then return end @@ -260,8 +270,13 @@ function TurtleController:RefuelIfEmpty() -- Include the distance to the last position when refueling -- to keep the amount of work done between refuelings constant + local target_fuel_level = self.config.refuel_amount local last_position = self.last_positions:Peek() - local target_fuel_level = self.config.refuel_amount + last_position.x + last_position.y + last_position.z + if last_position == nil then + shell.exit() + else + target_fuel_level = target_fuel_level + last_position.x + last_position.y + last_position.z + end -- Refuel until we hit the refuel_amount local before_level = turtle.getFuelLevel()