robathome icon

RoboMiner_miningTurtle

robathome | PRO | 10/18/25 07:14:53 PM UTC (Edited) | 0 ⭐ | 495 👁️ | Never ⏰ | []
text |

8.11 KB

|

None

|

0 👍

/

0 👎

-- miner_startup.lua
-- Ultra-dumb miner. Verbose local console + heartbeats.
-- Requires: wireless (ender) modem; label set via: label set miner_alpha
 local PROTOCOL = "minesys:v1"
local HEARTBEAT_SEC = 2
 local modem = peripheral.find("modem", function(_, p) return p.isWireless() end)
if not modem then error("No wireless modem") end
if not turtle then error("Run on a turtle") end
rednet.open(peripheral.getName(modem))
 -- ---------------- console/status ----------------
local state = {
  status = "waiting",
  extra = nil,
  facing = "N",
  pos = nil,
  fuel = turtle.getFuelLevel(),
  lastDraw = 0,
}
 local function invStats()
  local empty = 0
  for i=1,16 do if turtle.getItemCount(i)==0 then empty = empty + 1 end end
  local pct = (empty/16)*100
  return { freeSlots = empty, freePct = pct }
end
 local function now() return os.epoch("utc") end
 local function gpsPos()
  local x, y, z = gps.locate(1)
  if x then state.pos = {x=x,y=y,z=z} end
  return x, y, z
end
 local function setStatus(s, extra)
  state.status = s or state.status
  state.extra = extra or nil
end
 local function drawConsole(force)
  local t = now()
  if not force and (t - state.lastDraw) < 100 then return end -- 0.1s throttle
  state.lastDraw = t
   term.setBackgroundColor(colors.black)
  term.setTextColor(colors.white)
  term.clear()
  term.setCursorPos(1,1)
  local lbl = os.getComputerLabel() or ("id"..os.getComputerID())
  print(("Miner %s"):format(lbl))
  print(("Fuel: %s"):format(tostring(state.fuel)))
  local p = state.pos
  print(("Pos: %s"):format(p and ("("..p.x..","..p.y..","..p.z..")") or "unknown"))
  print(("Facing: %s"):format(state.facing))
  print(("Status: %s"):format(state.status))
   if state.extra then
    -- Render compact progress lines
    if state.extra.kind=="move" then
      print(("- Move %s: %d/%d"):format(state.extra.axis, state.extra.step, state.extra.total))
    elseif state.extra.kind=="clear" then
      print(("- Clear LxWxH: %d×%d×%d"):format(state.extra.L, state.extra.W, state.extra.H))
      print(("  Layer: %d/%d  Row: %d/%d  Step: %d/%d"):format(
        state.extra.layer, state.extra.H,
        state.extra.row, state.extra.W,
        state.extra.step, state.extra.L
      ))
    elseif state.extra.kind=="face" then
      print(("- Face: %s"):format(state.extra.dir))
    elseif state.extra.kind=="note" and state.extra.msg then
      print(("- Note: %s"):format(state.extra.msg))
    end
  end
end
 local function hb()
  state.fuel = turtle.getFuelLevel()
  gpsPos()
  local msg = {
    t = now(),
    op = "status",
    id = os.getComputerID(),
    label = os.getComputerLabel(),
    pos = state.pos,
    fuel = state.fuel,
    facing = state.facing,
    status = state.status,
    extra = state.extra,
	inv   = invStats(),
  }
  rednet.broadcast(msg, PROTOCOL)
end
 local function report(s, extra, forceDraw)
  setStatus(s, extra)
  drawConsole(forceDraw)
  hb()
end
 -- ---------------- motion primitives ----------------
local DIRS = {N=0, E=1, S=2, W=3}
local dirNames = {"N","E","S","W"}
 local function setFacing(newDir)
  if not DIRS[newDir] then return false, "bad dir" end
  if state.facing == newDir then
    report("waiting", {kind="face", dir=newDir})
    return true
  end
  local idx = DIRS[state.facing]; local tgt = DIRS[newDir]
  local diff = (tgt - idx) % 4
  report("waiting", {kind="face", dir=newDir}, true)
  if diff == 1 then turtle.turnRight()
  elseif diff == 2 then turtle.turnRight(); turtle.turnRight()
  elseif diff == 3 then turtle.turnLeft()
  end
  state.facing = newDir
  report("waiting", {kind="face", dir=newDir})
  return true
end
 local function digForward()
  while turtle.detect() do
    turtle.dig()
    sleep(0.15)
  end
end
 local function forward(n)
  n = math.max(0, n or 1)
  for i=1, n do
    report("moving to", {kind="move", axis="fwd", step=i, total=n})
    digForward()
    local tries=0
    while not turtle.forward() do
      digForward()
      tries=tries+1
      if tries>50 then
        report("waiting", {kind="note", msg="blocked fwd"})
        return false, "blocked"
      end
      sleep(0.15)
    end
  end
  report("waiting")
  return true
end
 local function up(n)
  n = math.max(0, n or 1)
  for i=1, n do
    report("moving to", {kind="move", axis="up", step=i, total=n})
    while turtle.detectUp() do turtle.digUp(); sleep(0.15) end
    local tries=0
    while not turtle.up() do
      while turtle.detectUp() do turtle.digUp(); sleep(0.15) end
      tries=tries+1
      if tries>50 then
        report("waiting", {kind="note", msg="blocked up"})
        return false, "blocked"
      end
      sleep(0.15)
    end
  end
  report("waiting")
  return true
end
 local function down(n)
  n = math.max(0, n or 1)
  for i=1, n do
    report("moving to", {kind="move", axis="down", step=i, total=n})
    while turtle.detectDown() do turtle.digDown(); sleep(0.15) end
    local tries=0
    while not turtle.down() do
      while turtle.detectDown() do turtle.digDown(); sleep(0.15) end
      tries=tries+1
      if tries>50 then
        report("waiting", {kind="note", msg="blocked down"})
        return false, "blocked"
      end
      sleep(0.15)
    end
  end
  report("waiting")
  return true
end
 -- ---------------- clear area ----------------
local function clearArea(length, width, height, startDir)
  local L = math.max(1, length or 1)
  local W = math.max(1, width  or 1)
  local H = math.max(1, height or 1)
  setFacing(startDir or state.facing)
   local function sweepRow(len, layerIdx, rowIdx)
    for i=1,len do
      report("clearing area", {
        kind="clear", L=L, W=W, H=H,
        layer=layerIdx, row=rowIdx, step=i
      })
      digForward()
      if i<len then assert(forward(1)) end
    end
  end
   for h=1,H do
    setFacing(startDir or state.facing)
    for w=1,W do
      sweepRow(L, h, w)
      if w<W then
        if (w % 2 == 1) then
          turtle.turnRight(); digForward(); assert(forward(1)); turtle.turnRight()
          -- update facing tag
          if     state.facing=="N" then state.facing="E"
          elseif state.facing=="E" then state.facing="S"
          elseif state.facing=="S" then state.facing="W"
          elseif state.facing=="W" then state.facing="N" end
        else
          turtle.turnLeft(); digForward(); assert(forward(1)); turtle.turnLeft()
          if     state.facing=="N" then state.facing="W"
          elseif state.facing=="W" then state.facing="S"
          elseif state.facing=="S" then state.facing="E"
          elseif state.facing=="E" then state.facing="N" end
        end
      end
    end
    if h<H then assert(up(1)) end
  end
  report("waiting")
  return true
end
 -- ---------------- heartbeat + loop ----------------
report("waiting", {kind="note", msg="boot"}, true)
 parallel.waitForAny(
  function()
    -- command loop
    while true do
      local sender, msg, proto = rednet.receive(PROTOCOL, HEARTBEAT_SEC)
      if sender and proto==PROTOCOL and type(msg)=="table" and msg.op=="cmd" then
        local ok, err
        if msg.act=="face" then
          ok, err = setFacing(msg.dir)
        elseif msg.act=="forward" then
          ok, err = forward(msg.n or 1)
        elseif msg.act=="up" then
          ok, err = up(msg.n or 1)
        elseif msg.act=="down" then
          ok, err = down(msg.n or 1)
        elseif msg.act=="clear_area" then
          ok, err = clearArea(msg.length or 1, msg.width or 1, msg.height or 1, msg.dir or state.facing)
        elseif msg.act=="set_facing_tag" then
          state.facing = msg.dir or state.facing
          report("waiting", {kind="face", dir=state.facing})
          ok = true
        else
          ok, err = false, "unknown act"
          report("waiting", {kind="note", msg="unknown act"})
        end
        rednet.send(sender, {op="ack", ok=ok, err=err, ref=msg.ref}, PROTOCOL)
      else
        report("waiting") -- idle tick keeps console fresh
      end
    end
  end,
  function()
    while true do
      sleep(HEARTBEAT_SEC)
      report("waiting")
    end
  end
)

Comments