This is a read-only snapshot of the ComputerCraft forums, taken in April 2020.
jag's profile picture

Need help with goto program

Started by jag, 18 October 2012 - 05:56 PM
jag #1
Posted 18 October 2012 - 07:56 PM
First off, I want to create a goto program.

This is how long I've come so far:
(Also on pastebin: D1UKi7vU)
Spoiler
local tArgs = {...}
if #tArgs < 3 then
  write("Usage: ")
  write(shell.getRunningProgram())
  print(" <x> <y> <z>")
  return
end

local posX, posY, posZ = 0
dir = 0

function goUp()
  while not turtle.up() do
	goForward()
  end
  posY = posY + 1
end
function goDown()
  while not turtle.down() do
	goForward()
  end
  posY = posY - 1
end
function left()
  if dir < 0+1 then
	dir = 3
  else
	dir = dir - 1
  end
  turtle.turnLeft()
end
function right()
  if dir > 3-1 then
	dir = 0
  else
	dir = dir + 1
  end
  turtle.turnRight()
end
function goForward()
  while not turtle.forward() do
	goUp()
  end
  if dir == 0 then
	posZ = posZ + 1
  elseif dir == 1 then
	posX = posX + 1
  elseif dir == 2 then
	posZ = posZ - 1
  elseif dir == 3 then
	posX = posX - 1
  else
	error("Undefined direction.")
  end
end
function goBack()
  while not turtle.back() do
	goUp()
  end
  if dir == 0 then
	posZ = posZ - 1
  elseif dir == 1 then
	posX = posX - 1
  elseif dir == 2 then
	posZ = posZ + 1
  elseif dir == 3 then
	posX = posX + 1
  else
	error("Undefined direction.")
  end
end
function faceZ()
  if dir ~= 0 then
	if dir == 1 then
	  left()
	else
	  repeat
		right()
	  until dir == 0
	end
  end
end
function faceNZ()
  if dir ~= 2 then
	if dir == 3 then
	  left()
	else
	  repeat
		right()
	  until dir == 2
	end
  end
end
function faceX()
  if dir ~= 1 then
	if dir == 2 then
	  left()
	else
	  repeat
		right()
	  until dir == 1
	end
  end
end
function faceNX()
  if dir ~= 3 then
	if dir == 0 then
	  left()
	else
	  repeat
		right()
	  until dir == 3
	end
  end
end
function goto(x,y,z)
  print("Heading to x"..x..", y"..y..", z"..z.."!")
  repeat
	if x < posX then
	  faceNX()
	elseif x > posX then
	  faceX()
	end
	while x ~= posX do
	  goForward()
	end
	if z < posZ then
	  faceNZ()
	elseif z > posZ then
	  faceZ()
	end
	while z ~= posZ do
	  goForward()
	end
	while y < posY do
	  goDown()
	end
	while y > posY do
	  goUp()
	end
  until x == posX and y == posY and z == posZ
end
function dropOff()
  for i = 1, 16 do
	turtle.select(i)
	turtle.drop()
  end
  turtle.select(1)
end

local param1 = tonumber(tArgs[1])
local param2 = tonumber(tArgs[2])
local param3 = tonumber(tArgs[3])
goto(param1,param2,param3)
faceZ()

This goto program uses it's current position as x, y and z coordinates and the direction 0 (facing the Z-axle).
That means that if you run the program like this
-- goto x y z
goto 0 0 4
it will then go 4 times forward.

But what I want to do is to replace this
local posX, posY, posZ = 0
dir = 0
with some way to detect the pos and dir.

The detection of the pos is really simple, just do
rednet.open("right")
local posX, posY, posZ = gps.locate(.5)
rednet.close("right")
if not posX then
  print("Could not locate position!")
  return
end
but the tricky part comes in where I need to find out the direction…

If you come up with some clever way to detect this then I would love to see some suggestions from you guys!

Thanks!
//Kalle

EDIT: I found out why the program was acting weird! The x-coordinates was kind of inverted. Instead of going 2 steps forward on the x-axle it went 2 steps backward…
Ditto8353 #2
Posted 18 October 2012 - 08:06 PM
Have the turtle move one space and then get the new location.
Compare that with the old location.
jag #3
Posted 18 October 2012 - 08:24 PM
Have the turtle move one space and then get the new location.
Compare that with the old location.
Yeah but what if its a block in the way? I dont want it to break the block just to figure out its position

EDIT: Ofc if it can't go forward I could let it go up… But then I get into the "no breaking unnecessary blocks"-problem.

EDIT 2: What I could do is just print a line for the user that the turtle must be able to move to check its pos…
Ditto8353 #4
Posted 18 October 2012 - 08:29 PM
if it can't move forward, try backward.
If it can't move backward then turn to either side and try forward then backward again.
If all 4 directions fail then move up one and start over… Or error out.
jag #5
Posted 18 October 2012 - 08:41 PM
Yeah, gonna try that!
if it can't move forward, try backward.
If it can't move backward then turn to either side and try forward then backward again.
If all 4 directions fail then move up one and start over… Or error out.
Thanks for the tip!
jag #6
Posted 18 October 2012 - 09:02 PM
I got a code now:
Spoiler
rednet.open("right")
local posX, posY, posZ = gps.locate(.5)
local curX, curY, curZ = posX, posY, posZ
rednet.close("right")
if not posX then
  print("Could not locate position!")
  return
end

function checkGPS()
  rednet.open("right")
  curX, curY, corZ = gps.locate(.5)
  rednet.close("right")
end

function checkDir()
  if curX ~= posX then
    if curX < posX then
      dir = 3
    elseif curX > posX then
      dir = 1
    end
  elseif curZ ~= posZ then
    if curZ < posZ then
      dir = 2
    elseif curZ > posZ then
      dir = 0
    end
  end
end

if not turtle.forward() then
  if not turtle.back() then
    turtle.turnRight()
    if not turtle.forward() then
      if not turtle.back() then
        turtle.turnLeft()
        print("No empty space found!")
        return
      else
        checkGPS()
        checkDir()
        while not turtle.forward() do
          if not turtle.dig() then
            turtle.attack()
          end
        end
        turtle.turnLeft()
      end
    else
      checkGPS()
      checkDir()
      for q = 1, 2 do
        turtle.turnRight()
      end
      while not turtle.forward() do
        if not turtle.dig() then
          turtle.attack()
        end
      end
      turtle.turnRight()
    end
  else
    checkGPS()
    checkDir()
    while not turtle.forward() do
      if not turtle.dig() then
        turtle.attack()
      end
    end
    turtle.turnLeft()
  end
else
  checkGPS()
  checkDir()
  for w = 1, 2 do
    turtle.turnRight()
  end
  while not turtle.forward() do
    if not turtle.dig() then
      turtle.attack()
    end
  end
  turtle.turnRight()
end
It's not the most beautiful piece of code, but it will do.

And to be clear: This has not been tested yet!