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

exterminator wanted...

Started by etopsirhc, 15 December 2012 - 07:57 PM
etopsirhc #1
Posted 15 December 2012 - 08:57 PM
yeah, i have a bug that is seriously eluding, but heres the workup to whats happening.

i'me making a move api / psudo-class to make my turtle get around a bit easier , and making them a little smarter about getting to a place than go up X go forward Y and so on, i have it setup so it will store relitive or if set , global positioning and move to that location. but when an obstical is in the way it should stop trying to go that way and try moving in one of the other posible directions it needs to go to get to the destination. currently it kinda does that. it will try and take another path, but never go back and try to finish the other direction.

it would be great if i could have some one look over my code and try to fix it ^^;


same code here for easy turtle copying http://pastebin.com/zLJDCC10

move = {
direction = 0,
currentX = -1,
currentY = -1,
currentZ = -1,
persistant = true,
gps = false
}

function move.init()
  return move
end

function init()
  return move
end

-- 0 = z+
-- 2 = z-
-- 1 = x-
-- 3 = x+

function move.to(x,y,z)
  xmoves = move.currentX + x
  ymoves = move.currentY + y
  zmoves = move.currentZ + z
  print(xmoves .." ".. ymoves .." "..zmoves)
  while xmoves ~= 0 or ymoves ~= 0 or zmoves ~= 0 do
    xstuck = false
    ystuck = false
    zstuck = false
    print(xmoves .." ".. ymoves .." "..zmoves)

    if ymoves < 0 then
	  print("ymoves less than 0")
	  while ystuck == false and ymoves ~= 0 do
	    if turtle.down() then
		  move.currentY = move.currentY - 1
		  ymoves = ymoves + 1
	    else
		  ystuck = true
	    end
	  end
    end

    if xmoves > 0 then
    print("xmoves greater than 0")
	  move.face(3)
	  while xstuck == false and xmoves ~= 0 do
	    if turtle.forward() then
		  move.currentX = move.currentX + 1
		  xmoves = xmoves - 1
	    else
		  xstuck = true
	    end
	  end
    elseif xmoves < 0 then
	  print("xmoves less than 0")
	  move.face(1)
	  while xstuck == false and xmoves ~= 0 do
	    if turtle.forward() then
		  move.currentX = move.currentX - 1
		  xmoves = xmoves + 1
	    else
		  xstuck = true
	    end
	  end
    end

    if zmoves > 0 then
	  print("zmoves greater than 0")
	  move.face(2)
	  while zstuck == false and zmoves ~= 0 do
	    if turtle.forward() then
		  move.currentZ = move.currentZ - 1
		  zmoves = zmoves - 1
	    else
		  zstuck = true
	    end
	  end
    elseif zmoves < 0 then
	  print("zmoves less than 0")
	  move.face(0)
	  while zstuck == false and zmoves ~= 0 do
	    if turtle.forward() then
		  move.currentZ = move.currentZ + 1
		  zmoves = zmoves + 1
	    else
		  zstuck = true
	    end
	  end
    end

    if ymoves > 0 then
	  print("ymoves greater than 0")
	  while ystuck == false and ymoves ~= 0 do
	    if turtle.up() then
		  move.currentY = move.currentY + 1
		  ymoves = ymoves - 1
	    else
		  ystuck = true
	    end
	  end
    end
  end
  zmoves = 0
  xmoves = 0
  ymoves = 0
end

function move.face(f)
  if plus(move.direction,1) == f then
	 turtle.turnRight()
	 move.direction = plus(move.direction,1)
  elseif minus(move.direction,1) == f then
	 turtle.turnLeft()
	 move.direction = minus(move.direction,1)
  elseif f == move.direction then
    -- -_-/> really?
  else
    turtle.turnLeft()
    turtle.turnLeft()
    move.direction = minus(move.direction,2)
  end
end

-- directional math
function minus(x,y)
  if x - y < 0 then
    r2 = 0
    for r1=x-y,0,1 do
	  r2 = r2 + 1	  
    end
    return 4-r2
  else
    return x-y
  end
end

function plus(x,y)
  if x + y > 3 then
    r = x+y
    while r > 3 do
	  r = r - 4
    end
    return r
  else
    return x+y
  end
end
theoriginalbit #2
Posted 15 December 2012 - 09:06 PM
From a quick read over and without running it it all looks good.

I will investigate more. How is it being called in test code?

also just an FYI convention is that you dont need == false or == true as the stuck variables are already booleans

while stuckBoolean  == false and ..............

while not stuckBoolean and ............ -- works just as well and is just as readable, just removes an unneeded calculation
etopsirhc #3
Posted 15 December 2012 - 09:13 PM
i was using not stuck, b4, but wheni tried i didnt think about the "not" version, i always used ~= ^^; might switch it not sure

i've been doing

os.loadAPI("move")
move = move.init()

--initilizes coordinates , just manualy untill i add the gps part to it.
move.currentX = x
--ect.

move.to(x,y,z)

it makes it work more like a class than an api, as you can store vars in it and access them w/o full function calls
theoriginalbit #4
Posted 15 December 2012 - 09:16 PM
it makes it work more like a class than an api, as you can store vars in it and access them w/o full function calls

well not "more like a class" its an object. The way you have made the API means its Object-Oriented :)/>



Anyways now that I have the way you call it, brb, testing :P/>
etopsirhc #5
Posted 15 December 2012 - 09:24 PM
object, class , meh, all works kinda the same :P/>

good luck ^^
theoriginalbit #6
Posted 15 December 2012 - 09:31 PM
object, class , meh, all works kinda the same :P/>

good luck ^^

haha yeh. getting an attempt to perform arithmetic __add on nil and table. apparently on line 24. the while line. sometimes i hate OO Lua!
etopsirhc #7
Posted 15 December 2012 - 09:35 PM
on the script it shows line 24 as the movesx = move.currentX - x , witch would be a failure to pass a variable to move.to or the move.currentX some how niled
theoriginalbit #8
Posted 15 December 2012 - 09:45 PM
on the script it shows line 24 as the movesx = move.currentX - x , witch would be a failure to pass a variable to move.to or the move.currentX some how niled

Oh yeah I have fixed that bit already. It was a declaration in your init that you missed. I also ended up optimising your directional math. I thought the issue was there, I was wrong :P/> but the code looks nice now ;)/>
etopsirhc #9
Posted 15 December 2012 - 09:47 PM
lol, well its a start :)/>
theoriginalbit #10
Posted 15 December 2012 - 09:49 PM
lol, well its a start :)/>

it is. its getting there. still trying to find this elusive one though.
etopsirhc #11
Posted 15 December 2012 - 10:06 PM
very elusive huh? i think its with the multi-condition while, but i cant seem to get it to loop again unless everything fails to move
theoriginalbit #12
Posted 15 December 2012 - 10:12 PM
very elusive huh? i think its with the multi-condition while, but i cant seem to get it to loop again unless everything fails to move

nope its not that. I got rid of the error, just testing the turtle now. the only issue i can for see is if it cant complete the last movement that it does there is no way for it to adjust
theoriginalbit #13
Posted 15 December 2012 - 10:18 PM
well I fixed it when its used within the file but its acting differently depending if the object is in the same file or not. may have to give me a little longer to figure this one out ;)/>

i optimised your directional math and it seems to have fixed one bug, and uncovered another :P/>
theoriginalbit #14
Posted 15 December 2012 - 10:23 PM
while I try to figure this out here is the new directional math. if you don't understand any of it, just ask :)/>



function minus(x,y)
r = x - y
   if r < 0 then
     return 4 - math.abs(r)
   else
     return r
   end
end

function plus(x, y)
return (x + y) % 4
end
etopsirhc #15
Posted 15 December 2012 - 10:29 PM
*scratches head* dafaq?
theoriginalbit #16
Posted 15 December 2012 - 10:37 PM
*scratches head* dafaq?

are you familiar with the modulus function? % means modulo

math.abs turns a number into a positive number
etopsirhc #17
Posted 15 December 2012 - 10:43 PM
i thin, i know what mod does , but i thought it was for getting the remainder from deviding
theoriginalbit #18
Posted 15 December 2012 - 10:49 PM
i thin, i know what mod does , but i thought it was for getting the remainder from deviding

it is, but if it can divide it returns the number. so there are 4 directions. meaning that 3 % 4 is 3 and 2 % 4 is 2. but 4 % 4 is 0 and 5%4 is 1 etc.

which is the same as your if r > 3 set r to r - 4



as for the other bug a cannot seem to figure it out sorry. :(/>

it has to be something small somewhere
theoriginalbit #19
Posted 15 December 2012 - 10:50 PM
EDIT: Oh the other thing i did to that seemed to help fix one of the bugs was changed all the move.currentX and all those variable types to self.currentX and such
etopsirhc #20
Posted 15 December 2012 - 11:01 PM
nice =D , ok , hope i can figure it out. gotta finish this b4 i can get my large scale 3d printer runing :} first print will be a 256 by 112 by 120 airship of epicness!
theoriginalbit #21
Posted 15 December 2012 - 11:10 PM
well all I can do is wish you luck and hope that maybe someone else here can figure it out :)/>
KaoS #22
Posted 15 December 2012 - 11:48 PM
I'll take a look
KaoS #23
Posted 16 December 2012 - 12:12 AM
ok. I looked and I am not sure why you are making this so complex, try to avoid so many if statements when they can all be included in your move loop. it can be crammed into literally 1/3 of the length it is. here is a basic mock up I drew


pos={x=0,y=0,z=0,dir="z"}


local function face(dir)
  local tDirs={["z"]="x",["x"]="-z",["-z"]="-x",["-x"]="z"}
  while pos.dir~=dir do
   turtle.turnRight()
   pos.dir=tDirs[pos.dir]
  end
end

local function goto(x,y,z)
  while pos.x~=x or pos.y~=y or pos.z~=z do
   face(pos.x>x and "-x" or "x")
   while pos.x~=x and turtle.forward() do
	pos.x=pos.x+(pos.dir="x" and 1 or -1)
   end

   face(pos.z>z and "-z" or "z")
   while pos.z~=z and turtle.forward() do
	pos.z=pos.z+(pos.dir="z" and 1 or -1)
   end

   while (pos.y>y and turtle.down()) or (pos.y<y and turtle.up()) do
	pos.y=pos.y+(pos.y<y and 1 or -1)
   end
  end
end

basically you use while ycurrent~=where_you_should_be and turtle.up/down() do adjust position end so the loop auto breaks if you at the correct position or the movement fails… then you keep looping all 3 directions until you are there. if you want a status display it can be done with coroutines. will post an example in a sec

EDIT: ok, with coroutines:

pos={x=0,y=0,z=0,dir='z'}
local function face(dir)
  local tDirs={["z"]="x",["x"]="-z",["-z"]="-x",["-x"]="z"}
  while pos.dir~=dir do
   turtle.turnRight()
   pos.dir=tDirs[pos.dir]
  end
end
local function c1(x,y,z)
  while pos.x~=x or pos.y~=y or pos.z~=z do
   face(pos.x>x and "-x" or "x")
   while pos.x~=x and turtle.forward() do
    pos.x=pos.x+(pos.dir="x" and 1 or -1)
   end
   face(pos.z>z and "-z" or "z")
   while pos.z~=z and turtle.forward() do
    pos.z=pos.z+(pos.dir="z" and 1 or -1)
   end
   while (pos.y>y and turtle.down()) or (pos.y<y and turtle.up()) do
    pos.y=pos.y+(pos.y<y and 1 or -1)
   end
  end
end
function goto(x,y,z)
  local co=coroutine.create(c1)
  local evts={}
  while coroutine.status(co)~="dead" do
   coroutine.resume(co,unpack(evts))
   evts={os.pullEvent()}
   if evts[1]=="turtle.response" then
    term.clear()
    term.setCursorPos(1,1)
    print(x-pos.x ..", ".. y-pos.y ..", ".. z-pos.z)
   end
  end
end
Edited on 15 December 2012 - 11:27 PM
etopsirhc #24
Posted 16 December 2012 - 12:33 AM
part of the complexity is to make it OO , and the other is cause i cant understand what you just did there @.@
black magic maybe?
theoriginalbit #25
Posted 16 December 2012 - 12:35 AM
EDIT: ok, with coroutines:

Threading isn't always the best way to go. also, don't throw the new guys into the deep end of multi-threading without at least an explanation.
etopsirhc #26
Posted 16 December 2012 - 01:24 AM
while i'm not a compleate n00b,i'm thread illiterate XP
theoriginalbit #27
Posted 16 December 2012 - 01:26 AM
while i'm not a compleate n00b,i'm thread illiterate XP

no offence by the new guys statement. just trying to point out not to throw ppl into the deep end.
etopsirhc #28
Posted 16 December 2012 - 01:53 AM
none taken , just wanted to point it out
KaoS #29
Posted 16 December 2012 - 02:25 AM
EDIT: ok, with coroutines:

Threading isn't always the best way to go. also, don't throw the new guys into the deep end of multi-threading without at least an explanation.

in this case I think it is best otherwise you would have to implement a display loop in every single moving loop.


while i'm not a compleate n00b,i'm thread illiterate XP
etopsirhc it was not my intention to confuse you or "throw the new guys into the deep end", I just prefer the policy of posting help and assuming they understand, if not then they are free to ask further questions
etopsirhc #30
Posted 16 December 2012 - 10:15 AM
i'm sure what you have works, and for a scripting language thats probably the best way to do it ,
i've just been trying to make api's for myself that makes it more object oriented like the languages i'm good at. this is one of those.

what i got was basicaly a
while not at destination
try to go up ( if needed )
try to go in X axis the needed ammount
try to go in Y axis the needed ammount
try to go down ( if needed )
if pars failed loop again

i seporated the up and down y cause in builds i will be having it move back to a refuel area for both fuel and blocks and didnt want it to get stuck inside of builds
*feels like i need try catch statements even though i know it can be done w/o *
KaoS #31
Posted 17 December 2012 - 02:16 AM
that is literally exactly what my code does except I have not separated the up and down movements. allow me to insert comments



pos={x=0,y=0,z=0,dir="z"}

local function face(dir) --I use this function to turn in the correct direction before moving in the x or z axis
  local tDirs={["z"]="x",["x"]="-z",["-z"]="-x",["-x"]="z"}
  while pos.dir~=dir do
    turtle.turnRight()
    pos.dir=tDirs[pos.dir]
  end
end

local function goto(x,y,z)  --this is the function you will be using to actually move
  while pos.x~=x or pos.y~=y or pos.z~=z do --as long as you are not at your destination keep looping

    face(pos.x>x and "-x" or "x") --turn to face the x direction, -x if your position is further along the x axis than your destination
    while pos.x~=x and turtle.forward() do --keep looping as long as you are not at the correct x position and as long as the move command is successfull
      pos.x=pos.x+(pos.dir="x" and 1 or -1) --decrease/increase the pos.x value as you move
    end

    face(pos.z>z and "-z" or "z") --same loop and pos adjustment for z
    while pos.z~=z and turtle.forward() do
      pos.z=pos.z+(pos.dir="z" and 1 or -1)
    end

    while (pos.y>y and turtle.down()) or (pos.y<y and turtle.up()) do --as long as you are not at your destination check if your y is higher than your destination, if so go down and vice versa
      pos.y=pos.y+(pos.y<y and 1 or -1) --same position adjustment for y
    end
  end
end