![]() |
Viscious Game Bug
Hello, folks. I need help.
The following is a function that determines the winner of a single battle in the game I'm creating, and then updates the field and stats appropriately. The "DetermineBattleOutcome" call is what actually determines the winner. My debug output shows that this ALWAYS returns the correct value. The "outcome" variable which stores this result is checked against the SUCCESS and FAILURE codes (values 1.00 and 0.01, respectively,) in an IF statement following the "Determine..." call. PROBLEM IS: When I lose a battle on purpose, and the value of outcome is CORRECTLY set to MWEIGHT_FAILURE (0.01), the afore-mentioned IF statement DOES NOT evaluate "outcome == MWEIGHT_FAILURE" to true............. It's late... and I hope I'm just missing something obvious, but this is truly perplexing. If the debug code is too confusing, please let me know and I'll remove it. :
void DoBattle (UINT attacker, UINT pos) |
Fixed
Sorry for answering my own post :o I finally figured out that I had to (float) my variables:
:
// if someone won the battle |
How did you define MWEIGHT_FAILURE and MWEIGHT_SUCCESS? You don't show that.
It's also error prone to compare floats directly. Floats gain their range at the expense of precision. You should generally define an error value such that if the difference between two floats is within that range, they're considered equal. |
Quote:
:
#define MWEIGHT_FAILURE 0.01Quote:
I'm using floats as the return value from the DetermineBattleOutcome function because the result acts as the root weight in the AI for determining which move is the best. If FAILURE is returned for instance, the weight starts as low as possible (0.01, in this case), while still being a valid move. When the AI gets this value, it then adds the float value that represents the importance of the card to this root weight. E.g. a 3 card would be weighted 0.15 because of it's low importance, while a Queen would be 0.90, etc. The AI part is working great, since it adds the floats up and takes their average, then justs looks for the highest. The battle handling function that I posted does not need float values, but uses them for sake of convenience. Do you think it would be best for me to return integer values for this part, instead of the floats? The code is so uncluttered now, I don't really want to gunk it up by doing that. But if it's a high probability that I'm going to run into problems with it the way it is now, I'll be happy to change it. |
I had similar problem once, and all I did was create a new method that returned BOOL, and did a comparison on 2 floats to see if they are "equal". (if abs(f1-f2) < SOME_CONSANT)
Didn't clutter things up too much :/ |
Assuming you're on a typical 32-bit system, there are only 2^32 values available for all the floats in the approximate range 10^-38 to 10^38. As you can see, there would be a huge number of actual values missing.
The value that andro is using (SOME_CONSTANT) is often called Epsilon. I often define my own epsilon, according to what I think I need. Your system may define a constant, such as FLT_EPSILON, that is the smallest number which, when added to 1.0, will not result in 1.0. In the case of MS' C++, this value is 1.192092896e–07F. As an example, if you divide 1.0 by 100.0, you will get 0.01. You will get that same result if you divide 1.0 by 100.00001. Your mileage may vary slightly depending on your machine's floating point implementation, but you get my drift. Very small changes in your weights will introduce error. |
Thank you, DaWei. That's a bit over my head :) but I'll keep it in mind as I go. Hopefully the way that it is coded now will not present any major problems, as the game will be relatively simple.
And thank you for the suggestion Andro. I'll keep that in mind, also. |
| All times are GMT -5. The time now is 8:13 PM. |
Powered by vBulletin® Version 3.7.0, Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.
Copyright ©2007 DaniWeb® LLC