-2
#include <iostream>
#include <string>//needed to make string array
#include <fstream>//Needed for redaing in from external file
#include <cstdlib>//needed for rand() function (for random word)
#include <ctime>//needed for time() funtion to seed rand()
using namespace std;
/* Sage Balcita
 April 25,2020
 This program will take read in a random word from an external file and use it for a game of hang man */


//class
class Hangman{
public:
    Hangman();//default constuctor
    void setWord(string);
    string getWord();

private:
    string secretWord;



};

void Hangman::setWord(string Word)
{
    ifstream inFile("randwords.txt");
          if(inFile.is_open())
          {
              string wordlist[10];
              for(int i = 0; i < 10; ++i)
              {
                  inFile >> wordlist[i];


              }
              srand(time(0));

                            string secretword = wordlist[rand() % 10];
                            cout<< secretword << endl;
              inFile.close();

          }
}




//void wordPick();
int main()
{



    //wordPick();

    return 0;
}


/*void wordPick()//reads in external file and puts it in an array for a library of words to randomly choose
{


    ifstream inFile("randwords.txt");
       if(inFile.is_open())
       {
           string wordlist[10];
           for(int i = 0; i < 10; ++i)
           {
               inFile >> wordlist[i];


           }
           srand(time(0));

                         string secretword = wordlist[rand() % 10];
                         cout<< secretword << endl;
           inFile.close();

       }

}
*/

so what I'm trying to accomplish is to make a hangman game that uses classes to operate. my problem is that I can't for the life of me understand how to get the function I made to read a random word from an external file to work inside the class. I make a separate function specifically for this that worked by itself but I can't get a class to work for the same thing.

  • 1
    _I can't get a class to work_ In what way? Does it not compile? Does it compile but not run right? [Edit] the question to include those details. – 1201ProgramAlarm May 05 '20 at 00:50
  • Helpful reading: [srand() — why call it only once?](https://stackoverflow.com/questions/7343833/srand-why-call-it-only-once) – user4581301 May 05 '20 at 01:00

1 Answers1

0

Your issue is that the secretword variable in your member function isn't the same as the secretWord member variable, meaning you're not updating the one in your instance. Had you not declared the local variable, your code wouldn't have compiled since case matters in C++.

However, there are some other quality issues in your code. First of all, you want to use the newer random number facilities available in <random> since they're higher quality than srand and rand.

Lastly, this is a perfect use case for reservoir sampling. The idea behind reservoir sampling is that you have a set of potential data (e.g., your word list), and each item has a capacity/set_size chance of being included in the result (this is just a special case where capacity is 1). It also means you don't need to store every possible word in your program, unless you want to do multiple iterations of the game and don't want to read the word list again (probably a good idea).

A simple reservoir sampling implementation for your game looks like this:

std::string get_word(std::default_random_engine &engine) {
    std::ifstream input_file{"words.txt"};
    auto count = 0;
    std::string read_word;
    std::string result;
    while(input_file >> read_word) {
        std::uniform_int_distribution<int> dist{0, count};
        auto const random_index = dist(engine);
        if(random_index == count) {
            result = read_word;
        }
        ++count;
    }
    return result;
}

Each iteration of the loop, a single word is read and we generate a random number between 0 and count. If the random number is equal to our current count, then we replace the currently selected word, otherwise we do nothing.

On the first iteration, the random number will always be 0, so we select that. On the second iteration, we have a 1/2 chance of replacing our selected word. On the third, 1/3, and so on and so on. The odds of replacing our word decrease each iteration, but the odds of any given word being selected works out to 1/N.

Stephen Newell
  • 7,330
  • 1
  • 24
  • 28