Sign in to follow this  

hangman extending word list

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

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

Recommended Posts

Have done the hangman prog from Beg. C++ through games. I thought Id try to develop this game as an excercise. The three angles I wanted to take were: An increased word list (this posts subject) Some basic grahpics (splash screen, the gallows) Some basic sound (beeps for correct/incorrect answer) Ive had all sorts of issues getting GLUT to work, different subject/thread. Have not yet started on sound. Racking my mind on extended word list. I have a 110000ish long word list, so obviously I need to put it outside the main prog file. I want a bit of basic knowledge of organizing files, also to have fuctions I can reuse in other projects, and have the following idea: psuedocode-- include a file as <random word func> <random word func> get word-to-guess from func@<random word func> -- <random word func> assign words to array/list/vector (alv)* random alv function(something that randomly selects an alv member on position, as opposed to shuffling) return alv member -- *this is the bit that I'm most confused with. As the list is so long, it is not feasible to assign each member individually. a)is there a simple way to group or mass assign data? b)should the list be IN the file, or seperate again? The list format is just ascii with return(enter) formating, ie one word per line.

Share this post


Link to post
Share on other sites
Could you not just parse a random line on each game start. That way you don't end up parsing 100k+ words every time, and it's very easy to add new words via your .txt file by just writing a new line.

After assigning your new word to a variable (or however you check it) you can just use that variable in each function that you need it. When it comes time for a new game, just reassign it to another random parse.

Sorry if I misunderstood as I wasn't quit sure of what you were looking for, but I think you are looking at the problem the wrong way.

Share this post


Link to post
Share on other sites
Quote:
Original post by codehappycactus
Some basic grahpics (splash screen, the gallows)
Some basic sound (beeps for correct/incorrect answer)


Honestly, forget these for now. I know every beginning programmer hates to hear it, but... these things aren't essential to the task of *learning to program*, and that's what you need to worry about first. Once you have your head fully wrapped around the idea of using an API and writing (and organizing!) your own code (and treating your own code as if it were someone else's API), then you can just look up the appropriate APIs and their documentation and get to work.

Quote:

Racking my mind on extended word list. I have a 110000ish long word list, so obviously I need to put it outside the main prog file. I want a bit of basic knowledge of organizing files


There are two ideas here.

Source file organization is covered in this article.

But you really, really don't want your word list to be built into the program in a source file. Instead, make a text file, and *read* the file from your program (more later).

Quote:

include a file as <random word func>
<random word func>
get word-to-guess from func@<random word func>

--

<random word func>
assign words to array/list/vector (alv)*
random alv function(something that randomly selects an alv member on position, as opposed to shuffling)
return alv member


An appropriate technical term for your "alv" is sequence, which covers arrays, lists, vectors, strings (you can think of them as a container of characters) and also deques (which you may not have heard of, but should probably look up). In your case you should probably stick with the vector, since (a) you don't want to have to know the size ahead of time (so arrays won't do) and (b) you want random access (so lists are inappropriate).

(An even more general term is container, which also covers associative containers such as std::set and std::map.)

Anyway, you probably want to store the words in the vector *once*, at the beginning of the program, not as part of the "random word function"'s work. The function then picks a random number out of the length of the vector, and returns the corresponding element.

Quote:

*this is the bit that I'm most confused with. As the list is so long, it is not feasible to assign each member individually.
a)is there a simple way to group or mass assign data?


Q. How do you do the same thing multiple times?
A. With a loop.

Each item in your word list is fundamentally the same. So we simply loop the process of "grab an item from the file and put it at the end of the vector" until the file is exhausted.

Quote:
b)should the list be IN the file, or seperate again?


I'm not sure what you mean, but hopefully I've already covered this.

Quote:
The list format is just ascii with return(enter) formating, ie one word per line.


In C++, we use the free function std::getline to read a line from a file.

You should end up with something like this:


std::vector<std::string> container;
std::ifstream file("thefile.txt");
std::string line;
// Read this as "while we can get a line from the file into line"
while (std::getline(file, line)) {
// "push the line onto the back of the container"
container.push_back(line);
}


Yes, it's that easy.

But in order to handle doing this *once*, and then picking a word from the vector multiple times, we're going to want the vector to stick around, so we can't just wrap the reading in a function and be done with it. If you're from a C background, you're probably thinking "just make it global" at this point, but in C++ we have a smarter way of doing things. We make a class that holds the word list as a data member, and set it up in the constructor; then provide a member function that picks a word randomly and hands it back. This way, the loading happens "automatically", and just once: all we do is create one instance of it in the main() function, and pass it around (via function parameters) where needed.


// As an exercise, figure out what headers need to be included.

class Dictionary {
std::vector<std::string> words;

public:
// For reusability, we should specify the file name externally.
Dictionary(const std::string& name) {
std::ifstream file;
// A little magic here that helps us clean up if the file isn't found or
// something else goes wrong.
file.exceptions(std::ios::failbit | std::ios::badbit | std::ioseofbit);
file.open(name.c_str());
std::string line;
while (std::getline(file, line)) {
// "push the line onto the back of the container"
container.push_back(line);
}
}

const std::string& random() {
// I'll let you do some of the work. :)
}

// We don't need a destructor or anything. Really. You usually don't, with
// proper design.
};

// We can use it like:

int main() {
srand(time(0)); // NOT in the dictionary random() function!
// After all, someone, someday, somewhere will want to re-use your class
// and make more than one of them.
try {
Dictionary d("wordlist.txt");
playGame(d); // pass it by reference, please!
} catch (std::ios::failure&) {
// If anything went wrong with the file reading, we'll end up here. Don't
// worry, all the memory allocations etc. have been properly cleaned up.
std::cout << "Couldn't open the word list" << std::endl;
}
}

Share this post


Link to post
Share on other sites

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

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

Create an account or sign in to comment

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

Create an account

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

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this