Elegant way to determine when game field is clear
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.
I know I've seen an elegant way to do this, but I can't seem to recall it at the moment.
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)
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)
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...
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...
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(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
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
(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.
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.
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.
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.
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.
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
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?"
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;
}
