Why doesn't # decrease after remove?

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.
Trevor
Prole
Posts: 30
Joined: Thu Mar 31, 2011 4:14 pm

Why doesn't # decrease after remove?

Post by Trevor »

I just started using Love about a week ago and have made okay progress on my Galaga clone. Overall things are going smoothly, but I can't figure out why the value of #WeaponManager does not decrease.

I increase the value here:

Code: Select all

function Player:shoot(dt)
    table.insert(WeaponManager, self.Weapon:new{
        x = self.x, y = self.y - self.Weapon.image:getHeight() })
end
Decrease the value:

Code: Select all

function WeaponManager:move(dt)
    for i,v in ipairs(WeaponManager) do
        if WeaponManager[i] ~= nil then
            -- Removes a Weapon from the table if off screen
            if (v.x + v.image:getHeight() < 0 or v.x > love.graphics.getWidth() or
                v.y + v.image:getWidth() < 0 or v.y > love.graphics.getHeight()) then
                table.remove(v)
            else
                v:move(dt)
            end
        end
    end
end
Print the value here:

Code: Select all

function love.draw()
    p.anim:draw(p.x, p.y)
    WeaponManager:draw()
    love.graphics.print(#WeaponManager, 0, 0)
end
Here's the full game:
http://www.trevorhrenko.ca/jelaga/Jelaga.love

I am open to any feedback especially recommendations to improve the code. This my first time making a game and using Love. I've read PIL, but haven't spend a lot of time with Lua. Also, I come from a mostly Java background.
User avatar
sharpobject
Prole
Posts: 44
Joined: Fri Mar 18, 2011 2:32 pm
Location: California

Re: Why doesn't # decrease after remove?

Post by sharpobject »

table.remove() takes a table and an index and removes the thing at that index.
Trevor
Prole
Posts: 30
Joined: Thu Mar 31, 2011 4:14 pm

Re: Why doesn't # decrease after remove?

Post by Trevor »

Well that was obvious. Thank you so much!

Fixed it with:

Code: Select all

table.remove(WeaponManager, i)
noway
Prole
Posts: 43
Joined: Mon Mar 21, 2011 7:58 am

Re: Why doesn't # decrease after remove?

Post by noway »

BTW, here you can find some nice free art for galaga-like game.
Also maybe you'll be able to find there some sounds and models for other spaceships.
User avatar
Ensayia
Party member
Posts: 399
Joined: Sat Jun 12, 2010 7:57 pm

Re: Why doesn't # decrease after remove?

Post by Ensayia »

Another nice benefit of table.remove() over setting the index to nil is that table.remove() will automatically re-order your indexes to fill the gap left by the removed index. If you have {1, 2, 3, 4, etc.} and use table.remove() on index 3, index 4 will get bumped to 3 and so on until the list is whole and in order again.

Having a table with gaps in the indexes can do weird things when using iterators like ipairs() or even sometimes when using a numerical for loop.
Trevor
Prole
Posts: 30
Joined: Thu Mar 31, 2011 4:14 pm

Re: Why doesn't # decrease after remove?

Post by Trevor »

Thank you, both.
GloryFish
Prole
Posts: 19
Joined: Tue Jan 11, 2011 4:43 pm

Re: Why doesn't # decrease after remove?

Post by GloryFish »

Ensayia wrote:Another nice benefit of table.remove() over setting the index to nil is that table.remove() will automatically re-order your indexes to fill the gap left by the removed index. If you have {1, 2, 3, 4, etc.} and use table.remove() on index 3, index 4 will get bumped to 3 and so on until the list is whole and in order again.

Having a table with gaps in the indexes can do weird things when using iterators like ipairs() or even sometimes when using a numerical for loop.
Related: If you remove an item with table.remove() while you are iterating that table you will run into problems related to the reindexing behavior. You need to either make a list of objects to remove, and remove them after you finish iterating. Or, you need to iterate backwards so that any index reshuffling happens to items you've already iterated over.

Some examples can be found here: http://love2d.org/forums/viewtopic.php? ... 754#p29198
Freze
Prole
Posts: 9
Joined: Wed Apr 13, 2011 1:15 pm

Re: Why doesn't # decrease after remove?

Post by Freze »

Also the # operator doesn't count them. Takes the highest key.
To get a count do this:
local i = 0
for k,v in pairs(table) do
i = i + 1;
end
User avatar
nevon
Commander of the Circuloids
Posts: 938
Joined: Thu Feb 14, 2008 8:25 pm
Location: Stockholm, Sweden
Contact:

Re: Why doesn't # decrease after remove?

Post by nevon »

Freze wrote:Also the # operator doesn't count them. Takes the highest key.
Are you sure?

Code: Select all

> t = {}
> table.insert(t, "First")
> table.insert(t, "Second")
> table.insert(t, "Third")
> print(#t)
3
> table.remove(t, 2)
> print(#t)
2
EDIT: Huh. This is very interesting:

Code: Select all

> t = {}
> table.insert(t, "First")
> table.insert(t, "Second")
> table.insert(t, "Third")
> print(#t)
3
> t[2] = nil
> print(#t)
1
> print(t[3])
Third
User avatar
bartbes
Sex machine
Posts: 4946
Joined: Fri Aug 29, 2008 10:35 am
Location: The Netherlands
Contact:

Re: Why doesn't # decrease after remove?

Post by bartbes »

That's because a lua 'array' has no gaps in it. In fact, in the lua core there are two parts to a table, an array and a hashmap, with small gaps it will stay in the array, if there's a bigger gap (don't know the exact numbers, but t[1] and t[3000] should do it), the non-array part (the one at index 3000) will be in the hashmap, not the array.

This to illustrate lua's 'arrays' are gapless.
Post Reply

Who is online

Users browsing this forum: No registered users and 3 guests