patterncppMinor
Hangman game with hard-coded word or phrase
Viewed 0 times
withhardhangmangamewordphrasecoded
Problem
I feel that this implementation can still be simplified. I've tried to keep variable scopes low and have used as much of the standard library as I could.
It currently works with a hard-coded word or phrase, but I eventually plan on having it work with random words or phrases from a file.
My main concern is in regards to my functions. Am I using too few or too many of them? I still feel that
Note: I have not tagged this as c++11 because there's no utilization of it here, but I am open to any recommendations from C++11.
It currently works with a hard-coded word or phrase, but I eventually plan on having it work with random words or phrases from a file.
My main concern is in regards to my functions. Am I using too few or too many of them? I still feel that
main() is doing a little too much.Note: I have not tagged this as c++11 because there's no utilization of it here, but I am open to any recommendations from C++11.
#include
#include
bool isCorrectGuess(const char guess, std::string const& word)
{
return (word.find(guess) != std::string::npos);
}
std::string updateWrongGuesses(const char guess, std::string const& word, std::string wrongGuesses)
{
return wrongGuesses += guess;
}
std::string updateCorrectGuesses(const char guess, std::string const& word, std::string correctGuesses)
{
for (std::string::size_type i = 0; i != word.size(); ++i)
{
if (word[i] == guess)
{
correctGuesses[i] = guess;
}
}
return correctGuesses;
}
void displayStatus(const unsigned int triesLeft, std::string const& guessedWord, std::string const& wrongGuesses)
{
std::cout 0 && guessedWord != word)
{
std::cout > guess;
guess = tolower(guess);
attemptedGuesses += guess;
if (isCorrectGuess(guess, word))
{
guessedWord = updateCorrectGuesses(guess, word, guessedWord);
}
else
{
wrongGuesses = updateWrongGuesses(guess, word, wrongGuesses);
triesLeft--;
}
displayStatus(triesLeft, guessedWord, wrongGuesses);
}
if (guessedWord == word)
{
std::cout << "\n\nYou've guessed the word/phrase!\n\n";
}
else
{
std::cout << "\n\nYou've been hanged...\n\n";
std::cout << "The word/phrase is: " << word;
}
}Solution
The first thing that nearly jumps out at me is this:
It's not at all clear why you pass
...seems simpler and more readable than:
I think I probably would use a class (or possibly two) in writing this code. My first attempt would be something on this general order:
As far as how much of your code is in
As a natural consequence of being bigger, a bigger program will typically have more layers between
std::string updateWrongGuesses(const char guess, std::string const& word, std::string wrongGuesses)
{
return wrongGuesses += guess;
}It's not at all clear why you pass
word to this at all, since it doesn't use or modify it. Worse, it looks like it's actually more work to call the function than to re-implement what (little) the function does. At least to me:wrongGuesses += guess;...seems simpler and more readable than:
wrongGuesses = updateWrongGuesses(guess, word, wrongGuesses);I think I probably would use a class (or possibly two) in writing this code. My first attempt would be something on this general order:
#include
#include
class hangman{
static const int max_wrong = 8;
std::string word;
std::string display;
std::string wrong;
public:
hangman(std::string const &word) : word(word) {
for (char ch : word)
display += isspace(ch) ? ' ' : '*';
}
void enter_guess(char ch) {
bool correct = false;
for (std::string::size_type i = 0; i != word.size(); ++i)
if (word[i] == ch) {
display[i] = ch;
correct = true;
}
if (!correct)
wrong += ch;
}
bool is_over() {
return wrong.size() == max_wrong || display == word;
}
std::string final() {
return "The word was: " + word + (display == word ? "\nYou win!" : "\nYou lose");
}
std::string status() {
return "\nwrong guesses: " + wrong + "\nCurrent word: " + display;
}
};
char get_guess() {
std::cout > ch;
return ch;
}
int main()
{
hangman game("rabbit rabbit");
do {
std::cout << game.status() << "\n";
game.enter_guess(get_guess());
} while (!game.is_over());
std::cout << game.final();
}As far as how much of your code is in
main: I try not to treat main any differently from any other function. IMO, you shouldn't strive for main to be as small, or large, or anything else in particular as possible. Rather, main should be a function just about like any other. It should have accomplish something useful. Like any other function, it should have a clearly defined level of abstraction at which it operates, and (for the most part) it should try to stick to it.As a natural consequence of being bigger, a bigger program will typically have more layers between
main and the lowest levels of manipulation, so in a large program it'll typically have little code beyond creating objects and/or calling functions. I wouldn't consider that a particularly worthy goal in itself though. If it fits well with the size and type of program you're writing great--but there's not necessarily a good reason to force it if it doesn't happen to fit or work out well that way.Code Snippets
std::string updateWrongGuesses(const char guess, std::string const& word, std::string wrongGuesses)
{
return wrongGuesses += guess;
}wrongGuesses += guess;wrongGuesses = updateWrongGuesses(guess, word, wrongGuesses);#include <iostream>
#include <string>
class hangman{
static const int max_wrong = 8;
std::string word;
std::string display;
std::string wrong;
public:
hangman(std::string const &word) : word(word) {
for (char ch : word)
display += isspace(ch) ? ' ' : '*';
}
void enter_guess(char ch) {
bool correct = false;
for (std::string::size_type i = 0; i != word.size(); ++i)
if (word[i] == ch) {
display[i] = ch;
correct = true;
}
if (!correct)
wrong += ch;
}
bool is_over() {
return wrong.size() == max_wrong || display == word;
}
std::string final() {
return "The word was: " + word + (display == word ? "\nYou win!" : "\nYou lose");
}
std::string status() {
return "\nwrong guesses: " + wrong + "\nCurrent word: " + display;
}
};
char get_guess() {
std::cout << "Please enter your guess: ";
char ch;
std::cin >> ch;
return ch;
}
int main()
{
hangman game("rabbit rabbit");
do {
std::cout << game.status() << "\n";
game.enter_guess(get_guess());
} while (!game.is_over());
std::cout << game.final();
}Context
StackExchange Code Review Q#51461, answer score: 6
Revisions (0)
No revisions yet.