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

Trying To Get Some Inserted Sorting Code To Work With A Turtle.

Started by 25hz, 22 October 2013 - 06:30 PM
25hz #1
Posted 22 October 2013 - 08:30 PM
Hi :)/>

I started learning Lua to write script for turtles. I went through a bunch of the Youtube tutorials and have written some basic movement and mining scripts. I also have some other mining, quarry, xzy goto, and tree farm scripts that I've modified a little.

I started coding some house building, but I need a sorting function for the turtle inventory. Right now, I have to select() specific turtle slots to pull blocks from, and I have to count the blocks used so I know when to select() the next inventory slot. This makes it more cumbersome to code, but also to use the script and load up the turtle inventory at the start.

What I want to do is use getItemCount() or getItemSpace() to determine how much is left in a slot's stack, and then transfer items to the main slots. If I only use 3 or 4 block types (for example), the rest of the inventory space can have more building blocks, but it doesn't matter which slot the extra blocks are in. The function can compare the "main slot" blocks to the "storage slot" blocks, and if they are the same, top up the stack of the "main slots". I searched this forum and on the net for a sorting script, and only found this one. It's coded by Ashvathaman on youtube, and his pastebin is CS9S6CGq. I added comments to the code to list what "I" think the parts of code are doing. His function that I'd like to use is this:


local function sorting()
local space = 0
local items = 0
for n=1,8 do ----- "n" is referencing whichever of the first 8 slots is selected
	turtle.select(n) ----- whichever slot is currently selected
	if turtle.getItemCount(n) >40 then
		space = turtle.getItemSpace(n) ----- asking for how much space is left in the stack
		if space ~= 0 then
			for m=7,15 do ----- not sure what defines "m"  Is it the other slots that hold the extra blocks from 7 to 15?
				if turtle.compareTo(m) then ----- this compares the 7 to 15 slot to one of the first 6 slots with building blocks, and if it is the same it gets selected?
					turtle.select(m) ----- this selects on of the "storage slots"?
					items = turtle.getItemCount(m) ----- gets the item count of the storage stack it just compared?
					if items > space then ----- if the # of items are more than the space in the original stack
						turtle.transferTo(n, space) ----- either tops up the "main slot" stack, or
					else
						turtle.transferTo(n, items) ----- transfers the entire storage stack to the "main slot"?
					end
				end
			end
		end
	end
end
end

I've used his code to build a couple houses and it's works awesome, especially the inventory management, which is why I'd like to use it :)/>/>/>/>/> I checked through it and it doesn't seem to use any other functions that I don't have in my script, but it doesn't work. The only other part of his code that calls this function is this:


for k=1,14 do
	for i=1,12 do
		for j=1,12 do
			placed = placed + 1
			if house[placed] == nil then
				return
			end
			if house[placed] ~= 0 then
				turtle.select(house[placed])
				turtle.placeDown()
				used = used + 1
				if used == 16 then
					used = 0
					sorting()
				end
			end
			if j ~= 12 then
				tryForward()
			end
		end
		if i ~= 12 then
			if math.fmod(i, 2) == 0 then
				turtle.turnRight()
				tryForward()
				turtle.turnRight()
			else
				turtle.turnLeft()
				tryForward()
				turtle.turnLeft()
			end
		end
	end
	turtle.turnLeft()
	for m=1,11 do
		tryForward()
	end
	turtle.turnLeft()
	tryUp()


The fmod stuff is pretty much over my head, and I think he uses it to define the blocks to use, the slots to select and the type of movement of the turtle. If that's the case, it's an amazingly compact script for the kind of house it builds. I think, possibly, that by changing the fmod values, if I could decifer what they all mean, you could build just about any house style, while leaving the main code "engine" untouched. Pretty amazing, to me.

http://www.youtube.com/watch?v=1YGqgPFH2Lo

Any help would be appreciated in getting the sorting() function to work.

Thanks :)/>

EDIT: Also, I think I understand that "local" parameters and functions only operate inside the "container" that they are defined in. So for example, the "space" and "items" parameters have no value, and aren't modified or recorded, outside the "sorting()" function, correct?
Edited on 22 October 2013 - 08:12 PM
Bomb Bloke #2
Posted 23 October 2013 - 05:11 AM
It appears that the sorting script checks each of the first eight slots. If one already has more then 40 items, it tries to top it up using whatever stack in slots 7-15 matches.

I would assume you'd want to check for at least one item instead of 40. I'd also assume that you'd want to check slots 9-15 for spare resources. To say more then that, you'd have to show your implementation along with an explanation as to what it does do, and how this differs from what you want.

The fmod stuff is pretty much over my head,
In a nutshell, it performs division and returns the remainder (known as the "modulus"). math.fmod(35, 6) returns 5, for example. He's basically using it to determine if i is an odd number (if 1 is left over after dividing by 2, then the original was odd). The turtle hence turns left/right/left/right/etc… as i increments (the actual house design has less to do with this and more to do with what's in the "house" table which tells it what blocks to use).

You can do something similar (but a little less processor-intensive) with bit.band under some circumstances, eg if the number you want to "divide" with is a power of two. math.fmod(i, 2) returns the same thing as bit.band(i, 1) for eg. Ignore this if you've no knowledge of bitwise operators, but on the off chance that you've used them it may help explain the concept of what fmod is doing.

EDIT: Also, I think I understand that "local" parameters and functions only operate inside the "container" that they are defined in. So for example, the "space" and "items" parameters have no value, and aren't modified or recorded, outside the "sorting()" function, correct?
Pretty much. Attempting to reference them from anywhere else would show them as "nil". That the function they're in is local means that that function can only be accessed by that script - if it were not, after running the script OTHER scripts would be able to call it too (until the computer rebooted).

Along with generally keeping RAM neat and tidy, this lets you create a whole bunch of functions in the one script which use the same variable names without interfering with each other. Note that when creating eg a "for" loop, the counter variable used is automatically local to that loop.
25hz #3
Posted 23 October 2013 - 04:39 PM
Thanks for the answer.

About the "local" - I misread the description on it then. I thought a local parameter was confined to the function it was paired with. I didn't realize it could still be accessed by the entire script, but no other scripts/programs outside of that. At the same time, I didn't realize any non-local parameters could be accessed outside of the script they reside in. I can understand now how the non-local parameters could create a very cluttered environment outside the script. If one was clever though, I imagine that good coders can use this to their advantage when they can poach a function or parameter from the environment instead of having to write the code in the script/program itself.

About the sorting function - I was just trying to run the function when one of the main, selected stacks (ie the first 4 slots, all starting with a 64 stack) got down to a value of about 5. I too thought 40 was too high. When I tried to use the sorting script, nothing happened when I called it.

I tried to make my own sorting function by making a function called select1(), select2(), etc that selected that slot, and tracked how many times a certain slot was used, and when it got to a count of 59, it would run the sort function, find a comparable block stack, and top the main slot back up to 64, or copy the entire remainder of the storage slot stack if it would fit. In short order, the functions got deep enough that I couldn't keep track of what it was I was doing, and unsurprisingly, the functions didn't work. So, when I came across the one I posted above, it seemed to be doing pretty much exactly what I was trying to do. It obviously works great for his script, and from what I could tell, it didn't seem to be calling anything outside the function itself, so I was hoping I could get it to work for me too. I was trying to get the function to work as a stand alone function, by assigning the turtle.select(n) with an actual value to test it. If that worked, then I could call from another function when the stack got down to 5. Didn't work though - hence my post :)/>
Bomb Bloke #4
Posted 23 October 2013 - 05:27 PM
About the "local" - I misread the description on it then. I thought a local parameter was confined to the function it was paired with. I didn't realize it could still be accessed by the entire script, but no other scripts/programs outside of that.
That's not quite what I said.

If a variable is declared as local, then only that script may access it.

If a variable is declared as local inside a function in a script, then only that function in that script may access it.

Functions themselves can and should themselves be declared as local. They're loaded into RAM in much the same way as variables, tables, etc.

Global variables and functions may be accessed from other scripts once the script that defines them has been run at least once. Generally you should declare all of them as local.

About the sorting function - I was just trying to run the function when one of the main, selected stacks (ie the first 4 slots, all starting with a 64 stack) got down to a value of about 5. I too thought 40 was too high. When I tried to use the sorting script, nothing happened when I called it.
Indeed. I'm assuming you've already fixed it, but if not, you would either have to lower the check from 40 to something like 1, or call the function before your stacks fell to a value of 40 or less in size (as opposed to 5).
25hz #5
Posted 23 October 2013 - 08:14 PM
About the local - ok, I get it. So if it is declared local in a function, it is local only to the function, but if it is declared local outside of a function, anywhere in the script, it is local only to the script. Yes? Cool.

About the sorting function, no, still haven't got it working, regardless of the value size. I'll just have to continue writing the functions out individually and changing slots manually until I figure out how to make a sorting function that works, or figure out how to get that one to work.
jay5476 #6
Posted 23 October 2013 - 09:03 PM
well this could be used


local function sort(usedItems)
usedItems = usedItems or 1
  for cSlot = 1, usedItems do -- go through these slots
	turtle.select(cSlot)
	local space = turtle.getItemSpace(cSlot)
	for rSlot = usedItems+1,16 do
	  if turtle.compareTo(rSlot) then
	    turtle.select(rSlot)
		turtle.transferTo(cSlot,space)
	  end
	end
	sleep(0)
  end
end
sort(8)
that should work but is untested