Programming Forums
User Name Password Register
 

RSS Feed
FORUM INDEX | TODAY'S POSTS | UNANSWERED THREADS | ADVANCED SEARCH

Reply
 
Thread Tools Display Modes
Old Sep 3rd, 2007, 4:21 AM   #1
dr.p
Programmer
 
dr.p's Avatar
 
Join Date: Feb 2006
Location: Ohio
Posts: 93
Rep Power: 3 dr.p is on a distinguished road
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)
{
#ifdef GAME_PLAY_DEBUG_BATTLE
  Debug_CleanUp();
  char sztemp[256] = "\0";
  sprintf(sztemp, "BATTLE: a=%d p=%d", attacker, pos);
  Debug_CompyOut(sztemp);
  Delay(BATTLE_DEBUG_DELAY);
#endif

  if (attacker != COMPUTER && attacker != PLAYER) return;

  if (pos >= FIELD_SIZE) return;

  UINT defender = (attacker == COMPUTER) ? PLAYER: COMPUTER;

  float outcome = DetermineBattleOutcome(g_Field[attacker][pos], g_Field[defender][pos]);

#ifdef GAME_PLAY_DEBUG_BATTLE
  sprintf(sztemp, "BATTLE: outcome=%f", outcome);
  Debug_CompyOut(sztemp);
  Delay(BATTLE_DEBUG_DELAY);
#endif

  if (outcome == MWEIGHT_INVALID)
    return;

  BYTE suit, value, state, color;

    // if someone won the battle
  if (outcome == MWEIGHT_FAILURE || outcome == MWEIGHT_SUCCESS) {
      // set the winner and loser
    UINT winner = (outcome == MWEIGHT_SUCCESS) ? attacker: defender;
    UINT loser = (outcome == MWEIGHT_SUCCESS) ? defender: attacker;

#ifdef GAME_PLAY_DEBUG_BATTLE
    sprintf(sztemp, "BATTLE: w=%d l=%d", winner, loser);
    Debug_CompyOut(sztemp);
    Delay(BATTLE_DEBUG_DELAY);
#endif
      // get the value of the lost card
    ParseCardValue(g_Field[loser][pos], NULL, &value, NULL, NULL);
      // update the winer's states
    g_Scores[winner]->nTotalCaptured++;
    if (value > CARDROW_TENS) {
      g_Scores[winner]->nFacesCaptured++;
    }
      // and remove the lost card from the field
    g_Field[loser][pos] = 0;
  } else {
#ifdef GAME_PLAY_DEBUG_BATTLE
    sprintf(sztemp, "BATTLE: NO WINNER! %f %f", outcome, MWEIGHT_FAILURE);
    Debug_CompyOut(sztemp);
    Delay(BATTLE_DEBUG_DELAY);
#endif
  }
}
// end DoBattle
__________________
Neeley.org
dr.p is offline   Reply With Quote
Old Sep 3rd, 2007, 4:50 AM   #2
dr.p
Programmer
 
dr.p's Avatar
 
Join Date: Feb 2006
Location: Ohio
Posts: 93
Rep Power: 3 dr.p is on a distinguished road
Fixed

Sorry for answering my own post :o I finally figured out that I had to (float) my variables:
    // if someone won the battle
  if ( (float)outcome == (float)MWEIGHT_FAILURE
    || (float)outcome == (float)MWEIGHT_SUCCESS
  ) {
      // set the winner and loser
I'm using MS Visual C++ 2005 Express for this. Is it normal for most compilers to default a comparison between a float variable and a float value to an integer comparison?
__________________
Neeley.org
dr.p is offline   Reply With Quote
Old Sep 3rd, 2007, 8:14 AM   #3
DaWei
Resident Grouch
 
DaWei's Avatar
 
Join Date: Jun 2005
Posts: 6,453
Rep Power: 10 DaWei is on a distinguished road
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.
__________________
Abstraction doesn't make it impossible to write bad code; it makes it possible to write superior code.
Contributor's Corner: Grumpy on C++ Exceptions DaWei on Pointers
DaWei is offline   Reply With Quote
Old Sep 3rd, 2007, 2:58 PM   #4
dr.p
Programmer
 
dr.p's Avatar
 
Join Date: Feb 2006
Location: Ohio
Posts: 93
Rep Power: 3 dr.p is on a distinguished road
Quote:
Originally Posted by DaWei View Post
How did you define MWEIGHT_FAILURE and MWEIGHT_SUCCESS? You don't show that.
Like so:
#define MWEIGHT_FAILURE 0.01
#define MWEIGHT_SUCCESS 1.00


Quote:
Originally Posted by DaWei View Post
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.
That's not a good thing for what I'm doing.

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.
__________________
Neeley.org
dr.p is offline   Reply With Quote
Old Sep 3rd, 2007, 3:00 PM   #5
andro
Professional Programmer
 
Join Date: Oct 2005
Location: California
Posts: 311
Rep Power: 3 andro is on a distinguished road
Send a message via AIM to andro
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 :/
__________________
http://www.kevinherron.com/
andro is offline   Reply With Quote
Old Sep 3rd, 2007, 3:32 PM   #6
DaWei
Resident Grouch
 
DaWei's Avatar
 
Join Date: Jun 2005
Posts: 6,453
Rep Power: 10 DaWei is on a distinguished road
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.
__________________
Abstraction doesn't make it impossible to write bad code; it makes it possible to write superior code.
Contributor's Corner: Grumpy on C++ Exceptions DaWei on Pointers
DaWei is offline   Reply With Quote
Old Sep 3rd, 2007, 8:52 PM   #7
dr.p
Programmer
 
dr.p's Avatar
 
Join Date: Feb 2006
Location: Ohio
Posts: 93
Rep Power: 3 dr.p is on a distinguished road
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.
__________________
Neeley.org
dr.p is offline   Reply With Quote
Reply

Bookmarks

« Previous Thread in Forum | Next Thread in Forum »

Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Forum Jump

Similar Threads
Thread Thread Starter Forum Replies Last Post
An aspiring game programmer needs your advice Emperor Community Introductions 5 Feb 10th, 2007 5:36 PM
Trying to setup an anti-cheat system for a game friend and I are creating Dr.Backtick` C++ 14 Feb 15th, 2006 11:12 PM
Java programmers, game developers, artists, be ware! RPG game team is recruiting! atcomputers.us Paid Job Offers 7 Sep 25th, 2005 7:25 PM
Programmers Needed! Online Game troy_eisert C++ 2 Jan 29th, 2005 12:51 PM




DaniWeb IT Discussion Community
All times are GMT -5. The time now is 10:59 AM.

Powered by vBulletin® Version 3.7.0, Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.
Copyright ©2007 DaniWeb® LLC