So, I've just started with ComputerCraft and LUA, but I come from a programming background so it hasn't been too hard to pick up. Until now.
As a part of learning, I'm trying to write a simple program for a mining turtle so that, starting from a chest, it will dig a shaft N by M down. When it runs low on fuel or fills it's inventory up, it will return to the chest and dump everything before refuelling. I'm doing my path-finding with vectors. The start location is vector <0,0,0>, the mineshaft starts at vector <2,0,0> (2 blocks away from the chest), and every time I move I increase the vector appropriately.
The plan was, when the turtle does need to return to the chest, it can record it's current location as a vector, navigate to <0,0,0> to drop everything, and then use the previously recorded position to return to where it was last.
The problem is that reading the vector in, that I thought I'd stored, always returns <0,0,0> no matter what, so the turtle starts from where it's at and destroys the chest it just dumped everything into.
I think it's a scoping issue, but despite researching it for the last couple of hours, I haven't figured it out.
The relevant code is as follows:
Spoiler
local mineLocation = vector.new(2,0,0)
local location = vector.new(0,0,0)
-- miners start pointing backwards towards their chest.
-- '0' indicates positive x, '1' positive y, '2' negative x, '3' negative y
-- a right turn adds 1 to direction, a left turn subtracts
-- every time direction is modified, it is also normalized to remain between 0 and 3 inclusive
local direction = 2
local toMine = function()
print("Going to Mine")
print("Retreiving Mine Location")
-- THIS ALWAYS PRINTS (0,0,0) --
print("(" .. mineLocation.x .. "," .. mineLocation.y .. "," .. mineLocation.z .. ")")
print("")
tmpVec = mineLocation - location
-- if positive x
if tmpVec.x > 0 then
-- face positive x
while direction ~= 0 do
right()
end
-- move in that direction
for i=1,tmpVec.x do
forward()
end
end
-- if negative x
if tmpVec.x < 0 then
-- face negative x
while direction ~= 2 do
right()
end
-- move in that direction
for i=tmpVec.x,-1 do
forward()
end
end
-- if positive y
if tmpVec.y > 0 then
-- face positive y
while direction ~= 1 do
right()
end
-- move in that direction
for i=1,tmpVec.y do
forward()
end
end
--if negative y
if tmpVec.y < 0 then
-- face negative y
while direction ~= 3 do
right()
end
-- move in that direction
for i=tmpVec.y,-1 do
forward()
end
end
-- if positive z
if tmpVec.z > 0 then
for i=1,tmpVec.z do
down()
end
end
-- if negative z
if tmpVec.z < 0 then
for i=tmpVec.z,-1 do
up()
end
end
end
while true do
if refuel() then
toMine(mineLocation) -- THIS WORKS FINE AND MOVES TURTLE TO <2,0,0>
while (turtle.getFuelLevel() > 1600) do
for j=1,tArgs[2] do -- ROWS
for i=2,tArgs[1] do -- COLUMNS (-1 from column length as you need to move one less space than you need to dig)
if turtle.detectDown() then
turtle.digDown()
end
forward()
end
turtle.digDown()
if turtle.getItemCount(15) ~= 0 then -- If all slots now have something in them we're pretty full. Might as well empty the inventory.
mineLocation = location -- THIS IS WHERE I THINK EVERYTHING IS GOING WRONG --
print("Recording Mine Location")
-- THIS PRINTS THE RIGHT VALUES --
print("(" .. mineLocation.x .. "," .. mineLocation.y .. "," .. mineLocation.z .. ")")
print("")
returnToStart() -- PRACTICALLY THE SAME ALGORITHM AS toMine() BUT DOESN'T TOUCH mineLocation AT ALL --
refuel()
toMine()
end
end
returnToCorner()
down()
end
else
print("Ran out of fuel")
sleep(120)
end
end
I'm unsure if vectors work in ComputerCraft. I know tables do, try using that. You can find a lot of ComputerCraft stuff on the wiki. Just Google it. Tables are pretty simple.
I see. Personally, I've never used them. Learn something new everyday, eh? I like variables, and I have done the same things with them.
(x, y, z coordinates) If you are dead-set on vectors, I can't help you, I'm inexperienced with them. Someone else will eventually pick this up. But if you are willing to use a table, I'll be happy to lend what knowledge I do have. I'm not incredibly experienced, but I know enough to get most of my programs running.
--Lettuce
Well, I don't see any part that modifies the vectors. I guess you do it in the movement functions (forward, back, etc.), so you should post them.
The only vector that is regularly being modified is the location vector to keep track of where the turtle is. All the code that references mineLocation has been posted above.
For reference I'm including my movement functions and a couple of the supporting functions below.
Spoiler
local naturalizeDirection = function(z)
dir = direction + z
if dir > 3 then
dir = dir % 4
end
if dir < 0 then
dir = dir + 4
end
return dir
end
local turnTo = function(d)
if direction == d then
return true
else
change = d - direction
if change == 2 or change == -2 then
right()
right()
elseif change == 1 or change == -3 then
right()
elseif change == 3 or change == -1 then
left()
end
end
end
local right = function()
turtle.turnRight()
direction = naturalizeDirection(1)
end
local left = function()
turtle.turnLeft()
direction = naturalizeDirection(-1)
end
local up = function()
if not turtle.up() then
return false
end
location.z = location.z - 1
return true
end
local down = function()
if not turtle.down() then
return false
end
location.z = location.z + 1
return true
end
local forward = function()
if turtle.detect() then
turtle.dig()
end
if not turtle.forward() then
return false
end
if direction == 0 then
location.x = location.x + 1
elseif direction == 1 then
location.y = location.y + 1
elseif direction == 2 then
location.x = location.x - 1
elseif direction == 3 then
location.y = location.y - 1
end
return true
end
local back = function()
if not turtle.back() then
return false
end
if direction == 0 then
location.x = location.x - 1
elseif direction == 1 then
location.y = location.y - 1
elseif direction == 2 then
location.x = location.x + 1
elseif direction == 3 then
location.y = location.y + 1
end
return true
end
I see. Personally, I've never used them. Learn something new everyday, eh? I like variables, and I have done the same things with them.
(x, y, z coordinates) If you are dead-set on vectors, I can't help you, I'm inexperienced with them. Someone else will eventually pick this up. But if you are willing to use a table, I'll be happy to lend what knowledge I do have. I'm not incredibly experienced, but I know enough to get most of my programs running.
--Lettuce
I figure it's possible to do it with tables and other variables, but I don't know if that would solve the problem I've run into. My other vectors seem to be working fine so I don't know what the problem is. I don't really want to go through a whole rewrite of the code just cause a single vector doesn't want to work and the rest do.
I'm not sure if it might be a reference issue, where mineLocation just becomes a 'pointer' to the exact same object as location instead of a copy
Try changing:
First, if you're not opposed to using an external API, you could check out my Location API, which is very similar to the vector API with a few added things to make turtle tracking much easier. The latest version can be found here; the discussion topic on these forums is found here. Even if you don't choose to use it, please feel free to take a look through the code. It's not very long and it may help you tighten up some of your code. If you have any questions about it, feel free to ask here or PM me.
Also, when printing vectors (and locations, if using my API), passing the vector or location to tostring() will output a reasonably formatted (comma-separated) string output.
I would most likely suspect that mineLocation = location line, that does assign mineLocation to simply point to whatever table location points to already, so they are then linked until either of them is set to a new value.
tomass1996, on 08 September 2012 - 03:37 AM, said:
I'm not sure if it might be a reference issue, where mineLocation just becomes a 'pointer' to the exact same object as location instead of a copy
Try changing:
SUCCESS!! Thanks so much for your insight. Wish I had asked on these forums sooner.
Lyqyd, on 08 September 2012 - 04:02 AM, said:
First, if you're not opposed to using an external API, you could check out my Location API, which is very similar to the vector API with a few added things to make turtle tracking much easier. The latest version can be found here; the discussion topic on these forums is found here. Even if you don't choose to use it, please feel free to take a look through the code. It's not very long and it may help you tighten up some of your code. If you have any questions about it, feel free to ask here or PM me.
Also, when printing vectors (and locations, if using my API), passing the vector or location to tostring() will output a reasonably formatted (comma-separated) string output.
I would most likely suspect that mineLocation = location line, that does assign mineLocation to simply point to whatever table location points to already, so they are then linked until either of them is set to a new value.
I'm not opposed to an external API, but the purpose of this exercise was learning LUA, not actually getting a working miner. I did take a look at the API and might well use it, or at least integrate part of it, in future. Very clean. Going to have to learn LUA coding standards as well as just the language.