Posted 09 June 2012 - 06:44 PM
Hello my fellow coders :)/>/>
I consider myself a pretty decent coder, after I have been programming for several years. I have been trying to squash a bug in my turtle mining program for the last many hours, and for the life of me can't track it down.
I have been building an api for my programs, and each function in it has been tested as working before adding it to the final api code. With this api, I already managed to build a program like the one I am attempting again, that was working flawlessly. But, with bad luck, I lost it as it was only saved on computers and disks in that game world. Which is no longer running.
The basics of this program is to ask you the dimensions you want to dig on an x,y,z format, which directions (up/down and left/right), as well as however you want to configure comparing. Then it will return to any world x,y,z coord when all slots have something in them and drop everything off in a specific direction. Finally returning to it's last position and continuing on till finished. Once done it will head back to the "dropoff" location till retrieved.
Everything is working, except when going to the dropoff point, or when finished, sometimes (randomely as far as I have been able to test) will go an extra few blocks (- or +) on the x axis within minecraft. It has also missed the z axis only 1 time out of over 10 tests. I have put in several checks and logging with no avail of tracking it down.
Here is the relevant code for the problem:
snippet of code from the program with the problem: (With the debug print commands, I know the "world location" is always correct where it stops for it's current xyz and its return pos xyz. The only thing left is the call gotoPosition in my api. However, thats confusing as well, as that function has worked flawlessly on the other program when it was running.
Here is the relevant code referenced from the API:
That's almost everything from the api gotoPosition references. Left out the up and down versions of dig as there same as the forward with just the up and down substituted in for everything. Also it has always gone in the right y coord so not an issue.
If I forgot anything I will attach the full program code, as well as the api for reference.
The only thing I was thinking was in the X coord while loop within the gotoPosition function that the digForward(1) was not always returning true, when in fact the turtle did move forward. Since the coord is only updated here on a successful return, could screw up the movement. Yet, in every case It could return false, I added a print statement and none were ever activated.
Lastly, I was wondering if server lag can influence on turtle commands where it would perform it, but perhaps perform the action more than once during the "spike". Was thinking maybe if the movement coincides with one of my faster crontab jobs if it was possible. Sort of ruled it out without even testing, as if that was the case, it should be playing havoc on the actually digging the "quarry" dimensions as well. Yet, these have always been perfect and never off by 1 block in any direction.
Any help would be appreciated.
p.s. files attached are the full code for both the program and the api, if you need to see anything else
I consider myself a pretty decent coder, after I have been programming for several years. I have been trying to squash a bug in my turtle mining program for the last many hours, and for the life of me can't track it down.
I have been building an api for my programs, and each function in it has been tested as working before adding it to the final api code. With this api, I already managed to build a program like the one I am attempting again, that was working flawlessly. But, with bad luck, I lost it as it was only saved on computers and disks in that game world. Which is no longer running.
The basics of this program is to ask you the dimensions you want to dig on an x,y,z format, which directions (up/down and left/right), as well as however you want to configure comparing. Then it will return to any world x,y,z coord when all slots have something in them and drop everything off in a specific direction. Finally returning to it's last position and continuing on till finished. Once done it will head back to the "dropoff" location till retrieved.
Everything is working, except when going to the dropoff point, or when finished, sometimes (randomely as far as I have been able to test) will go an extra few blocks (- or +) on the x axis within minecraft. It has also missed the z axis only 1 time out of over 10 tests. I have put in several checks and logging with no avail of tracking it down.
Here is the relevant code for the problem:
snippet of code from the program with the problem: (With the debug print commands, I know the "world location" is always correct where it stops for it's current xyz and its return pos xyz. The only thing left is the call gotoPosition in my api. However, thats confusing as well, as that function has worked flawlessly on the other program when it was running.
print("finished!")
print("at pos: "..currentPos_x..":"..currentPos_y..":"..currentPos_z)
print("heading to: "..returnPos_x..":"..returnPos_y..":"..returnPos_z)
sprystudio.gotoPosition(currentPos_x, currentPos_y, currentPos_z, returnPos_x, returnPos_y, returnPos_z, currentPos_dir, returnPos_dir)
Here is the relevant code referenced from the API:
--[[
turtle will go to a specific vector(x,y,z) and face a specific direction
@param currentPos (current position in x,y,z format, whether local or world coords [world can be gotten from f3])
@param destination (the position you want your turtle to end up at, in x,y,z format, in relation to currentPos.)
@param currentDirection (which direction the turtle is facing right now (0=south, 1=west, 2=north, and 3=east [f under xyz in f3])
@param endingDirection (which direction you want turtle facing when reaches destination, same format as currentDirection)
--]]
function gotoPosition(currentPos_x, currentPos_y, currentPos_z, destination_x, destination_y, destination_z, currentDirection, endingDirection)
while currentPos_x ~= destination_x do
if currentPos_x > destination_x then
currentDirection = faceDirection(1, currentDirection)
if digForward(1) then currentPos_x = currentPos_x - 1 end
else
currentDirection = faceDirection(3, currentDirection)
digForward(1)
if digForward(1) then currentPos_x = currentPos_x + 1 end
end
end
while currentPos_z ~= destination_z do
if currentPos_z > destination_z then
currentDirection = faceDirection(2, currentDirection)
if digForward(1) then currentPos_z = currentPos_z - 1 end
else
currentDirection = faceDirection(0, currentDirection)
if digForward(1) then currentPos_z = currentPos_z + 1 end
end
end
while currentPos_y ~= destination_y do
if currentPos_y > destination_y then
if digDown(1) then currentPos_y = currentPos_y - 1 end
else
if digUp(1) then currentPos_y = currentPos_y + 1 end
end
end
faceDirection(endingDirection, currentDirection)
end
--[[
will turn the turtle so it is facing a specific direction.
@param direction (which direction you want to face: 0=south, 1=west, 2=north, and 3=east [f under xyz in f3])
@param currentDirection (current direction you are facing)
--]]
function faceDirection(direction, currentDirection)
while currentDirection ~= direction do
currentDirection = turnLeft(currentDirection)
end
return currentDirection
end
--[[
A turtle attempts to dig forward a set amount of blocks, or until unable. Tries to handle any obstructions, by trying to attempt it again 20 times in 5 seconds(gravel), then by waiting 30 seconds for final attempt. If successful it returns the new inventoryArray if set, otherwise true. If not successful it returns the number of spaces it has moved forward so your able to still update it's new location.
Needed Params:
@param amount (# of blocks, 0 = dig but doesn't move, -1 = until unable)
Optional Params:
@param inventoryArray (a table containing the amounts in each inventory slot of the turtle. needed if using compare to control inventory)
@param compareType (which type of compare we want to perform: same = equals one of the blocks, different = not equal to one of the blocks)
@param one-nine (slots representing turtle's inventory, 1 = use that slot, 0 = dont. If any are set, then comparing will be done each dig.)
--]]
function digForward(amount, inventoryArray, compareType, one, two, three, four, five, six, seven, eight, nine)
local compareResult, compareOnDig, zeroCheck = false, false, false
if inventoryArray and compareType and one and two and three and four and five and six and seven and eight and nine then compareOnDig = true end
if amount == 0 then
zeroCheck = true
amount = 1
end
if amount >= 0 then
for y = 1, amount, 1 do
if turtle.detect() then
if compareOnDig then compareResult = compare("forward", one, two, three, four, five, six, seven, eight, nine) end
if not turtle.dig() then
os.sleep(30)
if not turtle.dig() then return false end
end
if compareOnDig and ((compareResult == false and compareType == "same") or (compareResult == true and compareType == "different")) then inventoryArray = sortInventory(inventoryArray, "drop")
elseif compareOnDig then inventoryArray = sortInventory(inventoryArray, "keep") end
end
if not zeroCheck then
if not turtle.forward() then
print("failed to move forward, starting gravel check")
if not gravelCheck("forward") then
os.sleep(30)
if not turtle.forward() then return false end
end
end
end
end
else
while turtle.detect() do
if compareOnDig then compareResult = compare("forward", one, two, three, four, five, six, seven, eight, nine) end
turtle.dig()
if compareOnDig and ((compareResult == false and compareType == "same") or (compareResult == true and compareType == "different")) then inventoryArray = sortInventory(inventoryArray, "drop")
elseif compareOnDig then inventoryArray = sortInventory(inventoryArray, "keep") end
turtle.forward()
end
end
if compareOnDig then return inventoryArray else return true end
end
--[[
turns a turtle to the left, while also returning the new direction it's facing
@param currentDirection (current direction the turtle is facing, [f under xyz in f3])
--]]
function turnLeft(currentDirection)
turtle.turnLeft()
currentDirection = currentDirection - 1
if currentDirection == -1 then currentDirection = 3 end
return currentDirection
end
--[[
turns a turtle to the right, while also returning the new direction it's facing
@param currentDirection (current direction the turtle is facing, [f under xyz in f3])
--]]
function turnRight(currentDirection)
turtle.turnRight()
currentDirection = currentDirection + 1
if currentDirection == 4 then currentDirection = 0 end
return currentDirection
end
--[[
Moves a turtle forward a set amount of blocks, or until unable. Tries to handle any obstructions (i.e. gravel, players, etc..) by pausing 30 seconds and trying again once.
@param amount (# of blocks, -1 = until unable)
--]]
function moveForward(amount)
if amount >= 0 then
for y = 1, amount, 1 do
if not turtle.forward() then
os.sleep(30)
if not turtle.forward() then return false end
end
end
else
while turtle.forward() do end
end
return true
end
--[[
A turtle will return the results of a compare towards a direction(forward, up and down). Returns true or false on the compare, so can use for comparing to or against. Also you have full control over exactly what slots in the inventory the block is compared to.
@param direction (the direction of the block to compare: forward, up or down)
@param one-nine (1 = add this slot to the compare, 0 = ignore this slot, i.e. ,1,0,0,1,1,0,0,0,1 will compare against slots 1, 4, 5, and 9)
--]]
function compare(direction, one, two, three, four, five, six, seven, eight, nine)
local result = false
if one == 1 then result = compareSlot(1, direction) end
if not result and two == 1 then result = compareSlot(2, direction) end
if not result and three == 1 then result = compareSlot(3, direction) end
if not result and four == 1 then result = compareSlot(4, direction) end
if not result and five == 1 then result = compareSlot(5, direction) end
if not result and six == 1 then result = compareSlot(6, direction) end
if not result and seven == 1 then result = compareSlot(7, direction) end
if not result and eight == 1 then result = compareSlot(8, direction) end
if not result and nine == 1 then result = compareSlot(9, direction) end
return result
end
--[[
Sorts a turtle's inventory either keeping new blocks or dropping them based on action parameter.
@param inventoryArray (a table holding the number of items in each slot for the turtle for the respected slots 1-9 before the new blocks)
@param action ("keep" - keeps blocks and updates inventoryArray, "drop" - drops blocks and updates inventoryArray if values under 0)
--]]
function sortInventory(inventoryArray, action)
for slot = 1, 9, 1 do
local amount = turtle.getItemCount(slot)
if amount ~= inventoryArray[slot] then
if amount > 0 then
if action == "drop" then
turtle.select(slot)
turtle.drop(amount - inventoryArray[slot])
else inventoryArray[slot] = amount end
else inventoryArray[slot] = 0 end
end
end
return inventoryArray
end
That's almost everything from the api gotoPosition references. Left out the up and down versions of dig as there same as the forward with just the up and down substituted in for everything. Also it has always gone in the right y coord so not an issue.
If I forgot anything I will attach the full program code, as well as the api for reference.
The only thing I was thinking was in the X coord while loop within the gotoPosition function that the digForward(1) was not always returning true, when in fact the turtle did move forward. Since the coord is only updated here on a successful return, could screw up the movement. Yet, in every case It could return false, I added a print statement and none were ever activated.
Lastly, I was wondering if server lag can influence on turtle commands where it would perform it, but perhaps perform the action more than once during the "spike". Was thinking maybe if the movement coincides with one of my faster crontab jobs if it was possible. Sort of ruled it out without even testing, as if that was the case, it should be playing havoc on the actually digging the "quarry" dimensions as well. Yet, these have always been perfect and never off by 1 block in any direction.
Any help would be appreciated.
p.s. files attached are the full code for both the program and the api, if you need to see anything else