robathome

RoboMiner_miningTurtle

Oct 18th, 2025 (edited)
571
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 8.11 KB | None | 0 0
  1. -- miner_startup.lua
  2. -- Ultra-dumb miner. Verbose local console + heartbeats.
  3. -- Requires: wireless (ender) modem; label set via: label set miner_alpha
  4.  
  5. local PROTOCOL = "minesys:v1"
  6. local HEARTBEAT_SEC = 2
  7.  
  8. local modem = peripheral.find("modem", function(_, p) return p.isWireless() end)
  9. if not modem then error("No wireless modem") end
  10. if not turtle then error("Run on a turtle") end
  11. rednet.open(peripheral.getName(modem))
  12.  
  13. -- ---------------- console/status ----------------
  14. local state = {
  15. status = "waiting",
  16. extra = nil,
  17. facing = "N",
  18. pos = nil,
  19. fuel = turtle.getFuelLevel(),
  20. lastDraw = 0,
  21. }
  22.  
  23. local function invStats()
  24. local empty = 0
  25. for i=1,16 do if turtle.getItemCount(i)==0 then empty = empty + 1 end end
  26. local pct = (empty/16)*100
  27. return { freeSlots = empty, freePct = pct }
  28. end
  29.  
  30. local function now() return os.epoch("utc") end
  31.  
  32. local function gpsPos()
  33. local x, y, z = gps.locate(1)
  34. if x then state.pos = {x=x,y=y,z=z} end
  35. return x, y, z
  36. end
  37.  
  38. local function setStatus(s, extra)
  39. state.status = s or state.status
  40. state.extra = extra or nil
  41. end
  42.  
  43. local function drawConsole(force)
  44. local t = now()
  45. if not force and (t - state.lastDraw) < 100 then return end -- 0.1s throttle
  46. state.lastDraw = t
  47.  
  48. term.setBackgroundColor(colors.black)
  49. term.setTextColor(colors.white)
  50. term.clear()
  51. term.setCursorPos(1,1)
  52. local lbl = os.getComputerLabel() or ("id"..os.getComputerID())
  53. print(("Miner %s"):format(lbl))
  54. print(("Fuel: %s"):format(tostring(state.fuel)))
  55. local p = state.pos
  56. print(("Pos: %s"):format(p and ("("..p.x..","..p.y..","..p.z..")") or "unknown"))
  57. print(("Facing: %s"):format(state.facing))
  58. print(("Status: %s"):format(state.status))
  59.  
  60. if state.extra then
  61. -- Render compact progress lines
  62. if state.extra.kind=="move" then
  63. print(("- Move %s: %d/%d"):format(state.extra.axis, state.extra.step, state.extra.total))
  64. elseif state.extra.kind=="clear" then
  65. print(("- Clear LxWxH: %d×%d×%d"):format(state.extra.L, state.extra.W, state.extra.H))
  66. print((" Layer: %d/%d Row: %d/%d Step: %d/%d"):format(
  67. state.extra.layer, state.extra.H,
  68. state.extra.row, state.extra.W,
  69. state.extra.step, state.extra.L
  70. ))
  71. elseif state.extra.kind=="face" then
  72. print(("- Face: %s"):format(state.extra.dir))
  73. elseif state.extra.kind=="note" and state.extra.msg then
  74. print(("- Note: %s"):format(state.extra.msg))
  75. end
  76. end
  77. end
  78.  
  79. local function hb()
  80. state.fuel = turtle.getFuelLevel()
  81. gpsPos()
  82. local msg = {
  83. t = now(),
  84. op = "status",
  85. id = os.getComputerID(),
  86. label = os.getComputerLabel(),
  87. pos = state.pos,
  88. fuel = state.fuel,
  89. facing = state.facing,
  90. status = state.status,
  91. extra = state.extra,
  92. inv = invStats(),
  93. }
  94. rednet.broadcast(msg, PROTOCOL)
  95. end
  96.  
  97. local function report(s, extra, forceDraw)
  98. setStatus(s, extra)
  99. drawConsole(forceDraw)
  100. hb()
  101. end
  102.  
  103. -- ---------------- motion primitives ----------------
  104. local DIRS = {N=0, E=1, S=2, W=3}
  105. local dirNames = {"N","E","S","W"}
  106.  
  107. local function setFacing(newDir)
  108. if not DIRS[newDir] then return false, "bad dir" end
  109. if state.facing == newDir then
  110. report("waiting", {kind="face", dir=newDir})
  111. return true
  112. end
  113. local idx = DIRS[state.facing]; local tgt = DIRS[newDir]
  114. local diff = (tgt - idx) % 4
  115. report("waiting", {kind="face", dir=newDir}, true)
  116. if diff == 1 then turtle.turnRight()
  117. elseif diff == 2 then turtle.turnRight(); turtle.turnRight()
  118. elseif diff == 3 then turtle.turnLeft()
  119. end
  120. state.facing = newDir
  121. report("waiting", {kind="face", dir=newDir})
  122. return true
  123. end
  124.  
  125. local function digForward()
  126. while turtle.detect() do
  127. turtle.dig()
  128. sleep(0.15)
  129. end
  130. end
  131.  
  132. local function forward(n)
  133. n = math.max(0, n or 1)
  134. for i=1, n do
  135. report("moving to", {kind="move", axis="fwd", step=i, total=n})
  136. digForward()
  137. local tries=0
  138. while not turtle.forward() do
  139. digForward()
  140. tries=tries+1
  141. if tries>50 then
  142. report("waiting", {kind="note", msg="blocked fwd"})
  143. return false, "blocked"
  144. end
  145. sleep(0.15)
  146. end
  147. end
  148. report("waiting")
  149. return true
  150. end
  151.  
  152. local function up(n)
  153. n = math.max(0, n or 1)
  154. for i=1, n do
  155. report("moving to", {kind="move", axis="up", step=i, total=n})
  156. while turtle.detectUp() do turtle.digUp(); sleep(0.15) end
  157. local tries=0
  158. while not turtle.up() do
  159. while turtle.detectUp() do turtle.digUp(); sleep(0.15) end
  160. tries=tries+1
  161. if tries>50 then
  162. report("waiting", {kind="note", msg="blocked up"})
  163. return false, "blocked"
  164. end
  165. sleep(0.15)
  166. end
  167. end
  168. report("waiting")
  169. return true
  170. end
  171.  
  172. local function down(n)
  173. n = math.max(0, n or 1)
  174. for i=1, n do
  175. report("moving to", {kind="move", axis="down", step=i, total=n})
  176. while turtle.detectDown() do turtle.digDown(); sleep(0.15) end
  177. local tries=0
  178. while not turtle.down() do
  179. while turtle.detectDown() do turtle.digDown(); sleep(0.15) end
  180. tries=tries+1
  181. if tries>50 then
  182. report("waiting", {kind="note", msg="blocked down"})
  183. return false, "blocked"
  184. end
  185. sleep(0.15)
  186. end
  187. end
  188. report("waiting")
  189. return true
  190. end
  191.  
  192. -- ---------------- clear area ----------------
  193. local function clearArea(length, width, height, startDir)
  194. local L = math.max(1, length or 1)
  195. local W = math.max(1, width or 1)
  196. local H = math.max(1, height or 1)
  197. setFacing(startDir or state.facing)
  198.  
  199. local function sweepRow(len, layerIdx, rowIdx)
  200. for i=1,len do
  201. report("clearing area", {
  202. kind="clear", L=L, W=W, H=H,
  203. layer=layerIdx, row=rowIdx, step=i
  204. })
  205. digForward()
  206. if i<len then assert(forward(1)) end
  207. end
  208. end
  209.  
  210. for h=1,H do
  211. setFacing(startDir or state.facing)
  212. for w=1,W do
  213. sweepRow(L, h, w)
  214. if w<W then
  215. if (w % 2 == 1) then
  216. turtle.turnRight(); digForward(); assert(forward(1)); turtle.turnRight()
  217. -- update facing tag
  218. if state.facing=="N" then state.facing="E"
  219. elseif state.facing=="E" then state.facing="S"
  220. elseif state.facing=="S" then state.facing="W"
  221. elseif state.facing=="W" then state.facing="N" end
  222. else
  223. turtle.turnLeft(); digForward(); assert(forward(1)); turtle.turnLeft()
  224. if state.facing=="N" then state.facing="W"
  225. elseif state.facing=="W" then state.facing="S"
  226. elseif state.facing=="S" then state.facing="E"
  227. elseif state.facing=="E" then state.facing="N" end
  228. end
  229. end
  230. end
  231. if h<H then assert(up(1)) end
  232. end
  233. report("waiting")
  234. return true
  235. end
  236.  
  237. -- ---------------- heartbeat + loop ----------------
  238. report("waiting", {kind="note", msg="boot"}, true)
  239.  
  240. parallel.waitForAny(
  241. function()
  242. -- command loop
  243. while true do
  244. local sender, msg, proto = rednet.receive(PROTOCOL, HEARTBEAT_SEC)
  245. if sender and proto==PROTOCOL and type(msg)=="table" and msg.op=="cmd" then
  246. local ok, err
  247. if msg.act=="face" then
  248. ok, err = setFacing(msg.dir)
  249. elseif msg.act=="forward" then
  250. ok, err = forward(msg.n or 1)
  251. elseif msg.act=="up" then
  252. ok, err = up(msg.n or 1)
  253. elseif msg.act=="down" then
  254. ok, err = down(msg.n or 1)
  255. elseif msg.act=="clear_area" then
  256. ok, err = clearArea(msg.length or 1, msg.width or 1, msg.height or 1, msg.dir or state.facing)
  257. elseif msg.act=="set_facing_tag" then
  258. state.facing = msg.dir or state.facing
  259. report("waiting", {kind="face", dir=state.facing})
  260. ok = true
  261. else
  262. ok, err = false, "unknown act"
  263. report("waiting", {kind="note", msg="unknown act"})
  264. end
  265. rednet.send(sender, {op="ack", ok=ok, err=err, ref=msg.ref}, PROTOCOL)
  266. else
  267. report("waiting") -- idle tick keeps console fresh
  268. end
  269. end
  270. end,
  271. function()
  272. while true do
  273. sleep(HEARTBEAT_SEC)
  274. report("waiting")
  275. end
  276. end
  277. )
Advertisement
Add Comment
Please, Sign In to add comment