Last active
October 13, 2015 19:38
-
-
Save orlp/4246007 to your computer and use it in GitHub Desktop.
Excavation program for turtles in minecraft.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-- 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