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

New Project- Need Some Help And Advice.

Started by dom123, 29 October 2013 - 07:27 AM
dom123 #1
Posted 29 October 2013 - 08:27 AM
So I want to build a turtle that will take advantage of a small exploit with oak trees. Seeing as they can grow without any height checking to make was mass lump when you plant:



I want to make a turtle that will harvest the mass and return all it picks up then replanting everything

it built one code using my limited skills
pseudo code: http://pastebin.com/hJrVKinT
Actual code: http://pastebin.com/yZ12XKea
but it is long- clunky-

in theory no test yet. it has one issues that i can see right away it replants bottom-left to top-right. when it returns it could easily run into new trees that have grown in the few min it takes. Which really isn't a problem because it could .dig as it returns to stop from getting stuck. Pleas take a look at the code and help me hammer something out I am willing to start from scratch on the code if we need to.

i just started with computer craft 3 days ago so I am sorry for such a long request and so much information.

<any suggested changes please post the code you would use and tell me what you would replace>
i am just as eager to learn as i am to get this code working reliably and properly.
theoriginalbit #2
Posted 29 October 2013 - 10:42 AM
i just started with computer craft 3 days ago so I am sorry for such a long request and so much information.
Don't be sorry about this. More information is better! The more information you've supplied means that
1. you've actually taken the time and effort into thinking about what you want (read the fabulous quote by Lyqyd in my signature);
2. you are going to be heading into the project with a better mindset than most others;
3. We can provide you with better more accurate help as we have more information about the "problem" domain;

What you've done is definitely a good start. Some improvement notes:
1. Localise your variables and functions, it doesn't pollute the environment for other programs after yours has finished and it makes it a little bit more efficient because of the way Lua deals with global and local variables
2. You've got a nice usage of functions, but consider making more, breaking down each "task" into even smaller ones until you've got only "core tasks" that cannot be broken down more. Ideally you should be aiming for most of your functions to be, lets say less than 15 lines long (just as a rough guideline of how much you should want to break things down). This is whats known in computer science as [functional] decomposition.
3. Avoid some repetition by implementing the above suggestion and just calling the function instead of repeating logic and/or code. A good function to implement would be one for each turtle movement where you can supply a number on how many time you wish it to move in that direction.
4. Remove all the == true, if a function returns a boolean why bother checking if it is a boolean, does this really make much sense? true == true… just use the functions return result. As an added extra, in Lua, when any value other than false or nil is within a conditional it will resolve to true, if it is false or nil it will resolve to false, meaning that if "hello" then will resolve to true and execute the "true" fork.
5. Remove all the == false and place the not keyword in front of the conditional. Example if not turtle.forward() then is the same as if turtle.forward() == false then. Not simply flips the boolean, so true becomes false and false becomes true. The same logic as stated in 4 also works so you could say if not "hello" then which would always execute the "false" fork as "hello" resolves to true and is then flipped.
6. Take a look into how the "excavate" program works as it will allow you to severely compact your code that turns and completes a level, to the point that implementing something like it will also allow for a variable size as opposed to a static 12x12.
7. Its good that you thought of the fuel saving of getting the Turtle to mine 2 layers at once, but why not have it do 3 (up/down/front)?
8. I think planting the saplings back down after its got to the top and come back down would be a good idea so as to avoid the tree growth problem.
9. Last but not least, since as you stated the Oak trees can grow as tall as they wish, I think that if you implemented a tracking method on each "layer" to see whether it has "mined" a block would allow for your Turtle to dynamically know when it has reached the top of the tree cluster, i.e. it didn't mine any blocks on that layer, assuming you don't have a roof over them of course.
spdkils #3
Posted 29 October 2013 - 11:50 AM
I write things as a single step, and put it into a function, then just loop it… for example.

function fnDig()
-- Do my dig thing
  while not turtle.forward() do
	if not turtle.dig() then
	 turtle.attack()
	end
  end
end

Then I just loop that function with a simple 3 way loop.

for h=1,height do
  for w=1,width do
   for d=1,depth do
-- Do my 1 step dig!!!
  fnDig()
end
-- Do a turn function right or left!
end
-- Do a up/down function to dig/harvest up or down.
end

Then if you want to replant at the end, you can write 1 layer funciton to plant, etc.

That is how I would approach it.
dom123 #4
Posted 29 October 2013 - 12:22 PM
i just started with computer craft 3 days ago so I am sorry for such a long request and so much information.
Don't be sorry about this. More information is better! The more information you've supplied means that
1. you've actually taken the time and effort into thinking about what you want (read the fabulous quote by Lyqyd in my signature);
2. you are going to be heading into the project with a better mindset than most others;
3. We can provide you with better more accurate help as we have more information about the "problem" domain;

What you've done is definitely a good start. Some improvement notes:
1. Localise your variables and functions, it doesn't pollute the environment for other programs after yours has finished and it makes it a little bit more efficient because of the way Lua deals with global and local variables
2. You've got a nice usage of functions, but consider making more, breaking down each "task" into even smaller ones until you've got only "core tasks" that cannot be broken down more. Ideally you should be aiming for most of your functions to be, lets say less than 15 lines long (just as a rough guideline of how much you should want to break things down). This is whats known in computer science as [functional] decomposition.
3. Avoid some repetition by implementing the above suggestion and just calling the function instead of repeating logic and/or code. A good function to implement would be one for each turtle movement where you can supply a number on how many time you wish it to move in that direction.
4. Remove all the == true, if a function returns a boolean why bother checking if it is a boolean, does this really make much sense? true == true… just use the functions return result. As an added extra, in Lua, when any value other than false or nil is within a conditional it will resolve to true, if it is false or nil it will resolve to false, meaning that if "hello" then will resolve to true and execute the "true" fork.
5. Remove all the == false and place the not keyword in front of the conditional. Example if not turtle.forward() then is the same as if turtle.forward() == false then. Not simply flips the boolean, so true becomes false and false becomes true. The same logic as stated in 4 also works so you could say if not "hello" then which would always execute the "false" fork as "hello" resolves to true and is then flipped.
6. Take a look into how the "excavate" program works as it will allow you to severely compact your code that turns and completes a level, to the point that implementing something like it will also allow for a variable size as opposed to a static 12x12.
7. Its good that you thought of the fuel saving of getting the Turtle to mine 2 layers at once, but why not have it do 3 (up/down/front)?
8. I think planting the saplings back down after its got to the top and come back down would be a good idea so as to avoid the tree growth problem.
9. Last but not least, since as you stated the Oak trees can grow as tall as they wish, I think that if you implemented a tracking method on each "layer" to see whether it has "mined" a block would allow for your Turtle to dynamically know when it has reached the top of the tree cluster, i.e. it didn't mine any blocks on that layer, assuming you don't have a roof over them of course.

ok i can clean up my code alot now… in the code it includes both functions for a 2 layer cut and a 3 layer cut.


function FirstCutForward()
	    x = 0
	    while x < 13 do
			    while turtle.detect() do
					    turtle.dig()
					    turtle.attack()
			    end
			    if turtle.forward() then
					    x = x + 1
			    end
			    turtle.digUp()
			    if turtle.getFuelLevel() < 2 then
					    if turtle.getItemCount(16) == 1 then
							    turtle.select(16)
							    turtle.refuel(1)
							    turtle.turnRight()
							    turtle.turnRight()
							    turtle.select(15)
							    if turtle.place() == true then
									    turtle.place()
									    turtle.select(16)
									    turtle.suck()
									    turtle.select(15)
									    turtle.dig()
							    end
							    turtle.turnRight()
							    turtle.turnRight()
					    else
							    turtle.select(16)
							    turtle.refuel(1)
					    end
			    end
			    if turtle.getItemCount(13) > 0 then
					    turtle.turnRight()
					    turtle.turnRight()
					    turtle.select(14)
					    if turtle.place() == true then
							    for i = 1, 13 do
									    turtle.select(i)
									    turtle.drop()
							    end
							    turtle.select(14)
							    turtle.dig()
					    end
					    turtle.turnRight()
					    turtle.turnRight()
			    end
	    end
end

function CutForward()
	    x = 0
	    while x < 13 do
			    while turtle.detect() do
					    turtle.dig()
					    turtle.attack()
			    end
			    if turtle.forward() then
					    x = x + 1
			    end
			    turtle.digUp()
			    turtle.digDown()
			    if turtle.getFuelLevel() < 2 then
					    if turtle.getItemCount(16) == 1 then
							    turtle.select(16)
							    turtle.refuel(1)
							    turtle.turnRight()
							    turtle.turnRight()
							    turtle.select(15)
							    if turtle.place() == true then
									    turtle.place()
									    turtle.select(16)
									    turtle.suck()
									    turtle.select(15)
									    turtle.dig()
							    end
							    turtle.turnRight()
							    turtle.turnRight()
					    else
							    turtle.select(16)
							    turtle.refuel(1)
					    end
			    end
			    if turtle.getItemCount(13) > 0 then
					    turtle.turnRight()
					    turtle.turnRight()
					    turtle.select(14)
					    if turtle.place() == true then
							    for i = 1, 13 do
									    turtle.select(i)
									    turtle.drop()
							    end
							    turtle.select(14)
							    turtle.dig()
					    end
					    turtle.turnRight()
					    turtle.turnRight()
			    end
	    end
end
you will see in the first function it only does current level and top level. this is because i don't want to destroy the dirt below him that the trees grow on and when he goes up his first level he starts using the second function in place, as it cuts down, current, and above levels.

is the excavate code online anywhere i have been having a hard time finding any reference to it.
spdkils #5
Posted 29 October 2013 - 01:29 PM
You can find the excavate code in rom/programs/turtle

1: turtle.detect() only detects solid blocks. So don't bother to attack if you detect… I made that mistake myself early on too!
2: turtle.detect() returns true/false so you don't have to use == on if statements. (if turtle.detect() then) will work.
3: turtle.place() is the same… you can shorten it to "if turtle.place() then"
4: you get a lot of speed by using turtle.select(x) sparingly. in your "drop" loop. I would spend the time to ensure you need to drop before you bother to select, it will run faster.


for i=1, 13 do
  if turtle.getItemCount(i) > 0 then
	turtle.select(i)
	turtle.drop()
  end
end

Turtle selects are pretty slow, but just looping looking is way faster.

Moving works pretty well if you use a while not type loop on a movement.


while not turtle.forward() do
  if turtle.detect() then
	turtle.dig()
  else
   turtle.attack()
  end
end

or you can do a while loop on the steps, and loop the move/detect/dig


while steps < maxsteps do
if not turtle.forward() then
if turtle.detect() then
  turtle.dig()
else
  turtle.attack()
end
end
steps=steps +1
end

lots of ways to handle that problem.