Jump to content


[Begininger] - Textbase adventure project


24 replies to this topic

#1 Jynks

    Member

  • Members
  • PipPip
  • 85 posts

Posted 08 December 2005 - 06:04 AM

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.codeproje...stringsplit.asp

#2 Wernaeh

    Senior Member

  • Members
  • PipPipPipPip
  • 368 posts

Posted 08 December 2005 - 07:14 AM

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

#3 monjardin

    Senior Member

  • Members
  • PipPipPipPip
  • 1033 posts

Posted 08 December 2005 - 02:06 PM

There was a similar discussion here: Simple question...
monjardin's JwN Meter (1,2,3,4,5,6):
|----|----|----|----|----|----|----|----|----|----|
*

#4 monjardin

    Senior Member

  • Members
  • PipPipPipPip
  • 1033 posts

Posted 08 December 2005 - 02:30 PM

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.
monjardin's JwN Meter (1,2,3,4,5,6):
|----|----|----|----|----|----|----|----|----|----|
*

#5 Mattias Gustavsson

    Senior Member

  • Members
  • PipPipPipPip
  • 413 posts

Posted 08 December 2005 - 02:47 PM

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

#6 monjardin

    Senior Member

  • Members
  • PipPipPipPip
  • 1033 posts

Posted 08 December 2005 - 02:53 PM

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.
monjardin's JwN Meter (1,2,3,4,5,6):
|----|----|----|----|----|----|----|----|----|----|
*

#7 Jynks

    Member

  • Members
  • PipPip
  • 85 posts

Posted 09 December 2005 - 01:13 AM

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.

#8 monjardin

    Senior Member

  • Members
  • PipPipPipPip
  • 1033 posts

Posted 09 December 2005 - 04:43 PM

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 );

}

monjardin's JwN Meter (1,2,3,4,5,6):
|----|----|----|----|----|----|----|----|----|----|
*

#9 Jynks

    Member

  • Members
  • PipPip
  • 85 posts

Posted 09 December 2005 - 08:09 PM

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.

#10 monjardin

    Senior Member

  • Members
  • PipPipPipPip
  • 1033 posts

Posted 09 December 2005 - 08:28 PM

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
monjardin's JwN Meter (1,2,3,4,5,6):
|----|----|----|----|----|----|----|----|----|----|
*

#11 Reedbeta

    DevMaster Staff

  • Administrators
  • 5305 posts
  • LocationBellevue, WA

Posted 09 December 2005 - 09:39 PM

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.
reedbeta.com - developer blog, OpenGL demos, and other projects

#12 Jynks

    Member

  • Members
  • PipPip
  • 85 posts

Posted 09 December 2005 - 10:33 PM

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





#13 NomadRock

    Senior Member

  • Members
  • PipPipPipPip
  • 785 posts

Posted 09 December 2005 - 10:46 PM

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.
Jesse Coyle

#14 Jynks

    Member

  • Members
  • PipPip
  • 85 posts

Posted 09 December 2005 - 11:06 PM

@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.

#15 monjardin

    Senior Member

  • Members
  • PipPipPipPip
  • 1033 posts

Posted 09 December 2005 - 11:56 PM

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.
monjardin's JwN Meter (1,2,3,4,5,6):
|----|----|----|----|----|----|----|----|----|----|
*

#16 Jynks

    Member

  • Members
  • PipPip
  • 85 posts

Posted 10 December 2005 - 06:40 AM

@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


#17 Jynks

    Member

  • Members
  • PipPip
  • 85 posts

Posted 12 December 2005 - 01:53 AM

@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;

	

}


#18 Jynks

    Member

  • Members
  • PipPip
  • 85 posts

Posted 12 December 2005 - 02:38 AM

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 = ' ' )



#19 monjardin

    Senior Member

  • Members
  • PipPipPipPip
  • 1033 posts

Posted 12 December 2005 - 03:52 AM

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

#20 Jynks

    Member

  • Members
  • PipPip
  • 85 posts

Posted 12 December 2005 - 11:10 PM

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!!





1 user(s) are reading this topic

0 members, 1 guests, 0 anonymous users