Skip to main content
GameDev.net gamedev.net
🔒 Locked

effective switch statements

Started by Joker2000 Jul 10, 2000 at 1:35 AM 6 replies 200+ views
Original Post
Joker2000
Joker2000
Well, I''ve been posting here quite a bit recently concerning all the problems I''ve been having with my game (hell, at this point, it seems as though YOU ALL have been writing the game and not me...I''ve been getting so much help). But anyway, thank God all my previous problems have been solved (so far). Now, the reason I''m writing this post is not so much because of a problem, but because I know there are ways to better optimize the code I''m currently working with. Ok, the idea is that the user is at the weapons menu screen and to choose a weapon they simply enter the number corresponding to the weapon they want - simple enough, AND I can do it the long, hard way.
    
switch(choice)
case ''1'':
   weapon * TheWeapon = new weapon("NAME OF WEAPON 1",5,100);
   break;
case ''2'':
   weapon * TheWeapon = new weapon("NAME OF WEAPON 2",8,200);
   break;
// etc etc.
  
Talk about redundancy! So, at this point I''ve gotten the code a little more simplified:
char menu_choice;
char convert[1];
int weapon_select;
int done = 0;

switch(toupper(menu_choice))
{
    case ''1'':
    case ''2'':
    case ''3'':
    case ''4'':
    case ''5'':
    case ''6'':
    case ''7'':
    case ''8'':
    {
        done = 1;
        *convert = menu_choice;        // if 1-8...weapon wanted
        weapon_select = atoi(convert); // see notes at bottom
        weapon * pWeapon = new weapon(NAME,DAMAGE,50);
        break;
    }
    case ''S'':
    {
        ThePlayer->show_player_stats();
        TheWeapon->show_weapon_stats();
        break;
    }
    case ''Q'':
    {
        done = 1;
        break;
    }
    default:
    {
        cout << endl << invalid_option;
        getch();
        break;
    }
}
  
As you can see, it has less redundant code, but now I don''t know how to get it to recognize exactly which weapon they want. It only knows "Hey, they entered a number, they must want a weapon." Unfortunately, that''s all it knows. The reason I converted the menu_choice to an integer (weapon_select) was so I could test it to see which weapon they wanted, but then that defeats the whole purpose - I would have to write another long, redundant switch statement for that. The only reason I really care about doing this is because some guy chewed my butt out one time when I used a switch statement like the one at the top (too redundant). So, to make that jerkoff happy I decided I''d better learn how to do this the right way. PS: I''ve tried some stuff already, but it always felt like I was heading right for a brick wall. For example, I tried making a weapon codename and damage codename generator. It would do something like append their menu_choice to ''WC'', creating the string ''WC1'' if they wanted weapon #1, ''WC2'' for weapon #2, etc. Then, I had a list of defines like: #define WC1 "Colt .45 Pistol" #define WC2 "Shotgun" However, I realized that it wouldn''t go and substitute "Colt" for WC1 because WC1 was ALREADY a string. Talk about disappointment. Anyway, that''s about it. Below is some of the more relevant code to my program if you need it to help solve the problem. Enjoy.
class weapon
{
public:
    weapon(string, int, int);
    ~weapon(void);
    void show_weapon_stats(void);
    void fire_weapon(void);
    void change_fire_method(int);
    void reload_weapon(int);
    void buy_ammo(int);
    friend player;
private:
    string weapon_name;
    int damage;
    int ammo;
};

weapon::weapon(string w_name, int d, int a)
{
this->weapon_name = w_name;
this->damage = d;
this->ammo = a;
}
      
jtecin
jtecin
Have you tried making an array of the weapon class? You just take weapon_select and that is the array number. So you call the function new weapon(weapon[weapon_select].weapon_name, 5, 100). I''m not sure if this is what you''re looking for, but it''s late and I''m tired. Good night all.




Masters Software
Qoy
Qoy
Or, you could make an array of all the weapon names, where the index to the name is the same as the index to the weapon type, like this:


char* weaponNames[] = { "Colt .45",
"Shotgun",
"Rocket Launcher" }



That way, you can index that array for the weapon''s name. And you can define numbers to be the weapon types, for easy array access:

#define WPN_COLT45 0
#define WPN_SHOTGUN 1
#define WPN_ROCKETLAUNCH 2


I hope this helps. Sorry if I didn''t understand your question, it''s late
Joker2000
Joker2000
Well, I understand what you guys mean when you talk about using arrays, but DOING is often more difficult than understanding. I''ve gotten it to work (in a sense), but instead of displaying readable text it gives me crap like "0047582A". So here''s where I''m at, I hope you follow my logic(?). If there are particular areas of interest I will comment them with NOTE #. Then you can look at the bottom to see why I did what I did:


class weapon
{
public:
weapon(int);
~weapon(void);
void load_arrays(void);
void show_weapon_stats(void);
void fire_weapon(void);
void change_fire_method(int);
void reload_weapon(int);
void buy_ammo(int);
friend player;
private:
string weapon_name[9];
int damage[9];
int ammo[9];
};

weapon::weapon(int wn)
{
this->weapon_name[wn];
this->damage[wn];
this->ammo[wn];
}

void weapon::load_arrays(void) // NOTE #3
{
string weapon_name[9] = {"None", "Kabar Combat Knife", "Colt .45 Pistol", ".44 Magnum",
"Blaster Pistol", "Remington 12G Shotgun", "MP-5 Sub-Machine Gun",
"M-16 Machine Gun", "Plasma Rifle"};
int damage[9] = {0, 2, 4, 7, 8, 14, 10, 15, 20};
int ammo[9] = {0, 0, 20, 12, 30, 16, 50, 50, 50};
}

void main(void)
{
show_title_screen();
player * pPlayer = prompt_new_player();
weapon * pWeapon = new weapon(0); // NOTE #1
pWeapon->load_arrays(); // NOTE #2
menu_main(pPlayer, pWeapon);
}

void menu_weapons(player *ThePlayer, weapon *TheWeapon)
{
char menu_choice;
char convert[1];
int weapon_select;

// do this stuff if number is selected for weapon

*convert = menu_choice;
weapon_select = atoi(convert);
weapon * TheWeapon = new weapon(weapon_select); // NOTE #4
ThePlayer->change_weapon_status(1); // NOTE #5
menu_main(ThePlayer, TheWeapon);
break;
}


NOTE 1: I wanted to make sure that from the very beginning something was in the place of the user''s weapon. Therefore if the player checked his stats before buying a weapon it would read: Weapon Name: "None", Ammo: "0", etc. instead of Weapon Name: , Ammo: , etc. To tell you the truth, I''m not even sure if it would put blank spaces if not array data was loaded, it''s just what I''m guessing. Nevertheless, I feel something should be loaded from step 1.

NOTE 2: Because you can''t give values to class members on declaration, I needed some way to load the class member arrays with proper data.

NOTE 3: See note 2.

NOTE 4: Here''s where the "stuff" really starts hitting the fan. First of all, because I''ve already passed the *TheWeapon pointer to the function, should I use:
TheWeapon->weapon(weapon_name);
as the constructor or just stick with what I already have? I should also add that the code compiles, and has no run-time errors during this routine, BUT, after selecting a weapon, my weapon stats look like: Weapon Name: "0097234A", Ammo: "004314F4", etc. I don''t know why in the HECK this is happening! It''s just garbage!

NOTE 5: Not really important. It just lets "class player" know that the user has a weapon.

If I''m going about this wrong, which is a highly logical possibility, please turn me in the right direction. Thanks.

Joker

PS: If you need to see any more code, I can put it up.
Magicdude
Magicdude
OK, I'm not sure if I'm missing the point here, but you are creating a new pointer each time? Shouldn't you have either a global pointer Weapon *weapon or at class scope in the player class or something, then make a function that you pass the data to and it changes it all appropriately, something like:

    
// Global scope

weapon *Weapon = NULL;

// In initialization

Weapon = new weapon(0);

// The weapon select thingy

void menu_weapons(player *ThePlayer, weapon *TheWeapon)
{
char menu_choice;
char convert[1];
int weapon_select
*convert = menu_choice;
weapon_select = atoi(convert);
TheWeapon->SetWeapon(weapon_select);
ThePlayer->change_weapon_status(1);
menu_main(ThePlayer, TheWeapon);
break;
}


Edited by - Magicdude on July 10, 2000 1:42:46 PM
bishop_pass
bishop_pass
You should either do the array and have the 0th item of the array mean you have no weapon, or just do the switch statemnt.

There is nothing wrong with doing the switch statement if it makes like easier for you. This is because this function is not executed 4000 times a second. Your code will be a smidgeon bigger, but it won''t make a diddly of difference. As for execution time, I don''t care how big you make that switch statment (say 100 items) it will still execute in no time a all.

The array way would be better only because you should know how to do it an you may need the practice.

_______________________________
"To understand the horse you'll find that you're going to be working on yourself. The horse will give you the answers and he will question you to see if you are sure or not."
- Ray Hunt, in
Stoffel
Stoffel
The reason "weapon" and "ammo" are coming up as 32-bit numbers in the debugger is that they are arrays , not values. The number you''re seeing is the starting address of the array.

The way you wrote the class, everything''s object-specific, i.e. you have to re-initialize your class every time you create a new weapon. Furthermore, the class objects would have all weapon data, not just the data specific to that weapon.

Let me show you an example of how I would write the class (without a lot of the class functions):
    
// weapons.h

class Weapon
{
public:
Weapon (int n);
~Weapon ();
static void Init (); // called globally to initialize arrays

protected: // i usually prefer protected over private for inheritance

static string name_array[9]; // static = global

static int damage_array[9];
static int ammo_array[9];
const string* name; // object-specific

const int* damage;
const int* ammo;
};

// weapons.cpp

static void Weapon::Init ()
{
name_array[0] = "weapon 1";
damage_array[0] = 100;
ammo_array[0] = 4;
// do for each weapon

}

Weapon::Weapon (int idx) :
name (&name_array[idx]), // name points to proper name

damage (&damage_array[idx]),
ammo (&ammo_array[idx])
{
}


Now, when you''re in a Weapon method, and you want to get the name, you just refer to it as a pointer:
cout << "This weapon''s name is: " << *name;

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.