Sign in to follow this  

Make a veriable be equel to multiple numbers

This topic is 4108 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

How can I have variable X be equal to multiple numbers? Example X = 1 and 2 and 3 and 4. If( input == x) { //do what ever… } I know a variable can only equal one at a time but I want to be able to input a integer and have it check against a list of numbers and if it equals one of them then continue. is that possible?

Share this post


Link to post
Share on other sites
You could always do something like this:


std::vector<int> list;

// add each item to the list like this:
list.push_back( 1 );
list.push_back( 2 );

// loop through each one and do the check
for( int i = 0; i < list.size(); ++i )
{
if( input == list[i] )
{
// do what ever...
}
}


Share this post


Link to post
Share on other sites
Quote:
Original post by ussnewjersey4
You could always do something like this:

*** Source Snippet Removed ***


with your code how can I add an else statment when it does not equel it with out having it loop through all the possible combos when it finds the one it needs?

Also whould it be better if I just read through a txt file or something because I also need to do some what the same thing with some strings or can I do the same thing with strings inside a vector?

Share this post


Link to post
Share on other sites
Quote:
Original post by kingpinzs
Quote:
Original post by ussnewjersey4
You could always do something like this:

*** Source Snippet Removed ***


with your code how can I add an else statment when it does not equel it with out having it loop through all the possible combos when it finds the one it needs?

Also whould it be better if I just read through a txt file or something because I also need to do some what the same thing with some strings or can I do the same thing with strings inside a vector?


std::vector<int>::iterator it = std::find( list.begin(), list.end(), input );
if( it != list.end() )
{
// handle if it is there....

}
else
{
// it isnt there
}

Share this post


Link to post
Share on other sites
You should go with Arek the Absolute's solution: it's pretty efficient, as in fact it's using the bits of the integer you're passing as booleans. Unless that doesn't suit your needs, I'd say, go for it.


You need to define a few constants, the values you want to check for, and these have to be powers of two. In pseudo-code:
SMART = 1;
STRONG = 2;
FAST = 4;

You can then use a single integer to pass a combination of these values:
CreateMonster("Fast, smart monster", FAST | SMART);

The binary OR operator combines the two values 1 and 4, to 5. You could use + as well but it messes up when you use one of the constants twice, so the OR operator is safest. Binary, the integer is now 101, where the left-most bit is the FAST flag, the center bit is the STRONG flag and the right-most bit the SMART flag. As you can see, the FAST and SMART bits are set, just as you wanted.
You can check the integer as following:

if(integer & SMART != 0)
// the SMART bit is set

What it does is bitwise AND'ing the integer, so if the SMART bit is 1, then the result isn't 0. You can check the integer for every constant you want to check for this way. Keep in mind that the number of flags you can pass is limited to the size of the variabele in bits.

Share this post


Link to post
Share on other sites
Quote:

Example
X = 1 and 2 and 3 and 4.
If( input == x)
{
//do what ever…
}



If it's only a couple of numbers, maybe use a switch statement:


switch( input )
{
case 1:
case 2:
case 3:
case 4:
doWhatever();
break;

default:
doSomethingElse();
break;
}




-JR

Share this post


Link to post
Share on other sites
I'd consider using an enum with a switch statement. Like this:
enum value_type {VALUE_ONE   = 1,
VALUE_TWO = 2,
VALUE_THREE = 3,
VALUE_FOUR = 4};

value_type input;

// Get input

switch(input)
{
case VALUE_ONE:
//do stuff
break;
case VALUE_TWO:
//do stuff
break;
case VALUE_THREE:
//do stuff
break;
case VALUE_FOUR:
//do stuff
}



Share this post


Link to post
Share on other sites
Quote:
Original post by Arek the Absolute
Logical operators, in this case logical OR: ||

if (input == 1 || input == 2)

Similarly, there is also logical AND: &&

if (input > 0 && input <= 10)

for instance, checks whether the variable is within a certain range.


QFT! There's been alot of other posts that are needlessly complicated and unreadable! Stick with what's easy, readable, and fast. I think some people took the thread title literally, while the actual post was about something a little different.

Share this post


Link to post
Share on other sites
Ok this is what I got so far from all the replyes that I have got.


vector<int> list;




int main(int argc, char *argv[])
{
//had to put this loop first before the veriabls to get it to work
for (int x = 0; x <= 11; x++)
{
list.push_back(x);
}


int input ;
int Armor = 0;
int gold = 10;
int stat1 = 0;
int stat2 = 0;
int armorclass = 0;
int IteamPrice = 0;
string ArmorName = "Unarmored";

cout<<"0. Unarmored AC: +0 Max Dex: INF"<<endl
<<"1. Padded Armor AC: +1 Max Dex: +8 5g"<<endl
<<"2. Leather Armor AC: +2 Max Dex: +6 10g"<<endl
<<"3. Hide Armor AC: +3 Max Dex: +4 15g"<<endl
<<"4. Studded Leather AC: +3 Max Dex: +5 25g"<<endl
<<"5. Scale Mail AC: +4 Max Dex: +3 50g"<<endl
<<"6. Chain Shirt AC: +4 Max Dex: +4 100g"<<endl
<<"7. Chainmail AC: +5 Max Dex: +2 150g"<<endl
<<"8. Breastplate AC: +5 Max Dex: +3 200g"<<endl
<<"9. Splint Mail AC: +6 Max Dex: +0 225g"<<endl
<<"10. Banded Mail AC: +6 Max Dex: +1 250g"<<endl
<<"11. Half-Plate AC: +7 Max Dex: +0 600g"<<endl
<<"12. Full Plate AC: +8 Max Dex: +1 1000g"<<endl;

cout<<"Pick your Armor type "<<endl<<endl;
cout<<endl<<"Tour curent armor type is "<<ArmorName<<endl;
cout<<"You have "<<gold<<" Gold left."<<endl;
cout<<"Choice: ";

vector<int>::iterator x = find( list.begin(), list.end(), input );


cin>>input;

if (x == list.end() )
{

if(Armor != input)
{

if(gold >= 9)//how to put iteam price here from reading the input
{
//the meat or center of my function
//every thing else was to check to make
//sure the player could get this far
//now that you are here need to beable to
//add states and take away gold ect

gold -= IteamPrice;
stat1 = 10;
stat2 = 20;
armorclass = 5;
ArmorName = " test";


}
else
{
cout<<"you dont have enogh gold";

}
}

else
{
cout<<"you have that already doop";
}


}
else
{

cout<<"nope"<<endl;

main(0,0);
}



system("PAUSE");
return EXIT_SUCCESS;
}





Now all I have to do is take the number inputed and find the corsponding veribel and then pull that states(for a lack of a better term) from it and fill out the veribles with the need info

can any one aid me on how to do it I think I almost got it but it is just on the tip of my brain and cant quit get it.

Thanks for all the help so far.

Edit:
Never mid I just add a switch statment and it all works together
so I just combined all the options and it all worked

Thanks again for all the help

And if you want to see the end code just let me know.

Share this post


Link to post
Share on other sites
Quote:
QFT! There's been alot of other posts that are needlessly complicated and unreadable! Stick with what's easy, readable, and fast. I think some people took the thread title literally, while the actual post was about something a little different.

See, I thought that he didn't know the number of items that he had to check against, so doing
if( input == 1 || input == 2 ..... )
wouldn't work.

Quote:
Now all I have to do is take the number inputed and find the corsponding veribel and then pull that states(for a lack of a better term) from it and fill out the veribles with the need info

can any one aid me on how to do it I think I almost got it but it is just on the tip of my brain and cant quit get it.

Now, I am not trying to discourage you, but the way you are doing this is so very complicated that I can hardly understand what you are trying to do. If you can wait until tomorrow, I can show you a revised solution that would be much easier to implement and maintain. I'm sorry, but your code is very twisted and mangled, and some of your ideas would be much easier to implement if you took a look at things such as classes and functions.

Share this post


Link to post
Share on other sites
Quote:
Original post by ussnewjersey4

Now, I am not trying to discourage you, but the way you are doing this is so very complicated that I can hardly understand what you are trying to do. If you can wait until tomorrow, I can show you a revised solution that would be much easier to implement and maintain. I'm sorry, but your code is very twisted and mangled, and some of your ideas would be much easier to implement if you took a look at things such as classes and functions.



Ya I can wait if you have a better clear way to do it.

Thanks I would very much aperitat it.

Share this post


Link to post
Share on other sites
normally, you'd simply write a basic wrapper class around your variable type, so that you can easily assign multiple different values to a container class. For example, use something along the lines of:


#include <iostream>
#include <vector>

template <class TYPE>
class MyNumContainer {
public:
MyNumContainer& operator= (TYPE a) {_nums.push_back(a);}
TYPE& operator== (TYPE n) {return search(n);}
private:
TYPE& search(TYPE &a) {
bool match=false;

for (int i=_nums.size(); i>=0;i--) {
TYPE& cmp=_nums[i];
if (cmp==a) return cmp; //match
}
}
std::vector<TYPE> _nums;
};

int main()
{
MyNumContainer<int> X; //set up a container of ints named X
int input=0;

X=1; X=2; X=3; X=4; // set up X to contain various numbers

if (X==input) //compare input against X
std::cout << input << " is contained within X" << std::endl;
else
std::cout << input << " is not contained within X" << std::endl;



return 0;
}

HTH


Share this post


Link to post
Share on other sites
Quote:
Original post by ussnewjersey4
Quote:
QFT! There's been alot of other posts that are needlessly complicated and unreadable! Stick with what's easy, readable, and fast. I think some people took the thread title literally, while the actual post was about something a little different.

See, I thought that he didn't know the number of items that he had to check against, so doing
if( input == 1 || input == 2 ..... )
wouldn't work.


Good point. His first post didn't really say that, but I guess that it is definately a possibility. It's just that Arek's response was the most similiar to his example of what he wanted.

Share this post


Link to post
Share on other sites
Quote:
Original post by Everyman
normally, you'd simply write a basic wrapper class around your variable type, so that you can easily assign multiple different values to a container class. For example, use something along the lines of:

*** Source Snippet Removed ***


That's nice, but I'd replace the operator =() with a method, named something, something like storeValue or whatever. Only to appease the "rule of least suprise". People have expectations on how things work, so:


MyNumContainer X;
X = 4;
bool b1 = (X == 4); // b1 should be true
X = 7;
bool b2 = (X == 7); // b2 should be true
bool b3 = (X == 4); // b3, by expectations, should be false


Don't underestimate the amount of assumptions we as programmers make about the language. If you changed the equals operator to a "store" method, then you immediately make the code more self-commenting, which is always better than hoping someone reads the comments you wrote about your class. It is a nice idea though! I very well may implement an almost identical piece of code in my library.

Edit: And names that begin with an underscore are reserved by the standard library. They could be variables, functions, or even macros. I'd especially be wary of _nums, as it's the sort of thing people would use. Underscores at the end of variable names have traditionally been used to represent private member variables.

Share this post


Link to post
Share on other sites
So question how would I get rid of all these switch statments?


if(x == list.end() )
{
if(ArmorT != input)
{
if(Gold >= test)//how to put iteam price here from reading the input
{
//the meat or center of my function
//every thing else was to check to make
//sure the player could get this far
//now that you are here need to beable to
//add states and take away gold ect
switch(input)
{
case 1:
Gold -= 5;
Dexterity += 8;
ArmorClass += 1;
Armor = "Padded Armor";
ArmorT =input;
break;

case 2:
Gold -= 10;
Dexterity += 6;
ArmorClass += 2;
Armor = "Leather Armor";
ArmorT =input;
break;
case 3:
Gold -= 15;
Dexterity += 4;
ArmorClass += 3;
Armor = "Hide Armor";
ArmorT =input;
break;
case 4:
Gold -= 25;
Dexterity += 5;
ArmorClass += 4;
Armor = "Studded Leather";
ArmorT =input;
break;
case 5:
Gold -= 50;
Dexterity += 3;
ArmorClass += 5;
Armor = "Scale Mail";
ArmorT =input;
break;
case 6:
Gold -= 100;
Dexterity += 4;
ArmorClass += 6;
Armor = "Chain Shirt";
ArmorT =input;
break;
case 7:
Gold -= 150;
Dexterity += 2;
ArmorClass += 7;
Armor = "Chainmail";
ArmorT =input;
break;

case 8:
Gold -= 200;
Dexterity += 3;
ArmorClass += 8;
Armor = "Breastplate";
ArmorT =input;
break;
case 9:
Gold -= 225;
Dexterity += 0;
ArmorClass += 9;
Armor = "Splint Mail";
ArmorT =input;
break;
case 10:
Gold -= 250;
Dexterity += 1;
ArmorClass += 10;
Armor = "Banded Mail";
ArmorT =input;
break;
case 11:
Gold -= 600;
Dexterity += 0;
ArmorClass += 11;
Armor = "Half-Plate";
ArmorT =input;
break;
case 12:
Gold -= 1000;
Dexterity += 1;
ArmorClass += 12;
Armor = "Full Plate";
ArmorT =input;
break;

}
}//end of if

else //else for third if statment
{
cout<<"you dont have enogh gold";

}
}//end of if

else//else for second if statment
{
cout<<"you have that already doop";
}


}
else//else for first if statment
{

cout<<"nope"<<endl;

main(0,0);
}




so you see how they are so similar How can I use that to my adavtage and have soemthing like

Gold -= IteamSelected(price);
Dexterity += IteamSelected(DEX);
ArmorClass += IteamSelected(AC);
Armor = IteamSelected(Name);
ArmorT =IteamSelected(Type);

Share this post


Link to post
Share on other sites
Oh, is *that* what you're trying to do?

Please pay careful attention, this is *fundamental*. And incredibly important.

The first step you take is to put the data into arrays, and use the 'input' to select from the array. That gets rid of most of the huge mass of code.


int costs[12] = { 5, 10, 15, 25, 50, 100, 150, 200, 225, 250, 600, 1000 };
int addedDex[12] = { 8, 6, 4, 5, 3, 4, 2, 3, 0, 1, 0, 1 };
int protection[12] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 };
// You could of course just use the input directly in the code below:
// i.e. 'ArmorClass += input;' But that reduces the flexibility of your data,
// which you'll eventually be reading into structures from a file. Dumb stuff
// like this goes into data, not code.
const char* names[12] = { "Padded Armor", "Leather Armor", "Hide Armor",
"Studded Leather", "Scale Mail", "Chain Shirt",
"Chainmail", "Breastplate", "Splint Mail",
"Banded Mail", "Half-Plate", "Full Plate" };
// We don't make an array of ArmorT values, because it's clear that the design
// requires us to use unique values in order for ArmorT, whereas there's no
// reason we wouldn't later want 'protection' values that don't follow those
// rules.

// Then, where you process input:
if (x == list.end()) {
if (ArmorT != input) {
if (input >= 1 && input <= 12) { // should check this first!
int index = input - 1;
// then *inside*, make sure we have enough gold:
if (Gold >= costs[index]) {
Gold -= costs[index];
Dexterity += addedDex[index];
ArmorClass += protection[index];
Armor = names[input];
ArmorT = input;
} else {
cout << "you don't have enough gold" << endl;
}
} else {
cout << "we don't have that" << endl;
}
} else {
cout << "you have that already doop" << endl;
}
} else {
cout << "nope" << endl;
// WTF? DO NOT call back to main(). This smells a lot like you're trying to
// treat function calls like gotos; functions don't work like that. They are
// supposed to represent tasks; the idea is that you arrange for the function
// to return when it is done, in such a way that the caller can pick up where
// it left off.
// main(0,0);
}



The next step is to rearrange the data into structs, so that the related data gets bound together into nice units. Trust me, maintaining an array of structures is much more fun than maintaining a set of arrays.

(You could also skip the first step and come here directly, with a little practice.)


// Since we will later want to read the structures in from a file, suddenly it
// seems like using real strings is a good idea.

struct Armor {
int cost;
int addedDex;
int protection;
string name;

// Constructors make our lives easier
Armor(int cost, int addedDex, int protection, const string& name) :
cost(cost), addedDex(addedDex), protection(protection), name(name) {}
};

// Since we'll be reading these in later, let's not hard-code the quantity
vector<Armor> armors;
armors.push_back(Armor(5, 8, 1, "Padded Armor"));
armors.push_back(Armor(10, 6, 2, "Leather Armor"));
// I'm sure you can figure out how to do the rest :)

// Then, where you process input:
if (x == list.end()) {
if (ArmorT != input) {
// quick fix to the code here so that we can handle whatever number of
// armors we actually have:
if (input >= 1 && input <= armors.size()) {
// Notice how we can now do less of the ugly indexing work:
Armor& a = armors[input - 1];
if (Gold >= a.cost) {
Gold -= a.cost;
Dexterity += a.addedDex;
ArmorClass += a.protection;
Armor = a.name; // a.name.c_str(), if you were using a char*
// but please don't!
ArmorT = input;
} else {
cout << "you don't have enough gold" << endl;
}
} else {
cout << "we don't have that" << endl;
}
} else {
cout << "you have that already doop" << endl;
}
} else {
cout << "nope" << endl;
}



Next is to create a file format and read the data in from files, instead of having a bunch of armors.push_back()s. I don't know what you already have in terms of files, so I'll leave this up to you for now :)

Finally, you can clean up the code so that you don't need to do the arithmetic work here (by the way, ever gave any thought to undoing the effect of the previous armor? x.x). For example, you might have some Player object that contains an Armor (you can just copy it out of the armors vector; you just let those instances be "prototypes"), Weapon etc., and when you need to know the player's Dexterity for example, you *calculate* it:


int Player::Dex() {
return m_speciesDex + m_Weapon.addedDex + m_Armor.addedDex;
}

Share this post


Link to post
Share on other sites
Wow that is exactly what I need to know I will learn what you have showed me and continue from there and see if I can figure out how to do it from files but one step at a time for now.

Thanks so much for showing me that it makes a lot of since.

Thanks again

Share this post


Link to post
Share on other sites

This topic is 4108 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this