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

Duplicating variables problem

Started by zeronoashaen, 30 January 2014 - 03:49 PM
zeronoashaen #1
Posted 30 January 2014 - 04:49 PM
Here is my code:


os.loadAPI("ocs/apis/sensor")
os.loadAPI("ocFunc")

monitor = peripheral.wrap("right")


--*********Variables**********
sensorSide = ocFunc.sensorSide()

curPlayer = ocFunc.playerName(sensorSide)

--**********Helper Functions**********
function newLine(monitor)
   local _,cY = monitor.getCursorPos()
   local _,mY = monitor.getSize()
   if cY==mY then
	  monitor.clear()
	  monitor.setCursorPos(1,1)
   else
	  monitor.setCursorPos(1,cY+1)
   end
end

function table_count(tt, item)
   local count
   count = 0
   for i=1,#tt do
	  if item == tt[i].RawName then
		 count = count + 1
	  end
   end
   return count
end

items = {}

invPlayer = false

sellItems = ocFunc.playerInventory(sensorSide, curPlayer)

if sellItems[1] then
   invPlayer = true
end

if invPlayer then
   for i=1,#sellItems do
	  count = table_count(items, sellItems[i].RawName)
	  if count == 1 then
		 inv = sellItems[i].RawName
		 for j=1,#items do
			item = items[j].RawName
			if item==inv then
			   local itemSize = tonumber(items[j].Size)
			   local sellSize = tonumber(sellItems[i].Size)
			   monitor.write("Items: "..itemSize.." + SellItems: "..sellSize.." ")
			   items[j].Size = tonumber(itemSize + sellSize)
			   monitor.write("Items: "..items[j].Size)
			   newLine(monitor)
			end
		 end
	  else
		 table.insert(items, sellItems[i])
	  end
   end
end

The problem I am having is that sellItems.Size becomes the same size as items[j].Size if the stack size is the same as one that went through previously. so if I have 4 stacks of 64 it goes 64+64 = 128 like it should, but the next time it is 128+128 which is obviously wrong.
CometWolf #2
Posted 30 January 2014 - 05:04 PM
tbh i have no idea what this code is supposed to do… anyways,

						   local itemSize = tonumber(items[j].Size)
						   local sellSize = tonumber(sellItems[i].Size)
						   items[j].Size = tonumber(itemSize + sellSize) -- your changing the value which you add, to the result from the addition here. So everytime you run the loop, it will just get bigger and bigger.
zeronoashaen #3
Posted 30 January 2014 - 05:08 PM
What this code does is search through a players inventory and finds all items in the inventory, once it does that it goes through and finds any duplicates and adds the sizes together so that I can only have one of the item type in a new table. For instance if I have 3 stacks of Iron Blocks plus 61, it should insert the first one into the items table then add the sizes of the other stacks onto it's size. The problem I have is that for some reason the sellSize is becoming the same as the itemSize variable if the size of the stack is the same as one that went through the system previously. for example in the above example it would find the first stack and put it into the table, then find the second stack and add it correctly, the third stack of 64 however will be changed to 128 instead and then added onto the size, lastly the stack of 61 will add find since there wasn't another stack of the same size previously.
Edited on 30 January 2014 - 04:11 PM
CometWolf #4
Posted 30 January 2014 - 05:25 PM
I must be really tired or something lol, this isn't making much sense to me… Anyways, i found the problem

		  else
				 table.insert(items, sellItems[i])
		  end
This will make items and sellItems point to the same table.
Here's an example to show you what i mean

sellItems = {
  [1] = {
	["size"] = 5
  }
}
items = {
  [1] = sellItems[1]
}
items[1].size = items[1].size+5
print(sellItems[1].size) -- this will print 10

to fix this you'll have to do the following instead

for k,v in pairs(sellItems[i]) do
  items[i][k] = v
end
This is called a deep copy, and copies the values within the table instead of the table itself.

Why this would only affect same numbered sizes however, idk.
Edited on 30 January 2014 - 04:27 PM
zeronoashaen #5
Posted 30 January 2014 - 05:35 PM
Will that still work if the table has more than two values in it? For instance the sellItems table gives you the name, damage value, max stack size, the raw name, and the size of the stack.
CometWolf #6
Posted 30 January 2014 - 05:41 PM
Yeah, the pairs iterator iterates through all the keys in the table, so unless there's another table inside that table, it should be good.
just realized you'll probably have to define items as a table beforehand however, so

items[i] = {}
for k,v in pairs(sellItems[i]) do
  items[i][k] = v
end
Edited on 30 January 2014 - 04:42 PM
zeronoashaen #7
Posted 30 January 2014 - 05:45 PM
The table has tables in it. each item in the table gives the above information. so sellItems[1] gives you the info for the blocks in slot 1 of your inventory, sellItems[2] gives you the info for slot 2 in your inventory, etc. etc.
CometWolf #8
Posted 30 January 2014 - 06:10 PM
Yeah i know that, copying the full table wouldn't make much sense… This is why i used (sellItems) in the iterator.
i meant if there was a table within those again.
zeronoashaen #9
Posted 31 January 2014 - 02:29 AM
oh, no there isn't. so you are suggesting changing

table.insert(items, sellItems[i])
to

items[i]={}
for k,v in pairs(sellItems[i]) do
   items[i][k] = v
end
but since my code is trying to take out all duplicates wouldn't that leave nil spaces in the array, since not all of the "i" 's will be going into the items array?
Edited on 31 January 2014 - 01:30 AM
Bomb Bloke #10
Posted 31 January 2014 - 03:36 AM
So instead of putting them into items, define a new table at items[#items+1] and then place the contents of sellItems into items[#items].