Elegant way to determine when game field is clear

Member
Posts: 65
Joined: 2009.01
Post: #1
I need to figure out when all of the objects in the game field have been destroyed, that is, all of their IsAlive boolean properties are false. The objects are all in a single array.
I know I've seen an elegant way to do this, but I can't seem to recall it at the moment.
Quote this message in a reply
Moderator
Posts: 916
Joined: 2002.10
Post: #2
how about this:
have a variable: numobjects
each time an object's isAlive goes to true, increment it
each time an object's isAlive goes to false, decrement it

and every frame you can just check if numobjects == 0 (aka, they're all dead)
Quote this message in a reply
Member
Posts: 65
Joined: 2009.01
Post: #3
Having to keep track of a separate variable seems to defeat the purpose of the IsAlive flag.

But, building on your idea, I could just do this:

int deadCount = 0;
foreach (object in ObjectArray) if(!object.isAlive) deadCount++;
if (deadCount == ObjectArray.Length()) all objects are destroyed...
Quote this message in a reply
Moderator
Posts: 771
Joined: 2003.04
Post: #4
I'd go for skyhawk's solution myself, but if you prefer to check the array, you don't necessarily have to check the entire array every time:

Code:
bool someoneAlive = false;
foreach (object in ObjectArray) {
    if (object.isAlive) {
        someoneAlive = true;
        break;
    }
}
if (!someoneAlive) { // everyone dead
Quote this message in a reply
Moderator
Posts: 916
Joined: 2002.10
Post: #5
(May 24, 2011 09:41 PM)johncmurphy Wrote:  Having to keep track of a separate variable seems to defeat the purpose of the IsAlive flag.

the purpose of the way I mentioned is it minimizes computational power (looping arrays is expensive, even more so if array is large) at the cost of maintaining a single variable (incrementing, decrementing, and a single bool check are all very efficient).

it's also elegant Rasp
Quote this message in a reply
Moderator
Posts: 452
Joined: 2008.04
Post: #6
Loop through the whole array every frame. Your array isn't that big.

Howling Moon Software - CrayonBall for Mac and iPhone, Contract Game Dev Work
Quote this message in a reply
Member
Posts: 227
Joined: 2008.08
Post: #7
(May 24, 2011 09:41 PM)johncmurphy Wrote:  Having to keep track of a separate variable seems to defeat the purpose of the IsAlive flag.

IsAlive isn't needed (nor is iteration). When you spawn an object, increase a game-state owned variable that tracks numbers of alive enemies, and when one dies, decrement it, and when it equals 0, then the game field is clear. 1 if for checking for 0, 1 increment/decrement on object spawn/death (which, I should add, is cheap as ... and insignificant compared to the other operations you'll probably be doing), and 1 unsigned integer, which is much less than the brute force using an isAlive flag.
Quote this message in a reply
Sage
Posts: 1,482
Joined: 2002.09
Post: #8
Yes, although what is inelegant about that is that it's adding redundant state. As your code grows and becomes more complex it's easy to accidentally forget to increment some random number when you do some random operation. It tends to be very difficult to find these sorts of bugs.

Iterating arrays is not particularly computationally expensive. Presumably you have to iterate the array in order to draw things. Iterating the array to count things in it is going to to be like 1% of the CPU time to iterate the array and draw the objects in it. Drawing commands tend to be the most expensive things that you can do in a game. Don't worry about the CPU cost of counting things...

Personally, I just remove the dead objects as soon as they die. Then you just need to check if the array is empty.

Scott Lembcke - Howling Moon Software
Author of Chipmunk Physics - A fast and simple rigid body physics library in C.
Quote this message in a reply
Member
Posts: 227
Joined: 2008.08
Post: #9
(May 25, 2011 03:46 PM)Skorche Wrote:  Personally, I just remove the dead objects as soon as they die. Then you just need to check if the array is empty.

I was assuming he didn't have a resizable array.
Quote this message in a reply
Moderator
Posts: 435
Joined: 2002.09
Post: #10
Your array likely isn't big enough to even register a blip in your frame rate when you iterate through it. You also only need to check it each time an object has been destroyed.

But it's also true that adding a bit of extra state for efficiency is done frequently. But it's better to do it when you observe a performance problem or to simplify the code being written, not develop spaghetti code up front because you don't ever want to loop.

Measure twice, cut once, curse three or four times.
Quote this message in a reply
Moderator
Posts: 452
Joined: 2008.04
Post: #11
I agree 100% with what MattDiamond said. Don't even think about adding state and complexity to fix performance problems you *think* exist, until you've *proved* they exist.

Howling Moon Software - CrayonBall for Mac and iPhone, Contract Game Dev Work
Quote this message in a reply
Member
Posts: 65
Joined: 2009.01
Post: #12
Thanks guys. I actually was able to find the elegant version that I had seen before.
It involved the creation of a separate method to run through the objects array and answer the question, "Are there any enemies left to kill?"

Code:
bool AnyEnemiesRemaining()
        {
            foreach (Enemy enemy in enemies) if (enemy.isAlive) return true;        
            return false;
        }
Quote this message in a reply
Post Reply