[Begininger] - Textbase adventure project

D7e6f7351b2b2e8bee27964ac843b1dc
0
Jynks 101 Dec 08, 2005 at 06:04

I’m very new to programming and was thinking of making a text based adventure as a way to test my emerging skills. Be warnned I am very new to all this. I hope by the end of this thread to build a small txt based adventure project.

At the moment I am planning on using a multidimentional vector array to store the “rooms”. Then use a “iterator” to symbolize the player as they move though the grid. - Is this a good way to go?

Also I was woundering if there is a way to break up string inputs from the user to split their responses into individual words that i can then run things on linke conparing them to a database of acepted words for a given action in the game.

I found this but I do not understand how to implement it

http://www.codeproject.com/string/stringsplit.asp

24 Replies

Please log in or register to post a reply.

B7568a7d781a2ebebe3fa176215ae667
0
Wernaeh 101 Dec 08, 2005 at 07:14

Hi there ;)

First,
>>multidimentional vector array to store the “rooms”. Then use a “iterator” <<
sounds a lot like STL to me ;)

I think this is not really stuff to begin with =) Keep it simple, like, just have a normal array that contains all rooms, and then store an index or a pointer that indicates where your player currently is.

Sorry, gotta rush, next lecture course beginning in minus 5 minutes, I’ll check back later.

Cheers,
- Wernaeh

6f0a333c785da81d479a0f58c2ccb203
0
monjardin 102 Dec 08, 2005 at 14:06

There was a similar discussion here: Simple question…

6f0a333c785da81d479a0f58c2ccb203
0
monjardin 102 Dec 08, 2005 at 14:30

The boost library has a tokenizer: boost::tokenizer
It splits strings and allows you to iterate over the tokens (pieces).
I would suggest writing your own string splitter. It’s a fairly trivial algorithm and would give you a better understanding of manipulating strings.

As to the multi-dimensional vector, I assume you mean something like this:

class Room;
typedef vector< vector< Room> > GameMap;

Using a regular iterator traverses the list of row vectors (or columns, depending on your semantics). The easiest thing would probably be to store the x/y location of the player and access each room like this:

GameMap rooms;
rooms[x][y];

Make sure to bounds check the coordinates.

Of course, you are limiting your map to a grid structure. Alternatively, you could use a regular vector and have each Room class store the ID of the rooms you can reach from there. Keep the IDs zero-base & sequential, and sort the vector by ID. Now you have quick, random access to any room, and you only need to store the ID of the Room the player is in. A room could be a dead end, or a portal to every other room.

8563f7b73aeb34bb8604f1dd8f546c88
0
Mattias_Gustavsson 101 Dec 08, 2005 at 14:47

Check out the strtok function, very handy for splitting strings.

6f0a333c785da81d479a0f58c2ccb203
0
monjardin 102 Dec 08, 2005 at 14:53

Just don’t use strtok on the output of std::string::c_str. It modifies the input buffer. You would need to copy the string to a char[] and then call strtok.

D7e6f7351b2b2e8bee27964ac843b1dc
0
Jynks 101 Dec 09, 2005 at 01:13

Hi there… thanks for the tips guys…. I think I have almost got it sorted. here is the code for what I am doing at the moment. It splits up the string and extracts the words you choose.

#include <iostream>
#include <string>
using namespace std;
int main ()
{

    string thisIsTheString = "Dream your little dreams.";
    cout << "\nThe String is:- " << thisIsTheString;
    cout << "\nThe String Size is:- " << thisIsTheString.size();
    cout << "\nPick a word to find 0 = your -> 2 = dreams.\n";
    int wordToFind = 0;
    cin >> wordToFind;
    const char WHITESPACE = ' ';
    int subString_start = thisIsTheString.find_first_of ( WHITESPACE );

    

    while (wordToFind > 0) {
        wordToFind--;
        subString_start = thisIsTheString.find_first_not_of( WHITESPACE, subString_start );
        subString_start = thisIsTheString.find_first_of( WHITESPACE, subString_start );
    }
    int subString_end = thisIsTheString.find_first_of( WHITESPACE, (subString_start+1) );
    
    cout << "\nThe final result:\n" << thisIsTheString.substr( subString_start +1, subString_end - subString_start -1 );

    cout << "\n\n\n\nPlease press enter to exit program.";
    cin.ignore(cin.rdbuf()->in_avail() + 1);
return 0;
}

There is still some improvement I can do to it.. I need to add an if statement to return the first word in the string… also I need to add a bit of code to strip out all (if any) punctuation (. , ; : ‘ “ - + = etc etc etc) but that is not wat I am looking for answers for. Also I need to add the code I have to convert it all to upper case.

Like I said I am very new to all this and was wondering how I would set up the function for this thing….

Basically I need to input two things into the function… the string I want to test and the number of the word I wish to extract.

eg:-
string = “Hello, I need some help thanks.”
findnumber = 1

Q - How do I set up a function to accept arguments.. I have only done void ones so far….

Also if you can figure it out why is “0” returning the 2nd word in the code I have written.. and is there a way to fix that? I was planning to use a if statement in the function with a return in it to automatically return the first word. And any thoughts as to how I can automaticaly strip out the words into a word list array.. any thoughts on that would be welcome.

6f0a333c785da81d479a0f58c2ccb203
0
monjardin 102 Dec 09, 2005 at 16:43

This line is your culprit:
int subString_start = thisIsTheString.find_first_of ( WHITESPACE );
Change it to:
int subString_start = 0;
Function:

std::string getWord( const std::string& text, int index ) {   
    // your algorithm here...
    return thisIsTheString.substr( subString_start +1, subString_end - subString_start -1 );
}
D7e6f7351b2b2e8bee27964ac843b1dc
0
Jynks 101 Dec 09, 2005 at 20:09

thank you so much.. I couldn’t get the function to work as I didn’t knw about the string& thing…

I had pretty much the same code but no “&”. What exactly dose the & mean?

I have already got the caps thing working and the remove punctuation.

for (int j=0; j<str1.length(); ++j)
    {
    str1[j]=toupper(str1[j]);
    }
    while (str1.find("`") != string::npos){
        str1.erase(str1.find("`"),1); 
    }
    while (str1.find("~") != string::npos){
        str1.erase(str1.find("~"),1); 
    }
    while (str1.find("!") != string::npos){
        str1.erase(str1.find("!"),1); 
    }
    while (str1.find("@") != string::npos){
        str1.erase(str1.find("@"),1); 
    }
    while (str1.find("#") != string::npos){
        str1.erase(str1.find("#"),1); 
    }
    while (str1.find("$") != string::npos){
        str1.erase(str1.find("$"),1); 
    }
    while (str1.find("%") != string::npos){
        str1.erase(str1.find("%"),1); 
    }
    while (str1.find("^") != string::npos){
        str1.erase(str1.find("^"),1); 
    }
    while (str1.find("&") != string::npos){
        str1.erase(str1.find("&"),1); 
    }
    while (str1.find("*") != string::npos){
        str1.erase(str1.find("*"),1); 
    }
    while (str1.find("(") != string::npos){
        str1.erase(str1.find("("),1); 
    }
    while (str1.find(")") != string::npos){
        str1.erase(str1.find(")"),1); 
    }
    while (str1.find("_") != string::npos){
        str1.erase(str1.find("_"),1); 
    }
    while (str1.find("-") != string::npos){
        str1.erase(str1.find("-"),1); 
    }
    while (str1.find("=") != string::npos){
        str1.erase(str1.find("="),1); 
    }
    while (str1.find("+") != string::npos){
        str1.erase(str1.find("+"),1); 
    }
    while (str1.find("|") != string::npos){
        str1.erase(str1.find("]"),1); 
    }
    while (str1.find("]") != string::npos){
        str1.erase(str1.find("}"),1); 
    }
    while (str1.find("}") != string::npos){
        str1.erase(str1.find("}"),1); 
    }
    while (str1.find("[") != string::npos){
        str1.erase(str1.find("["),1); 
    }
    while (str1.find("{") != string::npos){
        str1.erase(str1.find("{"),1); 
    }
    while (str1.find("'") != string::npos){
        str1.erase(str1.find("'"),1); 
    }
    while (str1.find(";") != string::npos){
        str1.erase(str1.find(";"),1); 
    }
    while (str1.find(":") != string::npos){
        str1.erase(str1.find(":"),1); 
    }
    while (str1.find("/") != string::npos){
        str1.erase(str1.find("/"),1); 
    }
    while (str1.find("?") != string::npos){
        str1.erase(str1.find("?"),1); 
    }
    while (str1.find(".") != string::npos){
        str1.erase(str1.find("."),1); 
    }
    while (str1.find(">") != string::npos){
        str1.erase(str1.find(">"),1); 
    }
    while (str1.find(",") != string::npos){
        str1.erase(str1.find(","),1); 
    }
//  while (str1.find("\") != string::npos){
//      str1.erase(str1.find("\"),1); 
//  }

//  while (thisIsTheString.find(""") != string::npos){
//      thisIsTheString.erase(thisIsTheString.find(" " "),1); 
//  }

This is the code I am using to do that, but I am having a problem with it.. I do not know how to search for \ or for “. As when I set up the while statment putting the \ or “ charicter into the find() “breaks” the line of code.

Apart from that I now have a completly working code to get a user input, remove most of the punctuation, convert it to caps and extract idividual words.

Now I just need to figure out how to automaticaly extract all the words and put them into a vector… .. . I’ll keep you posted.

6f0a333c785da81d479a0f58c2ccb203
0
monjardin 102 Dec 09, 2005 at 20:28

Glad to see you are making progress. The quote and backslash are special characters, and you have to use the ecape sequences ‘\”’ and ‘\\’ respectively.
Here is the first link google popped up: http://www-ccs.ucsd.edu/c/charset.html

A8433b04cb41dd57113740b779f61acb
0
Reedbeta 168 Dec 09, 2005 at 21:39

Also, instead of writing an enormous number of blocks for various characters like that, you can simply use

int i = str1.find_first_of("`~!@#$%^&*()_");
while (i != string::npos)
{
    str1.erase(i, 1);
    i = str1.find_first_of("`~!@#$%^&*()_");
}

The find_first_of function looks for any of the characters in the string you pass into it.

D7e6f7351b2b2e8bee27964ac843b1dc
0
Jynks 101 Dec 09, 2005 at 22:33

Thanks for all your help guys.. as someone learning from a book with no one I know programming this forum has been so informative. When I get good enough I’ll help others as thanks.

@Reedbeta - Great tip. I have iplamented it. Cheers

@monjardin - Escape sequences.. I knew that but forgot about it.. thanks… so many things to remember!!

I have finished coding the input phaser for my “learn c++ project” It will take any sentence, convert to caps, remove punctuation and place the data in a vector. I couldn’t have done it with out you guys!

What I am looking for now is a way to orginize it. Preferably if i could call all the code from a single line. I’ve been playing around with trying to get it all into a single function but not having much luck.

All I have to do now is figure out some way of comparing entire vectors to others and making operators off them

EG
word list array 1)-
SHOUT
SCREAM
YELL
HOLLER
BELLOW
CALL
CRY
EXCLAIM
etc etc etc etc

word list array 2) -
HELP
ASSISTANCE
AID
HAND
SAVED
SAVE

user input - Scream for help.

So if the program can find one of the words from the word list it can execute the command eg - “you scream for help, devmaters here you.”

Here is the finished code for the text phraser

// Text Phraser Code (temp) [10/12/2005 - Jynks]
//      Takes any user sentence input
//      removes any punctuation
//      Converts it to upper case
//      splits the sentence into individual words
//      puts each word into a vector array.

#include <iostream>
#include <string>
#include <vector>
using namespace std;

string userInput();
string ParseWord( const string& userInput, int wordNumber );
int main ()
{
    cout << "Please enter any sentence, you may use punctuation.\n\n";
    
    string calledfunction1 = userInput();

    int wordNumber = 0;
    string str1 = "temp";
    vector<string> wordlist;

// [START] Put the return value of the user input into a vector aray
    do
    {
        str1 = ParseWord( calledfunction1, wordNumber );
        wordlist.push_back(str1);
        ++wordNumber;
    }while (str1 != "");
    wordlist.pop_back();
// [END] Put the return value of the user input into a vector aray

    cout << "\n\nWord Number is: " << (wordNumber - 1) << endl;
    cout << "\n\nVector contains:\n";
    for (int i = 0; i < wordlist.size(); ++i)
        cout << wordlist[i] << endl;
    cout << "\nVector has these many items - " << wordlist.size();




    cout << "\n\n\n\nPlease press enter to exit program.";
    cin.ignore(cin.rdbuf()->in_avail() + 1);
return 0;
}

// [START FUNCTION] (User input) - Gets user input string, removes punctuation, converts to Caps
string userInput()
{
    string str1;
    getline(cin, str1);
    for (int j=0; j<str1.length(); ++j)
    {
    str1[j]=toupper(str1[j]);
    }
    int i = str1.find_first_of("`~!@#$%^&*()-_=+|}][{';:/?.>,<\\\"");
    while (i != string::npos)
    {
    str1.erase(i, 1);
    i = str1.find_first_of("`~!@#$%^&*()-_=+|}][{';:/?.>,<\\\"");
    }
    return str1;
}
// [END FUNCTION] (User Input) - Gets user input string, removes punctuation, converts to Caps

// [START FUNCTION] (Phrase Word) - Returns a single word from sentence string
//      userInput = Sentence String from user
//      wordNumber = Number of word in string to find
string ParseWord( const string& userInput, int wordNumber )
{

    const string WHITESPACE = " ";
    int string_start = userInput.find_first_not_of( WHITESPACE );
while( wordNumber > 0 ) {
        wordNumber--;
        string_start = userInput.find_first_of( WHITESPACE, string_start );
        string_start = userInput.find_first_not_of( WHITESPACE, string_start );
    }
int string_end = userInput.find_first_of( WHITESPACE, string_start );
if( string_start == string::npos ) {
        string_start = 0;
        string_end = 0;
    }
   return userInput.substr( string_start, string_end - string_start );

}
// [END FUNCTION] (Phrase Word) - Returns a single word from sentence string
7543b5c50738e23b200e69fe697ea85a
0
NomadRock 101 Dec 09, 2005 at 22:46

Sorry to hijack the thread, but I have to say im proud of you so far. You know well to start small, and also to take advice well and ask questions showing your effort.

It took me a bit to figure out what you were doing with wordNumber, but it is actually fairly clever. Here is where a good ammount of coments come in real handy. Not only for us, but for yourself. The code is small and all fresh in your mind, but later on when you want to come back to it, comments will help a lot. Anything clever should definately have an explaination. You should also put a comment at the top of the file explaining just what the hell the program is supposed to do, and probably even date it.

D7e6f7351b2b2e8bee27964ac843b1dc
0
Jynks 101 Dec 09, 2005 at 23:06

@NomadRock - Thank you. I am pretty happy with this as well, considering I have just started. I am really enjoying learning this so far. I have taken your advise and put in comments as well as updated the code in the last post.

6f0a333c785da81d479a0f58c2ccb203
0
monjardin 102 Dec 09, 2005 at 23:56

I think this would take your user input and give you a vector of words without the ParseWord function and much of the code in main. The std::getline function allows you to specify the delimiter for your words. In your case it’s a space ‘ ‘. This function uses a default parameter, which you may not have seen before.

void parseInput( const std::string& input, std::vector<std::string> words, char delim = ' ' ) {
  std::istringstream stream( input ); // this is like cin for you string
  while( !stream.eof() ) { // loop while there is data in the stream
    std::string word; // we'll put each word here temporarily
    // take the first word out of stream until we hit a delimeter,
    // skipping whitespace
    std::getline( stream, word, delim );
    words.push_back( word ); // store the word
  }
}

You would call it like this:

std::vector<std::string> words;
parseInput( userInput, words ); // the delim parameter defaults to a space

If this doens’t help don’t use it. ;)
Also, take a look at using iterators and algorithms when you are ready for them. For example, you can transform your input into all uppercase in the userInput function like this:

std::transform( str1.begin(), str1.end(), str1.begin(), std::toupper );

This iterates over the string from the beginning to the end, calls toupper with each character and then adds the character to the output iterator (the beginning of the same string in this case). I wouldn’t go this far yet, but it’s something to think about later. Iterators can save you troubles with bounds checking integer indexes.

D7e6f7351b2b2e8bee27964ac843b1dc
0
Jynks 101 Dec 10, 2005 at 06:40

@monjardin - I have yet to look into what you were talking about.. it dose sound a lot cleaner.. I’ll have a look at it latter.

I have got the program to search though to array lists of words and conpare them to the user input. This is a simple start for the room test program I will make. It will consit of just a box in a blank room. You will (hopefully) be able to interact with the box a bit and look around the room, but not move.

This is the start of it as I was trying to sort everything out… In this demo you can not look around, or do anything with the box apart from pick it up.

If you play the demo you can see that there is a lot of problems.. I can find the key words that will be used to execute the “pick up box” but can not figure out how to use them.

I have tried a number of things, but the variables that I build inside the for loops and the if statments do not seam to exist outside of themselves. So my original plan to use a simple && if statment using bool values from weather they found a word or not will not work.

Also I need advise in splitting up the data into seprate file I have never done that before and the cpp is getting messy and will get worse in future I think. As I will have to build large ammounts of word list arrays.

So the plan at the moment is to somhow get the search tests into a function that send back to the main program a true or false thing.. but not sure how to do it, as I will need to pass to the function an vector array list.

Here is the code so far…

// Text Phraser Code (temp) [10/12/2005] - Jynks
//      Takes any user sentence input
//      removes any punctuation
//      Converts it to upper case
//      splits the sentence into individual words
//      puts each word into a vector array.

#include <iostream>
#include <string>
#include <vector>
using namespace std;

string userInput();
string ParseWord( const string& userInput, int wordNumber );
int main ()
{
    cout << "Please enter any sentence, you may use punctuation.\n\n";
    string calledfunction1 = userInput();
    int wordNumber = 0;
    string str1 = "temp";
    vector<string> wordlist;

// [START] Put the return value of the user input into a vector aray
    do
    {
        str1 = ParseWord( calledfunction1, wordNumber );
        wordlist.push_back(str1);
        ++wordNumber;
    }while (str1 != "");
    wordlist.pop_back();
// [END] Put the return value of the user input into a vector aray

    string key = "temp";
    int numItems = 0;
    string box[13];
    box[numItems++]= "BOX";
    box[numItems++]= "CUBE";
    box[numItems++]= "CARTON";
    box[numItems++]= "CASE";
    box[numItems++]= "CASKET";
    box[numItems++]= "CHEST";
    box[numItems++]= "CRATE";
    box[numItems++]= "PACK";
    box[numItems++]= "PACKAGE";
    box[numItems++]= "RECEPTACLE";
    box[numItems++]= "TRUNK";
    box[numItems++]= "PORTMANTEAU";
    box[numItems++]= "COFINE";

    numItems = 0;
    string get[11];
    get[numItems++]= "GET";
    get[numItems++]= "AQUIRE";
    get[numItems++]= "GRAB";
    get[numItems++]= "ATTAIN";
    get[numItems++]= "FETCH";
    get[numItems++]= "OBTAIN";
    get[numItems++]= "PROCURE";
    get[numItems++]= "RECEIVE";
    get[numItems++]= "SECURE";
    get[numItems++]= "TAKE";
    get[numItems++]= "PICK";

    for (int i = 0; i < numItems; ++i) // Box for loop
    {
        key = box[i];
             for (int search = 0; search < wordlist.size(); search++) // search userInput
                if (key == wordlist[search])
                {
                    bool foundword2 = true;
                    cout << "\nI have found the word in the Vector - " << key;
                }
    }
    for (int i = 0; i < numItems; ++i) // get for loop
    {
        key = get[i];
             for (int search = 0; search < wordlist.size(); search++) // search userInput
                if (key == wordlist[search])
                {
                    bool foundword2 = true;
                    cout << "\nI have found the word in the Vector - " << key;
                }
    }

    


    cout << "\n\n\n\nPlease press enter to exit program.";
    cin.ignore(cin.rdbuf()->in_avail() + 1);
return 0;
}

// [START FUNCTION] (User input) - Gets user input string, removes punctuation, converts to Caps
string userInput()
{
    string str1;
    getline(cin, str1);
    for (int j=0; j<str1.length(); ++j)
    {
    str1[j]=toupper(str1[j]);
    }
    int i = str1.find_first_of("`~!@#$%^&*()-_=+|}][{';:/?.>,<\\\"");
    while (i != string::npos)
    {
    str1.erase(i, 1);
    i = str1.find_first_of("`~!@#$%^&*()-_=+|}][{';:/?.>,<\\\"");
    }
    return str1;
}
// [END FUNCTION] (User Input) - Gets user input string, removes punctuation, converts to Caps

// [START FUNCTION] (Phrase Word) - Returns a single word from sentence string
//      userInput = Sentence String from user
//      wordNumber = Number of word in string to find
string ParseWord( const string& userInput, int wordNumber )
{

    const string WHITESPACE = " ";
    int string_start = userInput.find_first_not_of( WHITESPACE );
while( wordNumber > 0 ) {
        wordNumber--;
        string_start = userInput.find_first_of( WHITESPACE, string_start );
        string_start = userInput.find_first_not_of( WHITESPACE, string_start );
    }
int string_end = userInput.find_first_of( WHITESPACE, string_start );
if( string_start == string::npos ) {
        string_start = 0;
        string_end = 0;
    }
   return userInput.substr( string_start, string_end - string_start );

}
// [END FUNCTION] (Phrase Word) - Returns a single word from sentence string
D7e6f7351b2b2e8bee27964ac843b1dc
0
Jynks 101 Dec 12, 2005 at 01:53

@monjardin - Thanks for you tips. I have been playing with the code you posted and it dose exactly what you say it will do.

The thing I am confused about with your version is the scope. Your function will take a string and then put the individual words of that string into a vector called words, but i am unsure how to get that vector back into the main program.

if i list the vector indise the function, I get the words all seperate, if i then list the vector words in the main function it will just list an empty funtion. You sugested using void in your function declaration and stuff.. dosn’t it mean that it dosn’t return anything?

// Text Phraser Code (temp) [10/12/2005] - Jynks
//      Takes any user sentence input
//      removes any punctuation
//      Converts it to upper case
//      splits the sentence into individual words
//      puts each word into a vector array.

#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <sstream>
using namespace std;

string userInput();
void parseInput ( const string& input, vector <string> words, char delim = ' ' );

int main ()
{
    cout << "Please enter any sentence, you may use punctuation.\n\n";
    
    string calledfunction1 = userInput();

    cout << "The first called Function is - " << calledfunction1;

    vector<string> words;
    parseInput( calledfunction1, words );

    cout << "\nThe vector called words inside MAIN:\n\n";
    for (int i = 0; i < words.size(); ++i)
        cout << words[i] << endl;



    cout << "\n\n\n\nPlease press enter to exit program.";
    cin.ignore(cin.rdbuf()->in_avail() + 1);
return 0;
}

//---------------------------------------------------------------------------------------------------------------------------
// Start User input function (Gets user input, removes all punctuation, converts user input into uppercase
//---------------------------------------------------------------------------------------------------------------------------
string userInput()
{
    string str1; // Declare String for user input
    getline(cin, str1); // Get User Input
    int i = str1.find_first_of("`~!@#$%^&*()-_=+|}][{';:/?.>,<\\\""); // Initalize "i" to the first occurence of punctuation in user input sting.
    while (i != string::npos)
    {
    str1.erase(i, 1); // Erase i from the user input string.
    i = str1.find_first_of("`~!@#$%^&*()-_=+|}][{';:/?.>,<\\\""); // Initalize "i" to the first occurence of punctuation in user input sting. (I is erased so it will find next)
    }
    transform( str1.begin(), str1.end(), str1.begin(), toupper ); // transform userinput into upper case.

    return str1;
}

//------------------------------------------------------------------------------------------------------------------------------------
// PHRASE INPUT - start --> Take string of words and split each word off the string and place in a seprate element of a vector.
//------------------------------------------------------------------------------------------------------------------------------------
void parseInput ( const string& input, vector <string> words, char delim )
{
    istringstream stream( input, delim );
    while( !stream.eof() ) { // loop while there is data in the stream
    string word; // we'll put each word here temporarily
    // take the first word out of stream until we hit a delimeter,
    // skipping whitespace
    getline( stream, word, delim );
    words.push_back( word ); // store the word
    }
    cout << "\n\n\nThe vector called words inside phraseInput function:\n\n";
    for (int i = 0; i < words.size(); ++i)
    cout << words[i] << endl;
    
}
D7e6f7351b2b2e8bee27964ac843b1dc
0
Jynks 101 Dec 12, 2005 at 02:38

Sorry I got that sorted already… it was just a silly error, I didn’t use a refrence for the words vector, I have had problems with refrences before. It is now working…

void parseInput ( const string& input, vector <string> words, char delim = ' ' )

// new line

void parseInput ( const string& input, vector <string> &words, char delim = ' ' )
6f0a333c785da81d479a0f58c2ccb203
0
monjardin 102 Dec 12, 2005 at 03:52

Sorry, I left out the ampersand! You fixed it correctly.

D7e6f7351b2b2e8bee27964ac843b1dc
0
Jynks 101 Dec 12, 2005 at 23:10

Hi there.

Basically I have built a program that can read a users text input and then “understand” it. The way it dose this is to take the user input then split it into each word, remove any punctuation found, capitalize the words, and then place those words in a vector. Once the user input is inside the vector, the program dose a search on the vectors comparing it to a number of word list arrays.

In the example I am posting I have made only a few word lists. The program will “understand” words that mean GET, DROP, LOOK and BOX.

The problem I have is NOW WAT?? I can find the words in the words list but how dose that help me?? Any ideas…

basically I need two bits if advise.

1) Now I have the words identified as “valid” what do I do next?
2) If I execute a command (eg - get box) how dose the program recognize that the room is in a different state?

here is the code and a exe to look at

TXT_Adventure-dev.exe

// Text Phraser Code (temp) [13/12/2005] - Jynks
//        Takes any user sentence input
//        removes any punctuation
//        Converts it to upper case
//        splits the sentence into individual words
//        puts each word into a vector array.

#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <sstream>
using namespace std;

string userInput(); // function - USER INPUT
void parseInput ( const string& input, vector <string> &words, char delim = ' ' ); // function PHRASE INPUT

int main ()
{

//---------------------------------------------------------------------------------------------------------------------------
// DEFINE WORD LISTS - START ---> Defines a set of arrays containing key words.
//---------------------------------------------------------------------------------------------------------------------------

    int wordListItems = 0;
    string wordlist_box[13];
    wordlist_box[wordListItems++]= "BOX";
    wordlist_box[wordListItems++]= "CUBE";
    wordlist_box[wordListItems++]= "CARTON";
    wordlist_box[wordListItems++]= "CASE";
    wordlist_box[wordListItems++]= "CASKET";
    wordlist_box[wordListItems++]= "CHEST";
    wordlist_box[wordListItems++]= "CRATE";
    wordlist_box[wordListItems++]= "PACK";
    wordlist_box[wordListItems++]= "PACKAGE";
    wordlist_box[wordListItems++]= "RECEPTACLE";
    wordlist_box[wordListItems++]= "TRUNK";
    wordlist_box[wordListItems++]= "PORTMANTEAU";
    wordlist_box[wordListItems++]= "COFINE";

    wordListItems = 0;
    string wordlist_get[10];
    wordlist_get[wordListItems++]= "GET";
    wordlist_get[wordListItems++]= "ACQUIRE";
    wordlist_get[wordListItems++]= "ATTAIN";
    wordlist_get[wordListItems++]= "CAPTURE";
    wordlist_get[wordListItems++]= "BAG";
    wordlist_get[wordListItems++]= "FETCH";
    wordlist_get[wordListItems++]= "GRAB";
    wordlist_get[wordListItems++]= "OBTAIN";
    wordlist_get[wordListItems++]= "PROCURE";
    wordlist_get[wordListItems++]= "TAKE";

    wordListItems = 0;
    string wordlist_look[19];
    wordlist_look[wordListItems++]= "BEHOLD";
    wordlist_look[wordListItems++]= "CONSIDER";
    wordlist_look[wordListItems++]= "LOOK";
    wordlist_look[wordListItems++]= "CONTEMPLATE";
    wordlist_look[wordListItems++]= "GAWK";
    wordlist_look[wordListItems++]= "GAZE";
    wordlist_look[wordListItems++]= "GLANCE";
    wordlist_look[wordListItems++]= "INSPECT";
    wordlist_look[wordListItems++]= "OBSERVE";
    wordlist_look[wordListItems++]= "NOTE";
    wordlist_look[wordListItems++]= "NOTICE";
    wordlist_look[wordListItems++]= "PEER";
    wordlist_look[wordListItems++]= "REGARD";
    wordlist_look[wordListItems++]= "SCAN";
    wordlist_look[wordListItems++]= "SCRUTINIZE";
    wordlist_look[wordListItems++]= "SEE";
    wordlist_look[wordListItems++]= "STUDY";
    wordlist_look[wordListItems++]= "VIEW";
    wordlist_look[wordListItems++]= "SURVEY";

    wordListItems = 0;
    string wordlist_drop[11];
    wordlist_drop[wordListItems++]= "ABANDON";
    wordlist_drop[wordListItems++]= "DUMP";
    wordlist_drop[wordListItems++]= "DROP";
    wordlist_drop[wordListItems++]= "RELEASE";
    wordlist_drop[wordListItems++]= "RELINQUISH";
    wordlist_drop[wordListItems++]= "UNLOAD";
    wordlist_drop[wordListItems++]= "DITCH";
    wordlist_drop[wordListItems++]= "FORSAKE";
    wordlist_drop[wordListItems++]= "LEAVE";
    wordlist_drop[wordListItems++]= "LOSE";
    wordlist_drop[wordListItems++]= "REJECT";

    wordListItems = 0;
    short IndexWords[4];
    IndexWords[wordListItems++]= 13;
    IndexWords[wordListItems++]= 10;
    IndexWords[wordListItems++]= 19;
    IndexWords[wordListItems++]= 11;
    

//---------------------------------------------------------------------------------------------------------------------------
// START ---> You beging here.
//---------------------------------------------------------------------------------------------------------------------------
    
    cout <<"\tTxt Adventure Game Demo - Learning Project";
    cout <<"\n\n\nYou are alive.\n\n> ";

    
    string userCommand = userInput(); // Get User input (call - function - USER INPUT)
    vector<string> words; // create vector to store the word lists from user input
    parseInput( userCommand, words ); // split user input up and place in words vector ( call function - PHRASE INPUT)
    int search_index = 0;
    int WordslistIndex = 0;

while ((userCommand != "QUIT") && (userCommand != "EXIT")) // Game loop conditions.
{

//---------------------------------------------------------------------------------------------------------------------------
// START ---> Eventually move this to a function or a seprate cpp file
//---------------------------------------------------------------------------------------------------------------------------
        search_index = 0;
        WordslistIndex = IndexWords[search_index++];
// Search BOX word List
            for (int i = 0; i < WordslistIndex; ++i){
                for (int search = 0; search < words.size(); search++)
                    if (wordlist_box[i] == words[search])
                        cout << "\nBOX search has found - " << wordlist_box[i];
                }
        WordslistIndex = IndexWords[search_index++];
// Search GET word List
            for (int i = 0; i < WordslistIndex; ++i){
                for (int search = 0; search < words.size(); search++)
                if (wordlist_get[i] == words[search])
                        cout << "\nGET search has found - " << wordlist_get[i];
                }
        WordslistIndex = IndexWords[search_index++];
// Search LOOK word List
            for (int i = 0; i < WordslistIndex; ++i){
                for (int search = 0; search < words.size(); search++)
                    if (wordlist_look[i] == words[search])
                        cout << "\nLOOK search has found - " << wordlist_look[i];
                }
        WordslistIndex = IndexWords[search_index++];
// Search DROP word List
            for (int i = 0; i < WordslistIndex; ++i){
                for (int search = 0; search < words.size(); search++)
                    if (wordlist_drop[i] == words[search])
                        cout << "\nLOOK search has found - " << wordlist_drop[i];
                }
//---------------------------------------------------------------------------------------------------------------------------


// - Repeat user input.
    cout <<"\n\n> ";
    userCommand = userInput();
    parseInput( userCommand, words );

} // - End for while Loop  - loop to start of phrase analisis

    cout << "\n\n\n\nPlease press enter to exit program.";
    cin.ignore(cin.rdbuf()->in_avail() + 1);
return 0;
}

//---------------------------------------------------------------------------------------------------------------------------
// USER INPUT - START ---> User input function (Gets user input, removes all punctuation, converts user input into uppercase
//---------------------------------------------------------------------------------------------------------------------------
string userInput()
{
    string str1; // Declare String for user input
    getline(cin, str1); // Get User Input
    int i = str1.find_first_of("`~!@#$%^&*()-_=+|}][{';:/?.>,<\\\""); // Initalize "i" to the first occurence of punctuation in user input sting.
    while (i != string::npos)
    {
    str1.erase(i, 1); // Erase i from the user input string.
    i = str1.find_first_of("`~!@#$%^&*()-_=+|}][{';:/?.>,<\\\""); // Initalize "i" to the first occurence of punctuation in user input sting. (I is erased so it will find next)
    }
    transform( str1.begin(), str1.end(), str1.begin(), toupper ); // transform userinput into upper case.

    return str1;
}

//------------------------------------------------------------------------------------------------------------------------------------
// PHRASE INPUT - start --> Take string of words and split each word off the string and place in a seprate element of a vector.
//------------------------------------------------------------------------------------------------------------------------------------
void parseInput ( const string& input, vector <string> &words, char delim )
{
    words.clear();
    istringstream stream( input, delim );
    while( !stream.eof() ) { // loop while there is data in the stream
    string word; // we'll put each word here temporarily
    // take the first word out of stream until we hit a delimeter,
    // skipping whitespace
    getline( stream, word, delim );
    words.push_back( word ); // store the word
    }
}

I have no idea how to do the game states yet but I am thinking that maybe I can do the “understand the word thing” with a fancy array and if statements.

You make an array with a element for each word LIST. in this case a 4 array, with BOX, GET, DROP, LOOK in it, and each of those elements assigned a value of 1. Then you get a return value from the word search saying “yes I have found the word box in user input” you basically put a ‘0’ in an array. Then using if statements and the && operators you can do things depending on what elements of the understandWord array is turned on. I would need to make a pretty comp[lex table in word or something to get all the combinations and it would get really hardcore once you are searching for a load of other words and not just four lists..

Any ideas on a better way to do this please let me know…

Thanks for you time and all those that have been helping me on this project so far!!

6f0a333c785da81d479a0f58c2ccb203
0
monjardin 102 Dec 13, 2005 at 01:50

I would suggest studying Object-Oriented Design (OOD) and learning how to use classes. That way you can structure your program into to objects (ie, a box or a door) each of which has state (member variables) and actions that can be taken on them (member functions).
You can then build a hierarchy. For example, you may have a room class that may contain any number of boxes and other items. It could have doors which would lead you to other rooms. The player is represented by an object the holds his/her inventory, location (i.e., which room he/she is in), health, etc.
I would also suggest learning to use file I/O via fstreams. They work in very much the same way as the iostreams you have already used. First, try populating your word lists from text files instead of hard coding them.
Ideally, you could create a natural language text game engine. Then a game could be fully defined simply by loading sets of data files.
There are a million ways to skin a cat. So, don’t let my advice drive you in a different direction than you want to go. Like my grandfather always says, “advice is worth what you pay for it.” ;)

D7e6f7351b2b2e8bee27964ac843b1dc
0
Jynks 101 Dec 13, 2005 at 02:05

@monjardin - Thanks for your advise again. I have been looking into classes and object for just that reason… but I was thinking of leaving datafiles on the back burner for a bit…. still mabey I should jump in.. I DID just jump into he adventure project when prob not ready for it :)

Just one quick thing…. . ..

I am trying to make a function of the word checking bit and function still confuse me…

I want to send the words vector as a refrence, the IndexWords array and recogWords array as a refrence and then send 2 ints that are only used in the function…. this is the code I am using so far…

void testUserInput (vector <string> &words, short &IndexWords[4], short &recogWords[5], int search_index = 0, int WordslistIndex = 0 );

void testUserInput (vector <string> &words, short &IndexWords[4], short &recogWords[5], int search_index, int WordslistIndex )

But I get erros all over the place.. I have tried a few diffrent things like moving the & arround and removing the [x] numbers from the arrays….

Any ideas?

6f0a333c785da81d479a0f58c2ccb203
0
monjardin 102 Dec 13, 2005 at 02:17

You really should be using a class for this! If you had a recognizer class that held the references to all of your words then you wouldn’t need to pass all these parameters.
Your problem is the arrays. Since they are passed as a pointer to memory there is no need to use a reference, even if you want to modify them.
Try to learn the answers to this kind of quesion from the multitude of great C++ tutorials online like this one: http://www.cplusplus.com/doc/tutorial/arrays.html
Step back and get a good grasp around functions and classes before you go further.

D7e6f7351b2b2e8bee27964ac843b1dc
0
Jynks 101 Dec 13, 2005 at 03:22

still you can do it this way can;t you?

D7e6f7351b2b2e8bee27964ac843b1dc
0
Jynks 101 Dec 15, 2005 at 02:51

Well I had another crack at the txt based adventure thing again today for a few hours.. and have built a very simply working room… it is basically just a demo of the text parser. You start in a infinitely large room that contains a box. You can interact with that box up to a point. And that is it…

Before I get into anything more I am thinking of starting from scratch but this time working on a simple character stats thing and inventory. To learn data structures and better understand classes and stuff. I will then come back and cannibalize this code to put the parser into the new version of the game… I may need to mod it a lot to fix errors I will learn not to do in the next part.

I am just getting real confused with it all at the mo and think while learning it is best to take each step real slow. So I’ll be starting on a character gen and stats thing now…

Still here is the box room code witch witch I have simplified the output text (for debug’n) as well as an exe with the full output mode for the true virtual box treatment :) lol

Thanks to everyone who helped me you have been very patient and with out you I would understand a lot less than I do from just reading the book itself. Especially “monjardin”.

I am still working on the text based adventure as a way to learn programming, so any suggestions as to how I can improve this will be taken aborad. Problems with the method I am using is that you can not recognize multi word strings (eg – pick up) also it looses any context of grammar…. (eg – look IN the box, look AT the box – at the moment it can not tell the difference)

Awakening_v0.2.exe

// Text Phraser Code (Box Demo) [15/12/2005] - Jynks
//      Takes any user sentence input
//      removes any punctuation
//      Converts it to upper case
//      splits the sentence into individual words
//      puts each word into a vector array.
//      compares each word of vector to various arrays full of word lists
//      if key words are found executs a command.

#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <sstream>
using namespace std;

string userInput(); // function - USER INPUT
void parseInput ( const string& input, vector <string> &words, char delim = ' ' ); // function PHRASE INPUT


class RecogUserInput {
public:
    void proccess(vector <string> &words, string &userCommand);
private:
    string wordlist_box[13];
    string wordlist_get[10];
    string wordlist_look[19];
    string wordlist_drop[11];
    string wordlist_kick[3];
    string wordlist_throw[14];
    string wordlist_punch[18];
    string wordlist_sit[5];
    string wordlist_push[4];
    string wordlist_pull[8];
    short recogWords[10];
    int search_index;
    int WordslistIndex;
};
void RecogUserInput::proccess(vector <string> &words, string &userCommand)
{
    wordlist_box[0]= "BOX";
    wordlist_box[1]= "CUBE";
    wordlist_box[2]= "CARTON";
    wordlist_box[3]= "CASE";
    wordlist_box[4]= "CASKET";
    wordlist_box[5]= "CHEST";
    wordlist_box[6]= "CRATE";
    wordlist_box[7]= "PACK";
    wordlist_box[8]= "PACKAGE";
    wordlist_box[9]= "RECEPTACLE";
    wordlist_box[10]= "TRUNK";
    wordlist_box[11]= "PORTMANTEAU";
    wordlist_box[12]= "COFINE";

    wordlist_get[0]= "GET";
    wordlist_get[1]= "ACQUIRE";
    wordlist_get[2]= "ATTAIN";
    wordlist_get[3]= "CAPTURE";
    wordlist_get[4]= "BAG";
    wordlist_get[5]= "FETCH";
    wordlist_get[6]= "GRAB";
    wordlist_get[7]= "OBTAIN";
    wordlist_get[8]= "PROCURE";
    wordlist_get[9]= "TAKE";

    wordlist_look[0]= "BEHOLD";
    wordlist_look[1]= "CONSIDER";
    wordlist_look[2]= "LOOK";
    wordlist_look[3]= "CONTEMPLATE";
    wordlist_look[4]= "GAWK";
    wordlist_look[5]= "GAZE";
    wordlist_look[6]= "GLANCE";
    wordlist_look[7]= "INSPECT";
    wordlist_look[8]= "OBSERVE";
    wordlist_look[9]= "NOTE";
    wordlist_look[10]= "NOTICE";
    wordlist_look[11]= "PEER";
    wordlist_look[12]= "REGARD";
    wordlist_look[13]= "SCAN";
    wordlist_look[14]= "SCRUTINIZE";
    wordlist_look[15]= "SEE";
    wordlist_look[16]= "STUDY";
    wordlist_look[17]= "VIEW";
    wordlist_look[18]= "SURVEY";

    wordlist_drop[0]= "ABANDON";
    wordlist_drop[1]= "DUMP";
    wordlist_drop[2]= "DROP";
    wordlist_drop[3]= "RELEASE";
    wordlist_drop[4]= "RELINQUISH";
    wordlist_drop[5]= "UNLOAD";
    wordlist_drop[6]= "DITCH";
    wordlist_drop[7]= "FORSAKE";
    wordlist_drop[8]= "LEAVE";
    wordlist_drop[9]= "LOSE";
    wordlist_drop[10]= "REJECT";

    wordlist_kick[0]= "KICK";
    wordlist_kick[1]= "PUNT";
    wordlist_kick[2]= "BOOT";

    wordlist_throw[0]= "THROW";
    wordlist_throw[1]= "CATAPULT";
    wordlist_throw[2]= "CAST";
    wordlist_throw[3]= "CHUCK";
    wordlist_throw[4]= "FLING";
    wordlist_throw[5]= "HEAVE";
    wordlist_throw[6]= "HURL";
    wordlist_throw[7]= "LAUNCH";
    wordlist_throw[8]= "LOB";
    wordlist_throw[9]= "PEG";
    wordlist_throw[10]= "PELT";
    wordlist_throw[11]= "PITCH";
    wordlist_throw[12]= "SLING";
    wordlist_throw[13]= "TOSS";

    wordlist_punch[0]= "PUNCH";
    wordlist_punch[1]= "BASH";
    wordlist_punch[2]= "BELT";
    wordlist_punch[3]= "CLOUT";
    wordlist_punch[4]= "CUFF";
    wordlist_punch[5]= "JAB";
    wordlist_punch[6]= "KNOCK";
    wordlist_punch[7]= "POKE";
    wordlist_punch[8]= "PROD";
    wordlist_punch[9]= "PUMMEL";
    wordlist_punch[10]= "SLAM";
    wordlist_punch[11]= "SLAP";
    wordlist_punch[12]= "SLUG";
    wordlist_punch[13]= "SMACK";
    wordlist_punch[14]= "SMASH";
    wordlist_punch[15]= "STRIKE";
    wordlist_punch[16]= "THUMP";
    wordlist_punch[17]= "WALLOP";

    wordlist_sit[0]= "SIT";
    wordlist_sit[1]= "PERCH";
    wordlist_sit[2]= "REST";
    wordlist_sit[3]= "SEAT";
    wordlist_sit[4]= "SQUAT";

    wordlist_push[0]= "PUSH";
    wordlist_push[1]= "MOVE";
    wordlist_push[2]= "NUDGE";
    wordlist_push[3]= "SHOVE";

    wordlist_pull[0]= "PULL";
    wordlist_pull[1]= "DRAG";
    wordlist_pull[2]= "HAUL";
    wordlist_pull[3]= "LUG";
    wordlist_pull[4]= "JERK";
    wordlist_pull[5]= "TUG";
    wordlist_pull[6]= "WRENCH";
    wordlist_pull[7]= "YANK";
    
    recogWords[0]= 1; //box
    recogWords[1]= 1; //get
    recogWords[2]= 1; //look
    recogWords[3]= 1; //drop
    recogWords[4]= 1; //kick
    recogWords[5]= 1; //throw
    recogWords[6]= 1; //punch
    recogWords[7]= 1; //sit
    recogWords[8]= 1; //push
    recogWords[9]= 1; //pull

    search_index = 0;

        for (int i = 0; i < 13; ++i){
            for (int search = 0; search < words.size(); search++)
                if (wordlist_box[i] == words[search]) {
//                  cout << "\nBOX search has found - " << wordlist_box[i];
                    recogWords[0] = 0;
                }
            }
        for (int i = 0; i < 10; ++i){
            for (int search = 0; search < words.size(); search++)
                if (wordlist_get[i] == words[search]) {
//                  cout << "\nGET search has found - " << wordlist_get[i];
                    recogWords[1] = 0;
                }
            }
        for (int i = 0; i < 19; ++i){
            for (int search = 0; search < words.size(); search++)
                if (wordlist_look[i] == words[search]) {
//                  cout << "\nLOOK search has found - " << wordlist_look[i];
                    recogWords[2] = 0;
                }
            }
        for (int i = 0; i < 11; ++i){
            for (int search = 0; search < words.size(); search++)
                if (wordlist_drop[i] == words[search]) {
//                  cout << "\nDROP search has found - " << wordlist_drop[i];
                    recogWords[3] = 0;
                }
            }
        for (int i = 0; i < 3; ++i){
            for (int search = 0; search < words.size(); search++)
                if (wordlist_kick[i] == words[search]) {
//                  cout << "\nKICK search has found - " << wordlist_kick[i];
                    recogWords[4] = 0;
                }
            }
        for (int i = 0; i < 14; ++i){
            for (int search = 0; search < words.size(); search++)
                if (wordlist_throw[i] == words[search]) {
//                  cout << "\nTHROW search has found - " << wordlist_throw[i];
                    recogWords[5] = 0;
                }
            }
        for (int i = 0; i < 18; ++i){
            for (int search = 0; search < words.size(); search++)
                if (wordlist_punch[i] == words[search]) {
//                  cout << "\nPUNCH search has found - " << wordlist_punch[i];
                    recogWords[6] = 0;
                }
            }
        for (int i = 0; i < 5; ++i){
            for (int search = 0; search < words.size(); search++)
                if (wordlist_sit[i] == words[search]) {
//                  cout << "\nSIT search has found - " << wordlist_sit[i];
                    recogWords[7] = 0;
                }
            }
        for (int i = 0; i < 3; ++i){
            for (int search = 0; search < words.size(); search++)
                if (wordlist_push[i] == words[search]) {
//                  cout << "\nPUSH search has found - " << wordlist_push[i];
                    recogWords[8] = 0;
                }
            }
        for (int i = 0; i < 8; ++i){
            for (int search = 0; search < words.size(); search++)
                if (wordlist_pull[i] == words[search]) {
//                  cout << "\nPULL search has found - " << wordlist_pull[i] << endl;
                    recogWords[9] = 0;
                }
            }


    if (userCommand == "LOOK")
        cout << "\nYou look around.\nYou see stuff including a box\n";
    if ((recogWords[0] || recogWords[1]) == 0)
        cout << "\nYou pick up the box.\n";
    if ((recogWords[0] || recogWords[2]) == 0)
        cout << "\nYou look at the box\n";
    if ((recogWords[0] || recogWords[3]) == 0)
        cout << "\nYou drop the box.\n";
    if ((recogWords[0] || recogWords[4]) == 0)
        cout << "\nYou kick the box.\n";
    if ((recogWords[0] || recogWords[5]) == 0)
        cout << "\nYou throw the box.\n";
    if ((recogWords[0] || recogWords[6]) == 0)
        cout << "\nYou punch the box.\n";
    if ((recogWords[0] || recogWords[7]) == 0)
        cout << "\nYou sit the box.\n";
    if ((recogWords[0] || recogWords[8]) == 0)
        cout << "\nYou push the box.\n";
    if ((recogWords[0] || recogWords[9]) == 0)
        cout << "\nYou pull the box.\n";
}



int main ()
{

    cout <<"\tTxt Adventure Game Demo - Learning Project";
    cout <<"\n\n\nYou are alive.\n\n> ";

    
    string userCommand = userInput(); // Get User input (call - function - USER INPUT)
    vector<string> words; // create vector to store the word lists from user input
    parseInput( userCommand, words ); // split user input up and place in words vector ( call function - PHRASE INPUT)
    int search_index = 0;
    int WordslistIndex = 0;

while ((userCommand != "QUIT") && (userCommand != "EXIT")) // Game loop conditions.
{

    RecogUserInput input1;
    input1.proccess(words, userCommand);
    cout <<"\n\n> ";
    userCommand = userInput();
    parseInput( userCommand, words );
}

    cout << "\n\n\n\nPlease press enter to exit program.";
    cin.ignore(cin.rdbuf()->in_avail() + 1);
return 0;
}

//---------------------------------------------------------------------------------------------------------------------------
// USER INPUT - START ---> User input function (Gets user input, removes all punctuation, converts user input into uppercase
//---------------------------------------------------------------------------------------------------------------------------
string userInput()
{
    string str1; // Declare String for user input
    getline(cin, str1); // Get User Input
    int i = str1.find_first_of("`~!@#$%^&*()-_=+|}][{';:/?.>,<\\\""); // Initalize "i" to the first occurence of punctuation in user input sting.
    while (i != string::npos)
    {
    str1.erase(i, 1); // Erase i from the user input string.
    i = str1.find_first_of("`~!@#$%^&*()-_=+|}][{';:/?.>,<\\\""); // Initalize "i" to the first occurence of punctuation in user input sting. (I is erased so it will find next)
    }
    transform( str1.begin(), str1.end(), str1.begin(), toupper ); // transform userinput into upper case.

    return str1;
}

//------------------------------------------------------------------------------------------------------------------------------------
// PHRASE INPUT - start --> Take string of words and split each word off the string and place in a seprate element of a vector.
//------------------------------------------------------------------------------------------------------------------------------------
void parseInput ( const string& input, vector <string> &words, char delim )
{
    words.clear();
    istringstream stream( input, delim );
    while( !stream.eof() ) { // loop while there is data in the stream
    string word; // we'll put each word here temporarily
    // take the first word out of stream until we hit a delimeter,
    // skipping whitespace
    getline( stream, word, delim );
    words.push_back( word ); // store the word
    }
}