Advertisement
Friendsincode

Robot Program (Minerobot)

Mar 21st, 2025 (edited)
354
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 10.84 KB | None | 0 0
  1. --------------------------------------------------------------------------------
  2. -- Mining Robot with Remote Commands and Configuration
  3. --
  4. -- On startup, the turtle (named "Minerobot <ID>") connects to rednet and waits
  5. -- for configuration from the handheld. The configuration sets the mine size
  6. -- (width and height) and the turtle’s starting facing direction.
  7. --
  8. -- After configuration, the turtle responds to these remote commands:
  9. --   "stats" - Sends its current coordinates.
  10. --   "start" - Begins mining with the configured parameters.
  11. --   "stop"  - Stops mining after finishing the current layer.
  12. --   "home"  - Returns to the starting position.
  13. --   "config:<width>:<height>:<facing>" - Updates configuration.
  14. --
  15. -- ASSUMPTIONS:
  16. --   - Starting position is (0,0,0).
  17. --   - A chest is behind the starting point.
  18. --   - Wireless modem attached on side "back" (adjust if needed).
  19. --------------------------------------------------------------------------------
  20.  
  21. -- CONFIGURATION defaults (will be updated via remote command)
  22. local areaWidth = 16
  23. local areaHeight = 16
  24. local startFacing = 0  -- 0=East, 1=South, 2=West, 3=North
  25.  
  26. local sleepTime = 0.1
  27.  
  28. -- Position and orientation tracking (starting at (0,0,0))
  29. local posX, posY, posZ = 0, 0, 0
  30. local facing = startFacing  -- will be updated with config
  31.  
  32. local startX, startY, startZ = 0, 0, 0
  33.  
  34. -- Control flags
  35. local miningActive = false
  36. local stopMining = false
  37.  
  38. -- Modem configuration
  39. local modemSide = "left"
  40. if not rednet.isOpen(modemSide) then
  41.   rednet.open(modemSide)
  42. end
  43.  
  44. local robotName = "Minerobot " .. os.getComputerID()
  45. rednet.broadcast("checkin:" .. robotName, "control")
  46. print("Checked in as " .. robotName)
  47. print("Waiting for configuration...")
  48.  
  49. --------------------------------------------------------------------------------
  50. -- INVENTORY & FUEL FUNCTIONS
  51. --------------------------------------------------------------------------------
  52. local function inventoryFull()
  53.   for slot = 1, 14 do
  54.     if turtle.getItemCount(slot) == 0 then
  55.       return false
  56.     end
  57.   end
  58.   return true
  59. end
  60.  
  61. local function dumpInventory()
  62.   for slot = 1, 14 do
  63.     turtle.select(slot)
  64.     turtle.drop()
  65.   end
  66.   turtle.select(1)
  67. end
  68.  
  69. local function ensureFuel()
  70.   if turtle.getFuelLevel() == "unlimited" then return end
  71.   local threshold = 10
  72.   if turtle.getFuelLevel() < threshold then
  73.     print("Low fuel (" .. turtle.getFuelLevel() .. "). Refueling...")
  74.     for slot = 1, 16 do
  75.       turtle.select(slot)
  76.       turtle.refuel(1)
  77.       if turtle.getFuelLevel() >= threshold then break end
  78.     end
  79.     if turtle.getFuelLevel() < threshold then
  80.       error("Not enough fuel. Please add more fuel and restart.")
  81.     end
  82.   end
  83. end
  84.  
  85. --------------------------------------------------------------------------------
  86. -- TURNING & FACING FUNCTIONS
  87. --------------------------------------------------------------------------------
  88. local function turnLeft()
  89.   turtle.turnLeft()
  90.   facing = (facing + 3) % 4
  91. end
  92.  
  93. local function turnRight()
  94.   turtle.turnRight()
  95.   facing = (facing + 1) % 4
  96. end
  97.  
  98. local function turnAround()
  99.   turtle.turnLeft()
  100.   turtle.turnLeft()
  101.   facing = (facing + 2) % 4
  102. end
  103.  
  104. local function faceDirection(dir)
  105.   local diff = (dir - facing) % 4
  106.   if diff == 1 then
  107.     turnRight()
  108.   elseif diff == 2 then
  109.     turnAround()
  110.   elseif diff == 3 then
  111.     turnLeft()
  112.   end
  113. end
  114.  
  115. --------------------------------------------------------------------------------
  116. -- MOVEMENT FUNCTIONS
  117. --------------------------------------------------------------------------------
  118. local function mineForwardStep()
  119.   if inventoryFull() then
  120.     return false
  121.   end
  122.   ensureFuel()
  123.   turtle.dig()
  124.   while not turtle.forward() do
  125.     if turtle.detect() then turtle.dig() end
  126.     sleep(sleepTime)
  127.   end
  128.   if facing == 0 then
  129.     posX = posX + 1
  130.   elseif facing == 1 then
  131.     posZ = posZ + 1
  132.   elseif facing == 2 then
  133.     posX = posX - 1
  134.   elseif facing == 3 then
  135.     posZ = posZ - 1
  136.   end
  137.   turtle.digUp()
  138.   turtle.digDown()
  139.   return true
  140. end
  141.  
  142. local function moveForwardNoDump()
  143.   ensureFuel()
  144.   turtle.dig()
  145.   while not turtle.forward() do
  146.     if turtle.detect() then turtle.dig() end
  147.     sleep(sleepTime)
  148.   end
  149.   if facing == 0 then
  150.     posX = posX + 1
  151.   elseif facing == 1 then
  152.     posZ = posZ + 1
  153.   elseif facing == 2 then
  154.     posX = posX - 1
  155.   elseif facing == 3 then
  156.     posZ = posZ - 1
  157.   end
  158. end
  159.  
  160. local function moveUpNoDump()
  161.   ensureFuel()
  162.   turtle.digUp()
  163.   while not turtle.up() do
  164.     turtle.digUp()
  165.     sleep(sleepTime)
  166.   end
  167.   posY = posY + 1
  168. end
  169.  
  170. local function moveDownNoDump()
  171.   ensureFuel()
  172.   turtle.digDown()
  173.   while not turtle.down() do
  174.     turtle.digDown()
  175.     sleep(sleepTime)
  176.   end
  177.   posY = posY - 1
  178. end
  179.  
  180. --------------------------------------------------------------------------------
  181. -- 3D NAVIGATION FUNCTION
  182. --------------------------------------------------------------------------------
  183. local function navigateTo3DNoDump(tx, ty, tz)
  184.   while posY < ty do
  185.     moveUpNoDump()
  186.   end
  187.   while posY > ty do
  188.     moveDownNoDump()
  189.   end
  190.   if posX < tx then
  191.     faceDirection(0)
  192.     while posX < tx do
  193.       moveForwardNoDump()
  194.     end
  195.   elseif posX > tx then
  196.     faceDirection(2)
  197.     while posX > tx do
  198.       moveForwardNoDump()
  199.     end
  200.   end
  201.   if posZ < tz then
  202.     faceDirection(1)
  203.     while posZ < tz do
  204.       moveForwardNoDump()
  205.     end
  206.   elseif posZ > tz then
  207.     faceDirection(3)
  208.     while posZ > tz do
  209.       moveForwardNoDump()
  210.     end
  211.   end
  212. end
  213.  
  214. --------------------------------------------------------------------------------
  215. -- DUMP INVENTORY ROUTINE
  216. --------------------------------------------------------------------------------
  217. local function manageInventoryDump()
  218.   local savedX, savedY, savedZ = posX, posY, posZ
  219.   local savedFacing = facing
  220.   print("Inventory full. Going to dump...")
  221.   navigateTo3DNoDump(startX, startY, startZ)
  222.   faceDirection(2)  -- face the chest
  223.   dumpInventory()
  224.   faceDirection(0)
  225.   print("Dump complete. Returning to mining spot...")
  226.   navigateTo3DNoDump(savedX, savedY, savedZ)
  227.   faceDirection(savedFacing)
  228. end
  229.  
  230. --------------------------------------------------------------------------------
  231. -- DESCEND TO NEXT LAYER FUNCTION
  232. --------------------------------------------------------------------------------
  233. local function descendToNextLayer()
  234.   navigateTo3DNoDump(startX, posY, startZ)
  235.   for i = 1, 3 do
  236.     turtle.digDown()
  237.     while not turtle.down() do
  238.       turtle.digDown()
  239.       sleep(sleepTime)
  240.     end
  241.     posY = posY - 1
  242.   end
  243.   return true
  244. end
  245.  
  246. --------------------------------------------------------------------------------
  247. -- MINE ONE LAYER (Serpentine based on configured areaWidth and areaHeight)
  248. --------------------------------------------------------------------------------
  249. local function mineLayer()
  250.   for row = 0, areaHeight - 1 do
  251.     if row % 2 == 0 then
  252.       faceDirection( (startFacing + 0) % 4 )  -- use starting direction for even rows
  253.       for i = 1, areaWidth - 1 do
  254.         if not mineForwardStep() then
  255.           manageInventoryDump()
  256.           mineForwardStep()
  257.         end
  258.       end
  259.     else
  260.       faceDirection( (startFacing + 2) % 4 )  -- opposite direction for odd rows
  261.       for i = 1, areaWidth - 1 do
  262.         if not mineForwardStep() then
  263.           manageInventoryDump()
  264.           mineForwardStep()
  265.         end
  266.       end
  267.     end
  268.     if row < areaHeight - 1 then
  269.       faceDirection( (startFacing + 1) % 4 )  -- move to next row (assumes southward shift)
  270.       if not mineForwardStep() then
  271.         manageInventoryDump()
  272.         mineForwardStep()
  273.       end
  274.     end
  275.   end
  276.   navigateTo3DNoDump(0, posY, 0)
  277.   faceDirection(startFacing)
  278. end
  279.  
  280. --------------------------------------------------------------------------------
  281. -- MINING LOOP
  282. --------------------------------------------------------------------------------
  283. local function miningLoop()
  284.   print("Mining started.")
  285.   while miningActive and not stopMining do
  286.     mineLayer()
  287.     local success, data = turtle.inspectDown()
  288.     if success and data.name == "minecraft:bedrock" then
  289.       print("Bedrock below. Stopping mining.")
  290.       miningActive = false
  291.       break
  292.     end
  293.     print("Layer complete. Descending...")
  294.     if not descendToNextLayer() then
  295.       print("Cannot descend further. Stopping mining.")
  296.       miningActive = false
  297.       break
  298.     end
  299.     sleep(0.1)  -- yield frequently
  300.   end
  301.   print("Mining stopped.")
  302. end
  303.  
  304. --------------------------------------------------------------------------------
  305. -- RETURN HOME FUNCTION
  306. --------------------------------------------------------------------------------
  307. local function returnHome()
  308.   print("Returning home...")
  309.   navigateTo3DNoDump(startX, startY, startZ)
  310.   faceDirection(startFacing)
  311.   print("Home reached.")
  312. end
  313.  
  314. --------------------------------------------------------------------------------
  315. -- REMOTE COMMAND LISTENER (Improved Responsiveness)
  316. --------------------------------------------------------------------------------
  317. local function remoteListener()
  318.   while true do
  319.     local sender, message, protocol = rednet.receive(nil, 0.5)
  320.     if message then
  321.       if message == "stats" then
  322.         local statusMsg = "Position: (" .. posX .. ", " .. posY .. ", " .. posZ .. ")"
  323.         rednet.send(sender, statusMsg)
  324.         print("Sent stats to " .. sender)
  325.       elseif message == "start" then
  326.         if not miningActive then
  327.           miningActive = true
  328.           stopMining = false
  329.           print("Received START command.")
  330.           parallel.spawn(miningLoop)
  331.         end
  332.       elseif message == "stop" then
  333.         if miningActive then
  334.           stopMining = true
  335.           miningActive = false
  336.           print("Received STOP command.")
  337.         end
  338.       elseif message == "home" then
  339.         stopMining = true
  340.         miningActive = false
  341.         print("Received HOME command.")
  342.         returnHome()
  343.       elseif message:sub(1,7) == "config:" then
  344.         local width, height, face = message:match("config:(%d+):(%d+):(%d+)")
  345.         if width and height and face then
  346.           areaWidth = tonumber(width)
  347.           areaHeight = tonumber(height)
  348.           startFacing = tonumber(face)
  349.           facing = startFacing
  350.           print("Configured: mine size " .. areaWidth .. "x" .. areaHeight ..
  351.                 " and starting facing " .. startFacing)
  352.           rednet.send(sender, "configured")
  353.         else
  354.           rednet.send(sender, "config error")
  355.         end
  356.       end
  357.     end
  358.     sleep(0.1)
  359.   end
  360. end
  361.  
  362. --------------------------------------------------------------------------------
  363. -- MAIN: Run remoteListener in parallel (ensuring responsiveness)
  364. --------------------------------------------------------------------------------
  365. parallel.waitForAny(remoteListener, function() while true do sleep(0.1) end end)
  366.  
  367. if rednet.isOpen(modemSide) then
  368.   rednet.close(modemSide)
  369. end
  370.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement