Tables [solved]

Questions about the LÖVE API, installing LÖVE and other support related questions go here.
Forum rules
Before you make a thread asking for help, read this.
TheHistoricApple
Prole
Posts: 26
Joined: Sun Jan 15, 2017 6:46 am

Tables [solved]

Post by TheHistoricApple »

So let's say I have a table of planets called Objects

Code: Select all

Objects = {}
So each index of objects is a planet, so if I wanted planet number 3 I'd do

Code: Select all

Objects[3]
Now in each planets index I have two more values for location

Code: Select all

Objects[3] = {math.random (1, 25), math.random (1,25)}

I use math.random to keep planet locations random each game. So this works fine, except I only want one planet at one location.

Ex: I don't want

Code: Select all

Objects[3][1] == Objects[4][1] and Objects[3][2] == Objects[4][2]
I've tried using a loop to keep radomizing it until it doesn't match any other planets location but it doesn't seem to work.
Last edited by TheHistoricApple on Fri Jan 20, 2017 11:50 pm, edited 1 time in total.
User avatar
raidho36
Party member
Posts: 2063
Joined: Mon Jun 17, 2013 12:00 pm

Re: Tables

Post by raidho36 »

This is in fact a common approach and should work, so there probably is an error on the code somewhere.

You can try using the available list method - compile a list of available places, randomly select one and immediately remove it from the list. Because it's no longer on the list, it will never get selected again.
TheHistoricApple
Prole
Posts: 26
Joined: Sun Jan 15, 2017 6:46 am

Re: Tables

Post by TheHistoricApple »

What loop would I use what I currently do is

Code: Select all

for i = 1, #Objects do
    for e = 1, #Objects do
        if Objects[i][1] == Objects[e][1] and Objects[i][2] == Objects[e][2] then
            Objects[i][1] = math.random(1, 25)
            Objects[i][2] = math.random (1, 25)
        end
    end
end
Last edited by TheHistoricApple on Fri Jan 20, 2017 4:36 am, edited 1 time in total.
TheHistoricApple
Prole
Posts: 26
Joined: Sun Jan 15, 2017 6:46 am

Re: Tables

Post by TheHistoricApple »

I can't really use the list and remove method because of the number of planets I'd have
User avatar
raidho36
Party member
Posts: 2063
Joined: Mon Jun 17, 2013 12:00 pm

Re: Tables

Post by raidho36 »

I see your problem - because it runs over all planets in both loops, at one point it will compare with itself, which will always return true and trigger reposition. There is also nothing preventing planets from getting repositioned into another planet or even forcing it to move at all (with 0.16% chance). But it's not the best approach in general.

What you should do is check for space being occupied when you create each planet, and shift it around until it's place is free, only then put it to the planet list.
Skeletonxf
Citizen
Posts: 87
Joined: Tue Dec 30, 2014 6:07 pm

Re: Tables

Post by Skeletonxf »

Why not fill in all 1-25 x 1-25 as a planet position and then run randomly through the list creating holes where you delete the planet?
User avatar
Positive07
Party member
Posts: 1014
Joined: Sun Aug 12, 2012 4:34 pm
Location: Argentina

Re: Tables

Post by Positive07 »

From what raidho said I can infere this would work

Code: Select all

for i = 1, #Objects do
    for e = 1, #Objects do
        if e ~= i then
            if Objects[i][1] == Objects[e][1] and Objects[i][2] == Objects[e][2] then
                Objects[i][1] = math.random(1, 25)
                Objects[i][2] = math.random (1, 25)
            end
        end
    end
end
You could do this when creating the planets in order to avoid looping through all objects but I don't know, I wouldn't do this at all
for i, person in ipairs(everybody) do
[tab]if not person.obey then person:setObey(true) end
end
love.system.openURL(github.com/pablomayobre)
User avatar
raidho36
Party member
Posts: 2063
Joined: Mon Jun 17, 2013 12:00 pm

Re: Tables

Post by raidho36 »

No it wouldn't. It doesn't reposition the planet itself for the second time but it still doesn't ensure that repositioned planet can't move into another plant thus defeating the purpose, or even move at all.

Code: Select all

local finished = false
while not finished do
	finished = true
	planet[ 1 ] = math.random ( 1, 25 )
	planet[ 2 ] = math.random ( 1, 25 )
	for i = 1, #objects do
		if planet[ 1 ] == objects[ i ][ 1 ] and planet[ 2 ] == objects[ i ][ 2 ] then
			finished = false
			break
		end
	end
end
objects[ #objects + 1 ] = planet
User avatar
Positive07
Party member
Posts: 1014
Joined: Sun Aug 12, 2012 4:34 pm
Location: Argentina

Re: Tables

Post by Positive07 »

Yeah I knew, I just keeped the code he was using, I still consider there should be a better way to do this, something like a table with all valid positions and removing the already used items or something like that... I think that performing this loop every single time to add a planet to the map would be a real pain...
for i, person in ipairs(everybody) do
[tab]if not person.obey then person:setObey(true) end
end
love.system.openURL(github.com/pablomayobre)
User avatar
raidho36
Party member
Posts: 2063
Joined: Mon Jun 17, 2013 12:00 pm

Re: Tables

Post by raidho36 »

That depends on how many planets are there and how big is the field. Odds of running into another planet randomly are N / W × H, to reach 50:50 odds on 25x25 map you'll need 63 planets in it, and even then there's still 50% chance it'll make it into a free spot on the first try, 75% on second try, 87.5% on third try and so on. It really only stops working well when available space is almost completely exhausted.
Post Reply

Who is online

Users browsing this forum: Ahrefs [Bot] and 165 guests