Jump to content




Evenly distributing items


  • You cannot reply to this topic
4 replies to this topic

#1 Things

  • Members
  • 15 posts
  • LocationAustralia

Posted 29 April 2014 - 04:11 AM

Hi all, I'm working on a pretty handy turtle program that I hope will be useful to people, but I'm having a hard time figuring out the most efficient way to go about something.

Basically, I want the turtles inventory to evenly distribute items between slots. Say if you have an iron ingot in slots 2, 3 and 5, and any number of ingots in any of those slots, I'd like to be able to distribute them evenly between all the slots already containing iron ingots. Round robin fashion, basically how the Auto crafting tables would do it.

I have some code already that creates a 2D array of which slots contain items the same as other slots, here:

for i=1,3 do
  if turtle.getItemCount(i) > 0 then
numItems[i] = turtle.getItemCount(i)
for k=1,3 do
  turtle.select(i)
  if turtle.compareTo(k) == true and i ~= k then
   sameItems[i][k] = 1
  else
   sameItems[i][k] = 0
  end
end
for k=5,7 do
  turtle.select(i)
  if turtle.compareTo(k) == true and i ~= k then
   sameItems[i][k] = 1
  else
   sameItems[i][k] = 0
  end
end
for k=9,11 do
  turtle.select(i)
  if turtle.compareTo(k) == true and i ~= k then
   sameItems[i][k] = 1
  else
   sameItems[i][k] = 0
  end
end
  end
end
for i=5,6 do
  if turtle.getItemCount(i) > 0 then
numItems[i] = turtle.getItemCount(i)
for k=1,3 do
  turtle.select(i)
  if turtle.compareTo(k) == true and i ~= k then
   sameItems[i][k] = 1
  else
   sameItems[i][k] = 0
  end
end
for k=5,7 do
  turtle.select(i)
  if turtle.compareTo(k) == true and i ~= k then
   sameItems[i][k] = 1
  else
   sameItems[i][k] = 0
  end
end
for k=9,11 do
  turtle.select(i)
  if turtle.compareTo(k) == true and i ~= k then
   sameItems[i][k] = 1
  else
   sameItems[i][k] = 0
  end
end
  end
end
for i=9,11 do
  if turtle.getItemCount(i) > 0 then
numItems[i] = turtle.getItemCount(i)
for k=1,3 do
  turtle.select(i)
  if turtle.compareTo(k) == true and i ~= k then
   sameItems[i][k] = 1
  else
   sameItems[i][k] = 0
  end
end
for k=5,7 do
  turtle.select(i)
  if turtle.compareTo(k) == true and i ~= k then
   sameItems[i][k] = 1
  else
   sameItems[i][k] = 0
  end
end
for k=9,11 do
  turtle.select(i)
  if turtle.compareTo(k) == true and i ~= k then
   sameItems[i][k] = 1
  else
   sameItems[i][k] = 0
  end
end
  end
end

So in my example with the iron ingots above, the array would contain:

[2][3], [2][5], [3][2], [3][5], [5][2], [5][3] would all be 1, everything else = 0.

Can anyone think of an efficient way of doing this? :)

#2 HometownPotato

  • Members
  • 62 posts

Posted 29 April 2014 - 04:26 AM

Why not just add them all up and divide them by the amount of slots and distribute by that number?

#3 Lyqyd

    Lua Liquidator

  • Moderators
  • 8,465 posts

Posted 29 April 2014 - 04:28 AM

This should create a table (matches) wherein each subtable contains a set of slot numbers whose contents all match each other:

local slots = {}
--# fill a table with the sixteen slot IDs.
for i = 1, 16 do
    slots[i] = i
end

local matches = {}

while #slots > 0 do
    --# get the next slot number from the slot ID table
    local current = table.remove(slots, 1)
    --# create a new match set including it.
    local match = {current}
    turtle.select(current)
    --# check the contents of that slot against the remaining unmatched slots.
    for i = #slots, 1, -1 do
        if turtle.compareTo(slots[i]) then
            table.insert(match, table.remove(slots, i))
        end
    end
    --# sort the slot IDs in the current set of matches (optional)
    table.sort(match)
    --# add the current set of matches to the final table.
    table.insert(matches, match)
end


#4 Things

  • Members
  • 15 posts
  • LocationAustralia

Posted 29 April 2014 - 04:39 AM

Hmm, much better way of doing the table, thanks :)

View PostHometownPotato, on 29 April 2014 - 04:26 AM, said:

Why not just add them all up and divide them by the amount of slots and distribute by that number?

This is what I was thinking, though having a hard time actually putting it into code :(

#5 Things

  • Members
  • 15 posts
  • LocationAustralia

Posted 29 April 2014 - 09:56 AM

View PostLyqyd, on 29 April 2014 - 04:28 AM, said:

This should create a table (matches) wherein each subtable contains a set of slot numbers whose contents all match each other:


So I've been messing with your code, and it seems to be doing exactly what I want, however I seem to be having some issues accessing the arrays. The code (set to ingore empty slots)

local slots = {}
--# Fill a table with the sixteen slot IDs.
for i = 1, 16 do
	slots[i] = i
end
local matches = {}
while #slots > 0 do
	--# Get the next slot number from the slot ID table
	local current = table.remove(slots, 1)
	--# Create a new match set including it.
if turtle.getItemCount(current) > 0 then
	local match = {current}
	turtle.select(current)
	--# Check the contents of that slot against the remaining unmatched slots.
	for i = #slots, 1, -1 do
		if turtle.compareTo(slots[i]) then
			table.insert(match, table.remove(slots, i))
		end
	end
	--# Sort the slot IDs in the current set of matches (optional)
	table.sort(match)
	--# Add the current set of matches to the final table.
	table.insert(matches, match)
end
end
for i = 1,#matches do
for k = 1,#matches[1] do
print(string.format("Match %d: %d", i, matches[i][k]))
end
end

Which, with this inventory config, gives me:

Posted Image

Not sure why it's getting stuck on the single entries?

EDIT: Oops, I'm an idiot.

for k = 1,#matches[1] do

should be

for k = 1,#matches[i] do

Edited by Things, 29 April 2014 - 11:18 AM.






1 user(s) are reading this topic

0 members, 1 guests, 0 anonymous users