Skip to content

Instantly share code, notes, and snippets.

@orlp
Last active October 13, 2015 19:38
Show Gist options
  • Save orlp/4246007 to your computer and use it in GitHub Desktop.
Save orlp/4246007 to your computer and use it in GitHub Desktop.
Excavation program for turtles in minecraft.
-- run by calling: f=fs.open("/startup", "w");f.write(http.get("https://gist.github.com/raw/4246007").readAll());f.close();dofile("/startup")
-- orientation: 0 = N, 1 = E, 2 = S, 3 = W
function save_state()
f = fs.open("/excavate_state", "w")
f.write("state = ")
f.write(textutils.serialize(state))
f.close()
end
function load_state()
dofile("/excavate_state")
end
function dig()
if turtle.detect() then
turtle.dig()
end
end
function dig_down()
if turtle.detectDown() then
turtle.digDown()
end
end
function dig_up()
if turtle.detectUp() then
turtle.digUp()
end
end
function orient_to(target_orientation)
delta_orientation = ((target_orientation % 4) - state["orientation"]) % 4
state["orientation"] = target_orientation
save_state()
if delta_orientation == 3 then
delta_orientation = -1
end
if delta_orientation == -3 then
delta_orientation = 1
end
while delta_orientation > 0 do
turtle.turnRight()
delta_orientation = delta_orientation - 1
end
while delta_orientation < 0 do
turtle.turnLeft()
delta_orientation = delta_orientation + 1
end
end
function move_up()
dig_up()
turtle.attackUp()
turtle.suckUp()
state["y_pos"] = state["y_pos"] + 1
save_state()
r = turtle.up()
if not r then
state["y_pos"] = state["y_pos"] - 1
save_state()
end
return r
end
function move_down()
dig_down()
turtle.attackDown()
turtle.suckDown()
state["y_pos"] = state["y_pos"] - 1
save_state()
r = turtle.down()
if not r then
state["y_pos"] = state["y_pos"] + 1
save_state()
end
return r
end
function move_forward()
dig()
turtle.attack()
turtle.suck()
if state["orientation"] == 0 then
state["z_pos"] = state["z_pos"] + 1
elseif state["orientation"] == 1 then
state["x_pos"] = state["x_pos"] + 1
elseif state["orientation"] == 2 then
state["z_pos"] = state["z_pos"] - 1
elseif state["orientation"] == 3 then
state["x_pos"] = state["x_pos"] - 1
end
save_state()
r = turtle.forward()
if not r then
if state["orientation"] == 0 then
state["z_pos"] = state["z_pos"] - 1
elseif state["orientation"] == 1 then
state["x_pos"] = state["x_pos"] - 1
elseif state["orientation"] == 2 then
state["z_pos"] = state["z_pos"] + 1
elseif state["orientation"] == 3 then
state["x_pos"] = state["x_pos"] + 1
end
save_state()
end
return r
end
function move_to_pos_step(target_x, target_z, target_y)
-- prioritize x over z over y
-- we're to the west of the target point
if state["x_pos"] < target_x then
orient_to(1)
move_forward()
-- we're to the east of the target point
elseif state["x_pos"] > target_x then
orient_to(3)
move_forward()
-- we're to the south of the target point
elseif state["z_pos"] < target_z then
orient_to(0)
move_forward()
-- we're to the north of the target point
elseif state["z_pos"] > target_z then
orient_to(2)
move_forward()
-- we're under the target point
elseif state["y_pos"] < target_y then
move_up()
-- we're above the target point
elseif state["y_pos"] > target_y then
move_down()
end
if state["x_pos"] == target_x and state["y_pos"] == target_y and state["z_pos"] == target_z then
return true
else
return false
end
end
function move_to_pos(target_x, target_y, target_z)
while not move_to_pos_step(target_x, target_y, target_z) do
end
end
function inventory_has_empty_slot()
for i = 1, 16 do
if turtle.getItemCount(i) == 0 then
return true
end
end
return false
end
function drop_inventory()
for i = 1, 16 do
turtle.select(i)
while turtle.getItemCount(i) > 0 do turtle.drop() end
end
end
function excavate()
if state["done"] then
return
end
while true do
if state["start"] then
move_to_pos(0, 0, starting_height)
if state["bottom_to_top"] then
dig_up()
move_up()
dig_up()
else
dig_down()
move_down()
dig_down()
end
if state["width"] < 0 then
orient_to(3)
else
orient_to(1)
end
while not move_forward() do end
dig_up()
dig_down()
state["start"] = false
save_state()
elseif state["dropping"] then
move_to_pos(0, 0, 0)
-- drop to south
orient_to(2)
drop_inventory()
move_to_pos(state["saved_x_pos"], state["saved_z_pos"], state["saved_y_pos"])
orient_to(state["saved_orientation"])
state["dropping"] = false
save_state()
else
while inventory_has_empty_slot() do
-- prioritize width over length over height
if state["x_pos"] == 0 or state["x_pos"] == state["width"] then
if state["z_pos"] == (state["length"] - 1) then
if state["bottom_to_top"] then
if state["y_pos"] >= (state["height"] + state["starting_height"] - 2) then
-- we're done
state["done"] = true
save_state()
return true
end
-- move to the next level
move_to_pos(0, 0, state["y_pos"] + 3)
dig_down()
dig_up()
else
if state["y_pos"] <= (-state["height"] + state["starting_height"] + 2) then
-- we're done
state["done"] = true
save_state()
return true
end
-- move to the next level
move_to_pos(0, 0, state["y_pos"] - 3)
dig_down()
dig_up()
end
if state["width"] < 0 then
orient_to(3)
else
orient_to(1)
end
else
-- move to next row
orient_to(0)
while not move_forward() do end
dig_up()
dig_down()
dir = 1
if state["x_pos"] == state["width"] then
dir = (dir + 2) % 4
end
if state["width"] < 0 then
dir = (dir + 2) % 4
end
orient_to(dir)
end
end
while not move_forward() do end
dig_up()
dig_down()
end
state["saved_x_pos"] = state["x_pos"]
state["saved_y_pos"] = state["y_pos"]
state["saved_z_pos"] = state["z_pos"]
state["saved_orientation"] = state["orientation"]
state["dropping"] = true
save_state()
end
end
end
function main()
if fs.exists("/excavate_state") then
load_state()
else
term.clear()
term.setCursorPos(1, 1)
print("----- Excavate program -----")
print("")
print("What dimensions?")
print("")
term.write("Width (+right, -left): ")
width = tonumber(io.read())
term.write("Length (in front of the turtle): ")
length = math.abs(tonumber(io.read()))
term.write("Height (multiple of 3, +up, -down): ")
height = tonumber(io.read())
term.write("Starting height (relative, +/-): ")
starting_height = tonumber(io.read())
-- sanitize input
if math.abs(height) < 3 then
return
end
if height < 0 then
bottom_to_top = false
height = -height
else
bottom_to_top = true
end
if math.abs(width) < 2 then
return
end
-- fix bug where the turtle wants to dig one too wide
if width < 0 then
width = width + 1
else
width = width - 1
end
state = {
x_pos = 0,
y_pos = 0,
z_pos = 0,
orientation = 0,
width = width,
length = length,
height = height,
starting_height = starting_height,
bottom_to_top = bottom_to_top,
start = true,
done = false,
dropping = false
}
save_state()
end
print("Excavating...")
excavate()
-- return to base and unload
move_to_pos(0, 0, 0)
orient_to(2)
drop_inventory()
orient_to(0)
print("Done!")
fs.delete("/excavate_state")
end
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment