Hi, I need some help with a C++ assignment. I'm supposed to write a Hangman program that will:

The user should be able to choose between playing against the computer, or against another human. The only difference will be how the word to be guessed is selected: If playing against the computer, the computer will choose from a built-in list of words, picking one of them at random; If playing against another human, the human hangman will type in a word (a string)(In C++, a string is MUCH preferable to the old-fashioned c-strings.)

The user (either the guesser or the hangman) should be asked for the number of incorrect guesses to allow the guesser... within the range 4 to 10 inclusive.

Before each guess entered by the user, the program should:
Display the letters already chosen
Display the number of guesses left
Display the portion of the word already guessed, inserting an * (asterisk) for each letter not yet guessed.

The user enters a character; the program will then indicate if an incorrect character was chosen:

A letter already chosen

Any non-alphabetic character (such as ?, /, 4, $, etc.) (Hint: see documentation on ctypes.h - especially isalpha())

If the user has correctly guessed a letter that appears in the word, the displayed word (with asterisks) is updated, replacing the proper asterisks with the correctly guessed letter. For example, if the word were "EAGLE" and the user guessed "E", both the first and last letters would be filled in : E***E.

If the user has correctly guessed the entire word without using all of the allowed incorrect guesses, a congratulatory message (and, optionally, bells and whistles!) Should be displayed. If, on the other hand, the user runs out of incorrect guesses, an appropriate message of condolence should be displayed.

Upon termination of a game the program should prompt the player if another game is wanted - an 'n' or 'N' will terminate the program, otherwise it will loop back, select another word, and do it all again!!

here's my code:

// PROGRAM 5
// HANGMAN GAME

#include <iostream>
#include <fstream>
#include <string>
#include <ctime>
#include <cstdlib>
using namespace std;

int	instructions();
void	manual();
void	file( char* );
int	letterFill( char, char*, char* );
void	Unknown( char*, char* );
const int MAX_LENGTH=10;

void main()																					
{
   	bool done = false;
	char word[MAX_LENGTH];
	char unknown[MAX_LENGTH];
	char letter;
	char name[MAX_LENGTH];
	int wrong_guesses=0;
	int MAX_TRIES;
	

	// SWITCH: MANUAL vs. SOURCE FILE
    do
    {
        switch(instructions())
        {
            case 1:
            {
                manual();
                break;
            }
            case 2:
            {
                file(word);
                break;
            }
            default:
            {
                done = true;
                break;
            }
        }
    }   
	while(!done);
	
	cout << "INPUT NUMBER OF GUESSES THE PLAYER IS ALLOWED: " << endl;
	cin >> MAX_TRIES;

	Unknown(word, unknown);

	cout << endl << endl << "HANGMAN";
	cout << endl << endl << "Each letter is represented by a star." << endl;
	cout << "You have " << MAX_TRIES << " tries to try and guess the word.";
	cout << "ENTER GUESS WHEN READY";
	
	while (letter !='N' && letter !='n')
	{
  // LOOP UNTIL GUESSES USED UP
	while (wrong_guesses < MAX_TRIES) 
    {
      
      // DISPLAY UNKNOWN WORD
      cout << unknown << endl;
      cout << "Guess a letter: " << flush;
      cin >> letter;
      
      // REPLACE * W/ LETTER IF CORRECT,
      // INCREMENT WRONG GUESSES IF INCORRECT.
      if (letterFill(letter, word, unknown)==0)
        {
          cout << endl << "Uh Oh! That's ONE Guess down!" << endl;
              wrong_guesses++;
        } 
	  else 
		{
		 cout << endl << "YAY! That letter is in the word" << endl;
		}         
      
      // GUESSES LEFT  
	  cout << "Guesses Left: " << MAX_TRIES-wrong_guesses << endl;
          
      // GUESSED WORD?
      if (strcmp(word, unknown) == 0) 
        {
          cout << word << endl;
          cout << "Yeah!  You got it!" << endl;
          exit(0);
        }

	cout << "Ouch, you've been hanged." << endl;
	cout << "The word was : " << word << endl;
	}
	}
system (“pause”);
}

// PROGRAM MENU
int instructions()	
{
    int select = 0;
	cout << endl << "HANGMAN" << endl << endl;
	cout << "     PROGRAM MENU" << endl;
	cout << "  Select option 1  or  2" << endl << endl;
    	cout << "      1. INPUT WORD MANUALLY" << endl;
    	cout << "      2. PLAY AGAINST THE COMPUTER" << endl;
	cout << "      3. EXIT PROGRAM BY INPUTING:  N  or  n" << endl << endl;
    	cin >> select;

    return select;
}

//WORD FROM USER INPUT
void manual()
{
    string word;
    
    cout << endl << "INPUT WORD: " << endl;
    cin >> word;
}

void file(char *roc)
{
	ifstream fin("G:/wordsource.txt");
	int x;
	int count=1;
	int word;
	int i = 0;
  
  // INITIALIZE RANDOM GENERATOR
  srand(time(0));

  // RANDOM NUMBER GENERATOR
  word = rand() % 20;

  // MOVE TO CORRECT PLACE IN FILE
  while (count < word) 
    {
      fin >> x;
      if (x==0) 
        {
          count++;
        }
    }
  
  // READ IN WORD
  do 
  {
    fin >> x;
    roc[i++] = char (x);
  } 
  while (x);
}

int letterFill( char guess, char *secretword, char *guessword )
{
  int i;
  int matches=0;
  
  for( i=0; i<MAX_LENGTH; i++ ) 
    {
      // END OF WORD
      if( secretword[i] == 0 ) 
        {
          break;
        }
      
      // GUESSED SAME LETTER TWICE
      if( guess==guessword[i] ) 
        {
          return 0;
        }

      // MATCH GUESS TO SECRET WORD
      if( guess==secretword[i] ) 
        {
          guessword[i] = guess;
          matches++;
        }
    }
  return matches;
}

// INITIALIZE UNKNOWN WORD

void Unknown( char *word, char *unknown)
{
  int i;
  int length=strlen(word);
  
  for( i=0; i<length; i++ )
    {
      unknown[i]='*';
    }
  
  unknown[i]=0;
}

It compiles, but then does some really odd things, so hopefully you can all help me edit it?

Assignment's due tomorrow and this program is driving me nuts. Any useful websites would be helpful as well.

Thanks!

What type of "really odd things"?

The program compiles and the menu shows up like I want it to. However, when I select option 1 (manual) the menu shows up again instead of continuing on to ask for the maximum number of attempts the user is allowed and so forth into the game.

When I try select option 2 (pull a word randomly from a .txt file) nothing happens.

When I select option 3 (which isn't even supposed to be an option) the game continues, by passing everything else (as far I can tell).

Pulling out code:

instructions:

// PROGRAM MENU
int instructions()	
{
    int select = 0;
	cout << endl << "HANGMAN" << endl << endl;
	cout << "     PROGRAM MENU" << endl;
	cout << "  Select option 1  or  2" << endl << endl;
    	cout << "      1. INPUT WORD MANUALLY" << endl;
    	cout << "      2. PLAY AGAINST THE COMPUTER" << endl;
	cout << "      3. EXIT PROGRAM BY INPUTING:  N  or  n" << endl << endl;
    	cin >> select;

    return select;
}

I used a switch function to show the selction:

do
    {
        switch(instructions())
        {
            case 1:
            {
                manual();
                break;
            }
            case 2:
            {
                file(word);
                break;
            }
            default:
            {
                done = true;
                break;
            }
        }
    }   
	while(!done);

Pulling a random word from a .txt file:

void file(char *roc)
{
	ifstream fin("G:/wordsource.txt");
	int x;
	int count=1;
	int word;
	int i = 0;
  
  // INITIALIZE RANDOM GENERATOR
  srand(time(0));

  // RANDOM NUMBER GENERATOR
  word = rand() % 20;

  // MOVE TO CORRECT PLACE IN FILE
  while (count < word) 
    {
      fin >> x;
      if (x==0) 
        {
          count++;
        }
    }

Word Manually input:

void manual()
{
    string word;
    
    cout << endl << "INPUT WORD: " << endl;
    cin >> word;
}

I see a couple of things right off, but I haven't had time to get through the whole program.

1) You're not exiting your while loop until they select Done. Your condition is while(!done).

2) Your manual program should return the string that is input, shouldn't it?

I see a couple of things right off, but I haven't had time to get through the whole program.

1) You're not exiting your while loop until they select Done. Your condition is while(!done).

2) Your manual program should return the string that is input, shouldn't it?

So by making the default done = true I'm making it so that option 3 exits the loop? How do I exit the while loop? I've been trying to figure it out.

I did try returning the string 'word' into manual() once, but I got an error message saying that 'the function does not take 1 arguements'.

You could change your while condition to while(done) instead of while(!done)... however you then have the problem of when the user gets to the end of the program, it doesn't re-execute the instructions() function.

Why don't you try putting a while loop around the entire program, take out the option to end the program from the instructions() function, and add the option right before the loop ends. Something like this:

Mostly pseudo code:

while(not done)
{
switch instructions()
    case 1:  manual() ;
break ;
    case 2:  file() ;
break ;
.
.
.
hangman game
.
.
.
cout << "Try again? (y/n):  " << flush ;
cin >> ans ;
if (ans == 'y' || ans == 'Y')
   done= true ;
else
   done = false ;
}//end while
cout << "-- Program Complete  --" << endl ;

You could change your while condition to while(done) instead of while(!done)... however you then have the problem of when the user gets to the end of the program, it doesn't re-execute the instructions() function.

Why don't you try putting a while loop around the entire program, take out the option to end the program from the instructions() function, and add the option right before the loop ends.

I added the while loop around the whole function instead of using do while, and it works now! Thanks! If I want to make it so the program exits on 'n' or 'N', would I change while(!done) to while (letter !=n && letter !=N) ? (In which 'letter' is the player's submitted guess).

Another thing showed up, when I attempt to guess the letter I get a bunch of stars and I keep getting the error message, even when I know that I 'guessed' a correct letter.

Is there something wrong with the if statement?

// REPLACE * W/ LETTER IF CORRECT,
      // INCREMENT WRONG GUESSES IF INCORRECT.
      if (letterFill(letter, word, unknown)==0)
        {
          cout << endl << "Uh Oh! That's ONE Guess down!" << endl;
              wrong_guesses++;
        } 
	  else 
		{
		 cout << endl << "YAY! That letter is in the word" << endl;
		}

No problem :)
1) Make sure the while loop is around the entire program... ending right before return 0 ; This way you can do "Try again? (y/n): " and you can change the if statement to if (letter == 'n' || letter =='N') THEN done = true ;

So your while loop should still be while(!done). Does that make sense?

I'm doing hw of my own right now, so I'm still looking at the rest of your program as I get time. I'll post back in a few minutes. Until then, do some desk checking (essential to every program you ever write).. get out a piece of paper and write down step by step what happens.

Newest code:

#include <iostream>
#include <fstream>
#include <string>
#include <ctime>
#include <cstdlib>
using namespace std;

int	instructions();
void	manual();
void	file( char* );
int	letterFill( char, char*, char* );
void	Unknown( char*, char* );
const int MAX_LENGTH=10;

void main()																					
{
   	bool done = false;
	char word[MAX_LENGTH];
	char unknown[MAX_LENGTH];
	char letter;
	char name[MAX_LENGTH];
	int wrong_guesses=0;
	int MAX_TRIES;
	char ans;
	

	// SWITCH: MANUAL vs. SOURCE FILE
    while (!done)
    {
        switch(instructions())
        {
            case 1:
            {
                manual();
                break;
            }
            case 2:
            {
                file(word);
                break;
            }
		}
	
	cout << "INPUT NUMBER OF GUESSES THE PLAYER IS ALLOWED: " << endl;
	cin >> MAX_TRIES;

	Unknown(word, unknown);

	cout << endl << endl << "HANGMAN";
	cout << endl << endl << "Each letter is represented by a star." << endl;
	cout << "You have " << MAX_TRIES << " tries to try and guess the word.";
	cout << "ENTER GUESS WHEN READY: "
	cin >> letter;
	
	while (letter !='N' && letter !='n')
	{
  // LOOP UNTIL GUESSES USED UP
	while (wrong_guesses < MAX_TRIES) 
    {
      
      // DISPLAY UNKNOWN WORD
      cout << unknown << endl;
      cout << "Guess a letter: " << flush;
      cin >> letter;
      
      // REPLACE * W/ LETTER IF CORRECT,
      // INCREMENT WRONG GUESSES IF INCORRECT.
      if (letterFill(letter, word, unknown)==0)
        {
          cout << endl << "Uh Oh! That's ONE Guess down!" << endl;
              wrong_guesses++;
        } 
	  else 
		{
		 cout << endl << "YAY! That letter is in the word" << endl;
		}         
      
      // GUESSES LEFT  
	  cout << "Guesses Left: " << MAX_TRIES-wrong_guesses << endl;
          
      // GUESSED WORD?
      if (strcmp(word, unknown) == 0) 
        {
          cout << word << endl;
          cout << "Yeah!  You got it!" << endl;
          exit(0);
        }

	cout << "Ouch, you've been hanged." << endl;
	cout << "The word was : " << word << endl;
	}
	}
	
	cout << "Try again? (y/n):  " << flush;
	cin >> ans ;
	if (ans == 'y' || ans == 'Y')   
		done= true ;
	else   
		done = false ;
}//end whilecout << "-- Program Complete  --" << endl ;

system ("pause");
}

// PROGRAM MENU
int instructions()	
{
    int select = 0;
	cout << endl << "HANGMAN" << endl << endl;
	cout << "     PROGRAM MENU" << endl;
	cout << "  Select option 1  or  2" << endl << endl;
    	cout << "      1. INPUT WORD MANUALLY" << endl;
    	cout << "      2. PLAY AGAINST THE COMPUTER" << endl;
	cout << "      3. EXIT PROGRAM BY INPUTING:  N  or  n" << endl << endl;
    	cin >> select;

    return select;
}

//WORD FROM USER INPUT
void manual()
{
    string word;
    
    cout << endl << "INPUT WORD: " << endl;
    cin >> word;
}

void file(char *roc)
{
	ifstream fin("G:/wordsource.txt");
	int x;
	int count=1;
	int word;
	int i = 0;
  
  // INITIALIZE RANDOM GENERATOR
  srand(time(0));

  // RANDOM NUMBER GENERATOR
  word = rand() % 20;

  // MOVE TO CORRECT PLACE IN FILE
  while (count < word) 
    {
      fin >> x;
      if (x==0) 
        {
          count++;
        }
    }
  
  // READ IN WORD
  do 
  {
    fin >> x;
    roc[i++] = char (x);
  } 
  while (x);
}

int letterFill( char guess, char *secretword, char *guessword )
{
  int i;
  int matches=0;
  
  for( i=0; i<MAX_LENGTH; i++ ) 
    {
      // END OF WORD
      if( secretword[i] == 0 ) 
        {
          break;
        }
      
      // GUESSED SAME LETTER TWICE
      if( guess==guessword[i] ) 
        {
          return 0;
        }

      // MATCH GUESS TO SECRET WORD
      if( guess==secretword[i] ) 
        {
          guessword[i] = guess;
          matches++;
        }
    }
  return matches;
}

// INITIALIZE UNKNOWN WORD

void Unknown( char *word, char *unknown)
{
  int i;
  int length=strlen(word);
  
  for( i=0; i<length; i++ )
    {
      unknown[i]='*';
    }
  
  unknown[i]=0;
}

Your manual and file functions have to return because when you are calling function Unknown, both of your arrays known and unknown have garbage value in them.

This question has already been answered. Start a new discussion instead.