Sign in to follow this  

Q abt enumerators & arrays

Recommended Posts

//First, please look at my compiled code below :) #include <iostream> #include <cstdlib> #include <ctime> using namespace std; // Word jumble guessing game (with 3 words!) int main()//Main { //Below - This enumeration defines 2 constants for accessing the array:- enum fields {WORD, HINT, NUM_FIELDS}; const int NUM_WORDS = 3; const string WORD_HINTS[NUM_WORDS][NUM_FIELDS]= { {"wall", "bang ur head on it!"}, {"cool", "rhymes with school"}, {"cooperate", "working together"}, }; //selecting a random word out of the (3) words above:- srand(time(0)); int choice = (rand()% NUM_WORDS); //random no = choice string word = WORD_HINTS[choice][WORD];//word 4 user, b4 jumbling string hint = WORD_HINTS[choice][HINT];//hint 4 user // creating the jumbled word:- string jumbled_word = word; int length = jumbled_word.size(); for (int i=0; i<length; ++i) { int index1 = (rand()%length); int index2 = (rand()%length); char tmp = jumbled_word[index1]; jumbled_word[index1] = jumbled_word[index2]; jumbled_word[index2] = tmp; } // Instructions:- cout<<"Game Instructions:\n"; cout<<"Enter 'hint' - for a hint\n'quit' + press Enter - to quit"; cout<<"\n\nThe jumble is.." + jumbled_word + "\n"; // User enters guess:- string guess; cout<<"\nYo guess please:-\n\n"; cin>>guess; //Entering game loop:- while ((guess != word) && (guess != "quit")) { if (guess == "hint") cout << "\n" + hint + "\n\n"; else cout << "wrong answer, try again please..\n"; cin>>guess; } //Exiting prog:- if (guess == word) cout<<"\nCorrect buddy boy!\n\nPress Enter to get the hell outta ere!"; //Required to keep info on the screen & keep compiler happy:- getc(stdin); getc(stdin); return 0; }// end Main ========================================================== The above is some code I modified a bit from a book (Beginning C++ Game Programming). I have a rough idea of what's going on, but am confused with some parts of the code.. In particular, Lines 21-2 ("string word = WORD_HINTS[choice][WORD];" & "string hint = WORD_HINTS[choice][HINT];") confuses me completely. Through experimentation, I removed choice & replaced it with a number between 0-2 (size of my array) and understand that it refers to an element of the array. However, I just don't get the format WORD_HINTS[choice][WORD]; Eg, in my declaration (Ln11) WORD_HINTS is - const string WORD_HINTS [NUM_WORDS] [NUM_FIELDS] - I understand this to be an array of 3x2, but why when I define 'word'(Ln21) & 'hint' (22) why do I refer to [choice] & [HINT] ? I really don't understand what's going on with the enumerator & array. Any tips, explanations of what's REALLY happening (as opposed to the vague - probably incorrect - idea in my head) would be greatly appreciated.

Share this post

Link to post
Share on other sites
Yeah, you have a 3x2 array. So the first array selection is going to select a 2-element "row" of the array, then the second array selection selects an element out of that.

"choice" is a randomly selected value (out of the legal possibilities) that is used to grab one of the rows randomly. Then you want to grab the two std::string elements and put them into separate variables "word" and "hint", for later use.

This is where the enumeration comes in: In C++, an enumerated type is its own type, but it is still "backed by" the integer type - the different enumeration values correspond to integers, starting at 0 and counting upwards. Thus WORD == 0, HINT == 1, and NUM_FIELDS == 2.

There is actually a common idiom being used here: when an enumeration will be used to select items from an array, one adds an item to the end which is a "count of items" - then it can be used for specifying array dimensions, since it's constant. Basically, an n-element array has valid indices 0 up to n-1, so we give all n names in the enumeration (which take values 0 to n-1), and then add some name like "NUM_WHATEVER" at the end, which takes value n. See, another reason to learn and love 0-based array indexing. :)

That's the rough explanation. Now here are a couple of technicalities:

First, like I was saying, enumerations in C++ define their own type. Since you have an enum "fields", you can declare "fields myFieldValue;", and it is of type "fields", not of type "int". (In C, you could make the same declaration, but it would basically be an int-typed variable.) And this type basically sub-types int - you can use a "fields" variable (or constant) as an integer (hence the array selection), but you need a cast in order to treat an integer like a "fields" - and the compiler won't protect you if you put in a bad value:

fields w = HINT; // ok
fields x = 1; // compile error
fields y = (fields)1; // ok, but be careful
fields z = (fields)3; // Here Be Dragons (at runtime)

Second, the array WORD_HINTS, with a known value for each dimension, isn't really a two-dimensional array - it's laid out in memory as a single-dimension array, one row after another, and the compiler adds the necessary arithmetic logic between your array indices in order to grab the relevant thing. This isn't really important for normal usages, but when you try to pass these "two-dimensional arrays" around to functions, it will explain a lot of the weirder things that may happen. For example:

void foo(const string[3][2] x);
foo(WORD_HINTS); // ok
void bar(const string** x, int width, int height);
bar(WORD_HINTS); // you might expect that to be ok, but actually you need to
// pass it as a string*, ...
void baz(const string* x, int width, int height);
baz(WORD_HINTS); // and do the indexing math yourself now. This is because
// pointers don't carry the information about dimensions that an array does,
// and multi-dimensional arrays are really single-dimension - all the array
// indexing information only exists at compile-time.

My advice would be to try not to pass arrays around at all if you can avoid it. (Wrapping them in a struct may work for you.) And I would also strongly advise that you read this, and the next three sections - especially the last of those four. Heck, read the whole page. (Heck, read the whole FAQ if you have time. Lots of good stuff in there, although a fair bit of it is probably above your level for the moment.)

Share this post

Link to post
Share on other sites
Thanx for the advice Zahlman :) I'm going to read the FAQ you gave me & see if I can work this code out. Some of what you wrote made sense - but I think I need a lot more practice (& definately need to read the FAQ) b4 I fully understand it.

Why is it bad to have 'char' in ur code? -If I try changing "char tmp" (Ln31) to "string tmp" I get errors.. Anyways, thanks again for taking the time to help me! :)

PS: Any other advice / links I should read will be greatly appreciated :)

Share this post

Link to post
Share on other sites

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