I am basically creating a Hangman game using object oriented programming and some parts of it was confusing with protected class and inheritance. My Words class is perfect and has been tested and works just fine. The class that needs to be worked on is Hangman and HangmanConsole. I am wondering how to get them to store and fill in characters. The goal is to basically create a simple program where the code simply generates a random word from the given text file and the program will have hyphens to give you the length of the word. Then the user will guess the word until all guesses are gone.
#include <iostream>
#include <fstream>
#include <ctime>
#include <string>
class Words
{
private:
int minlen{0};
int maxlen{0};
std::string file_name;
std::string* choices = nullptr;
int count{0};
public:
Words (int min, int max, std::string fName)
{
minlen = min;
maxlen = max;
file_name = fName;
this->load_words();
srand( time(NULL) );
}
~Words()
{
delete [] choices;
}
int getCount()
{
return count;
}
void display_list()
{
for(int i = 0; i < count; i++)
{
std::cout << choices[i] << '\n';
}
}
void load_words()
{
std::ifstream fwords(file_name);
if(!fwords)
{
std::cout << "Cannot open file\n";
return;
}
// This counts the words (1st file read)
std::string temp;
count = 0;
while(fwords >> temp)
{
// Filter words
if(temp.length() == minlen or temp.length()== maxlen)
count++;
}
// Setting up the array
choices = new std::string[count];
fwords.close();
// Loading the array (2nd File read)
fwords.open(file_name);
int index{0};
while(fwords >> temp)
{
if(temp.length() == minlen or temp.length() == maxlen)
{
choices[index] = temp;
index++;
}
}
fwords.close();
}
std::string pick_word()
{
if (count == 0)
{
return"Zero words available to select from";
}
return choices[rand() % count];
}
};
class Hangman
{
private:
char word[40];
// char progress[40]; // Progress will be the same length as char_word "----"
int word_length;
// void clear_progress(int length); // This will set progress to contain
protected:
int matches; // Characters that match
char last_guess; // Final guess
string chars_guessed; //The characters guessed
int wrong guesses; // Number of wrong guesses
int user_guess; // Character that the user will use to guess
int remaining; // Number of guesses remaining
constint total_guesses = 6; // Total number of tries
bool check(char user_guess); // Function designed to accept a single character.
class Hangman
{
private:
char word[40];
// char progress[40]; // Progress will be the same length as char_word "----"
int word_length;
// void clear_progress(int length); // This will set progress to contain
protected:
int matches; // Characters that match
char last_guess; // Final guess
string chars_guessed; //The characters guessed
int wrong guesses; // Number of wrong guesses
int user_guess; // Character that the user will use to guess
int remaining; // Number of guesses remaining
constint total_guesses = 6; // Total number of tries
bool check(char user_guess); // Function designed to accept a single character.
public:
Hangman(char w, char p, int wlen)
{
word = w; // This will be used to store the generated word
progress = p;
word_length = wlen;
}
Hangman(int m, char lg, string chg, int wg, int ug, int r)
{
matches = m;
last_guess = lg;
chars_guessed = chg;
wrong_guesses = wg;
user_guess = ug;
remaining = r;
}
char * get_word()
{
return word;
}
};
class HangmanConsole : public Hangman
{
};
int main()
{
std::string source_file;
source_file = "enable1.txt"; // This text file contains the complete word list for Hangman
// string unknown(word.length(), '-'); Maybe use this to initialize with '-' character.
rand(time(NULL)); // needs <ctime> included
Words words(7,10); // words between 7 and 10 chars long
HangmanConsole game(words.pick_word());
cout << "HANGMAN" << endl << "-------" << endl << endl;
cout << "Your word is: " << game.get_progress() << endl;
while (!game.is_word_complete() && game.get_remaining() > 0)
{
cout << endl;
cout << "Enter your guess: ";
cin >> game; // calls overloaded >> operator
system("clear"); // NON-PORTABLE, ONLY WORKS ON LINUX
game.show_info();
}
looks to me like you need a string that is assigned via pick-words. That belongs in hangman, and console can see it. An easy solution is to have the real word and a word of the same length that is all underscores or whatever (* will do, etc). As they get letters right, you fill them in and always print the one with the marker characters. Once they get all the letters the two are the same.
there is a universal clear the console string you can look up but if you are not moving it off your OS its not important.
line 68 is illegal in standard c++, array size must be a compile time constant.
<random> is better but rand() will do for now since you already used it. Consider it next time, its a little more setup but much better results and flexibility.
My Words class is perfect and has been tested and works just fine
??
Why use dynamic memory - and not a std::vector? Then you'd just have to read the file once rather than twice.
Use initialisation rather than assignment for member variables in constructors. Also pass string by const ref rather than by value to avoid an unnecessary copy:
1 2 3 4 5
Words (int min, int max, const std::string& fName) : minlen(min), maxlen(max), file_name(fName)
{
load_words();
srand( static_vast<unsignedchar>(time(nullptr)));
}
Member functions that don't change member variables should be marked as const
My Words class is perfect and has been tested and works just fine
Also loadWords will include words that are exactly minlen or maxlen characters, but nothing in between. In other words, if minlen is 3 and maxlen is 5, it will include "cat" and "chair" but not "frog" or "door"
Words::Words() should not call srand(). Call srand() exactly once, at the beginning of main().