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

Adding variables to a table depending on variables on another table

Started by remiX, 12 January 2013 - 09:13 AM
remiX #1
Posted 12 January 2013 - 10:13 AM
Not sure how to word the title but my problem is that I have a table with x and y co-ords that are 'walls' for a game which you can go through, thats fine. What I want to do is add other things that are not within the co-ords of the table full of x and y co-ords for the walls.

I'm trying to add the co-ords to the table using loops so I don't have to add them myself but it's failing terribly:

I am able to get it to add the co-ords of the exact co-ords within the table of the walls but I want the opposite, to add the co-ords that doesn't match the ones in the walls table.

This code that matches the co-ords within the walls table.

As you can see, I have it do this:

for sx = 2, 40 do
  for sy = 2, 5 do
	for i = 1, #t_gameWalls do
	  if sx == t_gameWalls[i].x and sy == t_gameWalls[i].y then
		table.insert(t_gameDots, {x = sx, y = sy, eatan = false})
		break
	 end
	end
  end
end

Spoiler

That then adds the same co-ords as the one's in the t_gameWalls table, but I want it to do the opposite, so i tried this code:

for sx = 2, 40 do
  for sy = 2, 5 do
	for i = 1, #t_gameWalls do
	  if not ( sx == t_gameWalls[i].x and sy == t_gameWalls[i].y ) then -- only changed this
		table.insert(t_gameDots, {x = sx, y = sy, eatan = false})
		break
	 end
	end
  end
end

Which caused it to add in every space possible:

Spoiler

What I want can be achieved if I draw the t_gameWalls after the t_gameDots table but then the t_gameDots has extra unnecessary indexes.

This is what I want:

Spoiler

Not sure if I explained it properly, hope I did.
GravityScore #2
Posted 12 January 2013 - 12:54 PM
Not sure if this will work (I haven't tested it), but instead of this:

if not ( sx == t_gameWalls[i].x and sy == t_gameWalls[i].y )

Try this:


if sx ~= t_gameWalls[i].x and sy ~= t_gameWalls[i].y

This might not have any affect whatsoever though :P/>
crazyguymgd #3
Posted 12 January 2013 - 03:55 PM


addFood = true

for sx = 2, 40 do
  for sy = 2, 5 do
    for i = 1, #t_gameWalls do
       if sx == t_gameWalls[i].x and sy == t_gameWalls[i].y then
       addFood = false  
       end
     end
     if addFood then
       table.insert(t_gameDots, {x = sx, y = sy, eatan = false})
     end
     addFood = true
  end
end

That's how I got it to work. To understand why yours was failing, take this scenario:
sx = 3, sy = 3 is a position with a wall, you detect that, break out of the loop and move on.
The next step, sx = 3, sy = 4, and there is another wall there, however, there is also a wall at 3,3 which is not 3,4 so it adds the dot. Does that make sense?
remiX #4
Posted 12 January 2013 - 10:41 PM
Not sure if this will work (I haven't tested it), but instead of this:

if not ( sx == t_gameWalls[i].x and sy == t_gameWalls[i].y )

Try this:


if sx ~= t_gameWalls[i].x and sy ~= t_gameWalls[i].y

This might not have any affect whatsoever though :P/>

Yeah I did try that :P/> Adds a dot to each space too



addFood = true

for sx = 2, 40 do
  for sy = 2, 5 do
	for i = 1, #t_gameWalls do
	   if sx == t_gameWalls[i].x and sy == t_gameWalls[i].y then
	   addFood = false  
	   end
	 end
	 if addFood then
	   table.insert(t_gameDots, {x = sx, y = sy, eatan = false})
	 end
	 addFood = true
  end
end

That's how I got it to work. To understand why yours was failing, take this scenario:
sx = 3, sy = 3 is a position with a wall, you detect that, break out of the loop and move on.
The next step, sx = 3, sy = 4, and there is another wall there, however, there is also a wall at 3,3 which is not 3,4 so it adds the dot. Does that make sense?

Why didn't I think of using a boolean ._. Spent forever on this.

I knew that was something sketchy about the way I was doing it :P/> Just couldn't figure it out, I understand the scenario though, big facepalm.

Thanks :>
KaoS #5
Posted 13 January 2013 - 02:34 AM
sorry to criticise but this seems like a very messy way of doing things… perhaps I misunderstood how you are making this work
remiX #6
Posted 13 January 2013 - 02:43 AM
sorry to criticise but this seems like a very messy way of doing things… perhaps I misunderstood how you are making this work

Well, you see the t_gameWalls table? .. It has 334 tables within it with x and y co-ords.

It took me forever and was too lazy to add more into the t_gameDots table :P/>
KaoS #7
Posted 13 January 2013 - 02:59 AM
well in those kind of situations I use a generic map table like so


local tMap=setmetatable({},{__index=function(self,index) self[index]={} return self[index] end})

and then you use it as a co-ordinate map


tMap[x][y]=="w"

to make that co-ordinate contain a wall block, you can make it 3 dimensional even… then you use loops to add walls etc


local function addwall(startx,starty,len,dir,type)
  startx,starty,len,dir,type=(tonumber(startx) or 1),(tonumber(starty) or 1),(tonumber(len) or 1),(dir or "up"),(type or "w")

  for loc=1,len do
	tMap[startx+loc*(dir=="left" and -1 or dir=="right" and 1 or 0)][starty+loc*(dir=="up" and -1 or dir=="down" and 1 or 0)]=type
  end
end

so you say addwall(2,2,5,"right","k")

and it will add "k" blocks in 2,2->7,2

I find that using this format makes it easier to use functions to go through your map and gather/change information effectively, you can then use map layers, one table as a physical map and another table for an entity map which is rendered over the first table etc etc etc… making Lua games is ridiculous

PS: the above function is untested and is just to explain what I mean, the second line is actually bad coding practice in some cases…
remiX #8
Posted 13 January 2013 - 03:11 AM
I've never used metatables before and have no clue how to or what they do. Could you link me a tutorial on them?

I knew that there was an easier way than what I'm doing but I didn't know what it was.

But it loops through the table really fast so it's fine imo :P/>
theoriginalbit #9
Posted 13 January 2013 - 03:13 AM
But it loops through the table really fast so it's fine imo :P/>
If its gets too big though it can cause problems, today I had a table take so long to iterate that I got a yield error…
KaoS #10
Posted 13 January 2013 - 03:19 AM
here is a link to a topic which will show you the amazing usefulness of metatables followed by a link to the tutorial I mentioned in the first thread

http://www.computercraft.info/forums2/index.php?/topic/5946-keep-computers-loaded/page__view__findpost__p__50038

http://nova-fusion.com/2011/06/30/lua-metatables-tutorial/
remiX #11
Posted 13 January 2013 - 03:20 AM
But it loops through the table really fast so it's fine imo :P/>
If its gets too big though it can cause problems, today I had a table take so long to iterate that I got a yield error…

Yeah i know it error if it doesn't yield, but I've tested about 30 times and it hasn't error'd once. And it loops through the tables every 0.5 seconds

How big was your table?
theoriginalbit #12
Posted 13 January 2013 - 03:21 AM
But it loops through the table really fast so it's fine imo :P/>
If its gets too big though it can cause problems, today I had a table take so long to iterate that I got a yield error…

Yeah i know it error if it doesn't yield, but I've tested about 30 times and it hasn't error'd once. And it loops through the tables every 0.5 seconds

How big was your table?
Honestly I don't know, it was dynamically generated from a few sources and it was while writing the values that I got the error… All I know is it was BIG…
KaoS #13
Posted 13 January 2013 - 03:24 AM
But it loops through the table really fast so it's fine imo :P/>
If its gets too big though it can cause problems, today I had a table take so long to iterate that I got a yield error…

wow that must have been an enormous table :o/> adding a sleep(0) to the pairs loop should sort that out though

EDIT: I remember having the same problem back in tekkit, I was running a proximity sensor and a quad flower EMC generator…. too many entities detected ^_^/>, it never died with the too long without yielding but it slowed down a lot
theoriginalbit #14
Posted 13 January 2013 - 03:25 AM
But it loops through the table really fast so it's fine imo :P/>
If its gets too big though it can cause problems, today I had a table take so long to iterate that I got a yield error…

wow that must have been an enormous table :o/> adding a sleep(0) to the pairs loop should sort that out though
nope it did not… I tried that… then I tried it again thinking I was crazy the first time… then I tried a third time… and gave up…
remiX #15
Posted 13 January 2013 - 03:26 AM
–snip

Honestly I don't know, it was dynamically generated from a few sources and it was while writing the values that I got the error… All I know is it was BIG…

So bigger than my one which has about 334 :P/> What are you using such big tables for…
theoriginalbit #16
Posted 13 January 2013 - 03:30 AM
–snip

Honestly I don't know, it was dynamically generated from a few sources and it was while writing the values that I got the error… All I know is it was BIG…

So bigger than my one which has about 334 :P/> What are you using such big tables for…

It was some HTML interpreting / processing / whole bunch of other stuff pulled in… unless I missed something in my code, it was defs the loop, remove the loop, no error… turns out the project wasn't feasible anyways…
KaoS #17
Posted 13 January 2013 - 03:32 AM
nope it did not… I tried that… then I tried it again thinking I was crazy the first time… then I tried a third time… and gave up…

:mellow:/> if that didn't fix it then it was not the for loop causing the issue. the sleep(0) would make it yield each loop so your program took too long to yield within a single loop…. not the table's fault there
theoriginalbit #18
Posted 13 January 2013 - 03:34 AM
nope it did not… I tried that… then I tried it again thinking I was crazy the first time… then I tried a third time… and gave up…

:mellow:/> if that didn't fix it then it was not the for loop causing the issue. the sleep(0) would make it yield each loop so your program took too long to yield within a single loop…. not the table's fault there
could have been that… not sure… can't remember…