C++ Hangman Game

Pages: 12
The assignment is a simple C++ Hangman game:
You'll ask the user to enter a secret word or phrase, a 100 char array
Any letter that gets entered will be replaced with a "*"
Spaces will be represented with a "_"
Any other character will be left alone.


For every correct guess, the letter in the proper place will be revealed.
For every wrong guess, a body part of the hangman will be printed out:

head
head - body
head - body - left arm
head - body - left arm - right arm
head - body - left arm - right arm - left leg
head - body - left arm - right arm - left leg - right leg - HANGMAN!

You need to keep track of previously guessed letters, so the user will not guess the same letter twice.
You will have a function that takes a char array and returns a char array of *'s of the same length as the original char array
You will have a function that takes a char and a char array, and checks to see if that char is in the char array
You will probably also want a function that will display that reveals the hidden letter with a correct guess
You may also want a function that keeps track of guessed letters
and also a function that determines the state of the hangman, if the user fails to guess the word before "HANGMAN!", display the word



I have tried everything but I cant make it work!! any advice or help would be awesome


...You tried everything? Can we see what you tried? How do you expect us to help you if all you told us is the assignment. We're not going to write it for you.
.
Last edited on
Please remember to use the code tags (the <> button) for all future code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
int main()
{
    int lifes=0;
    char letter;
    int yes;
    char solution[100]={0};
    char newW[100]={0};

    cout<<"Write a word: ";
    cin>>solution;

    while ( lifes <=6 && strcmp(newW, solution) != 0)
    {
        yes=0;
        cout<<endl<<"Guess a letter: ";
        cin>>letter;
        for(int n=0; n<100; n++) 
        {
            if(solution[n] == letter) 
            {
                newW[n]=solution[n];
                yes=1; 
            } 
            if (yes<1)
            {
                lifes=lifes+1;
                cout<<"Sorry please try again."<<endl; 
                cout << "you lost this many lifes: "<<lifes;
            }
       }
       if (lifes=1) // No closing } for this if statement untill much later down, add that and remove the one after the return
       { 
              cout<<endl<<"Head"; 
              if (lifes=2) 
              {
                     cout<<endl<<"Head-Body";
              }
              if (lifes=3) 
              {
                     cout<<endl<<"Head-Body-RightArm"; 
              }
              if (lifes=4)
              {
                     cout<<endl<<"Head-Body-RightArm-LeftArm"; 
              }
              if (lifes=5) 
              {
                     cout<<endl<<"Head-Body-RightArm-LeftArm-RightLeg"; 
              }
              if (lifes=6) 
              {
                     cout<<endl<<"Head-Body-RightArm-LeftArm-RightLeg-LeftLeg"; 
              }
       }

       getch();
       return 0; // return inside the while loop, will be fixed if you remove the last }
   }

} 


if (lifes=6) This does not check if lifes is equal to six, it assigns life six.
.
Last edited on
You missed the code tag again.
1
2
3
4
5
6
7
8
9
10
11
12
for(int n=0; n<100; n++) 
{
    if(solution[n] == letter) {
        newW[n]=solution[n];
        yes=yes+1; 
    } 
    if (yes<=0){
        lifes=lifes+1;
        cout<<"Sorry please try again."<<endl; 
        cout << "you lost this many lifes: "<<lifes;
    }
}


I'm assuming what you want to do here is check if the letter is in the solution (apart from recommending the use of strings) I recommend that instead of using an int for the variable yes use a bool and move the second if statement ( if(!yes) ) outside of the for loop.
Last edited on
@Adrio And also remember to properly format the code as well (i.e. with indentation). I realize that copying and pasting from an IDE will probably mess it up, but it's well worth the extra effort. I can tell right away in the code that Warnis posted that if (yes<=0) was within the loop, whereas looking at your post, I'd have a heck of a time.
Sorry about the code tagging! I understand it is annoying without the proper formatting I hope this is better! and thanks for the help! this is what I got so far:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
#include<iostream>
#include<conio.h>
using namespace std;

int main()
{
   
   int newlife=0;
   char letter;
   bool yes;
   char solution[100]={0};
   char newW[100]={0};

   cout<<"Write a word: ";
   cin>>solution;

   while ( newlife <7 && strcmp(newW, solution) != 0)
 
   {
	yes=0;
	cout<<endl<<"Guess a letter: ";
	cin>>letter;
   		
	for(int n=0; n<100, n++;) {
	
	if(solution[n] == letter) { //This section is not working, the code will not identify a successfull guess. 
	newW[n]=solution[n]; //You mentioned the use of strings, is this way of doing it wrong?
	yes=1;
	cout<<"nice! now continue"<<newW;} 
	}
	if (yes<=0){ //This part seems to be working now...  
	cout<<"Sorry please try again."<<endl; 
	newlife=(newlife+1);
	cout << "you lost this many lifes: "<<newlife;
	}

   if (newlife==1) {
	   cout<<endl<<"Head";}
    if (newlife==2) {
   cout<<endl<<"Head-Body"; }
	 if (newlife==3) {
   cout<<endl<<"Head-Body-RightArm"; }
	  if (newlife==4) {
   cout<<endl<<"Head-Body-RightArm-LeftArm"; }
	   if (newlife==5) {
   cout<<endl<<"Head-Body-RightArm-LeftArm-RightLeg"; }
	   if (newlife==6) {
		   cout<<endl<<"Head-Body-RightArm-LeftArm-RightLeg-LeftLeg"; }}

   getch();
   return 0;
}



There's a typo in your for loop:

for(int n=0; n<100, n++;)

It should be:

for(int n=0; n<100; n++)

newW[n]=solution[n]; //You mentioned the use of strings, is this way of doing it wrong?

It's not that it's wrong, it's just that this solution doesn't scale. What if the user wants to enter a word (or phrase) that's longer than 100 characters? You'd need to do your own memory management if you were to use char arrays. std::strings on the other hand, deal with that for you.

Also, if you were to enter a phrase instead of a word, using cin>> will break it (it doesn't handle spaces). std::getline would be better if you decide to go that route.
Hey! Thanks for the help the game is working perfectly... this seemingly impossible task is beginning to look good! anyways I am nonetheless stuck... I still cannot figure out how to make the game: keep track of previously guessed letters, so the user will not guess the same letter twice.
Have a function that takes a char array and returns a char array of *'s of the same length as the original char array.
Have another function that takes a char and a char array, and checks to see if that char is in the char array....
Here is what I got so far... any further advice will be awesome!!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
#include<iostream>
#include<conio.h>
using namespace std;

int main()
{
   
   int newlife=0;
   char letter;
   bool yes;
   char solution[100]={0};
   char newW[100]={0};

   cout<<"Write a word: ";

   cin>>solution;
   cout<<"you have six lives to guess the word";

   while ( newlife <6 && strcmp(newW, solution) != 0)
 
   {
	yes=0;
	cout<<endl<<"Guess a letter: ";
	cin>>letter;
   		
	for(int n=0; n<100; n++) {
	
	if(solution[n] == letter) { //This section is not working, the code will not identify a successfull guess. 
	newW[n]=solution[n]; //You mentioned the use of strings, is this way of doing it wrong?
	yes=1;
	cout<<"nice!"<<"This is what you got so far:" <<endl<<newW;} 
	}
	if (yes<=0){ //This part seems to be working now...  
	cout<<"Sorry please try again."<<endl; 
	newlife=(newlife+1);
	cout << "you lost this many lifes: "<<newlife<<endl;
	cout<<"This is what you got so far: "<<endl<<newW;
	}

   if (newlife==1) {
	   cout<<endl<<"Head";}
    if (newlife==2) {
   cout<<endl<<"Head-Body"; }
	 if (newlife==3) {
   cout<<endl<<"Head-Body-RightArm"; }
	  if (newlife==4) {
   cout<<endl<<"Head-Body-RightArm-LeftArm"; }
	   if (newlife==5) {
   cout<<endl<<"Head-Body-RightArm-LeftArm-RightLeg"; }
	   if (newlife==6) {
		   cout<<endl<<"Head-Body-RightArm-LeftArm-RightLeg-LeftLeg"; 
		   cout<<endl<<"Sorry you lost! HANGMAN!!"<<endl<<endl;
		   

	   }}
   system("pause");
   getch();
   return 0;
}


I still cannot figure out how to make the game: keep track of previously guessed letters, so the user will not guess the same letter twice.

Well, the user has up to 6 guesses, so you could store his guesses, as they come, into a char array of length 6. The user's first guess would go into the first slot. For every other guess, you'd check the array and see if the current guess is in there. If so, then you say the user already guessed that and ask for another letter. You would do this in a loop until they put a valid guess. Say it's the user's fifth guess, you would check the array from the first to the fourth slot. If the user didn't guess the same char as he did before, then the current char goes in the fifth slot.

Have a function that takes a char array and returns a char array of *'s of the same length as the original char array.
Have another function that takes a char and a char array, and checks to see if that char is in the char array....

I don't know if these are part of your requirements or if you're just thinking aloud or something, but for these char arrays, you would also have to pass in their length. Otherwise, the function would not know when to stop looking. You could also designate a character as a terminator, such as '0'. That way, you'd know when to stop the loop if a length was not given.

If you need to implement these functions for whatever reason, for the first one, you would need to somehow know the length of the array (either the length is passed in or use a terminator character). Once you know the length, you would need to dynamically allocate the char array and put an asterisk for every character. You would use dynamic allocation because the length of the array is not known at compile time.

The second one is pretty straightforward. Just loop through the array given the length or look for a terminator, and if the character is spotted, return true. Otherwise, return false.
Well, the user has up to 6 guesses, so you could store his guesses, as they come, into a char array of length 6. The user's first guess would go into the first slot. For every other guess, you'd check the array and see if the current guess is in there. If so, then you say the user already guessed that and ask for another letter. You would do this in a loop until they put a valid guess. Say it's the user's fifth guess, you would check the array from the first to the fourth slot. If the user didn't guess the same char as he did before, then the current char goes in the fifth slot.


The user has six wrong guesses, but as long as he guesses right he can have more depending on the length of the word, does this affect what you said?

I understand what you say haha but as a C++ Newb I cannot seem to write it in code.....so how exactly do you store stuff in an array and check for past guesses? I understand it is a loop but could you guys give me an example in code so I can visualize it and see what Im doing wrong??
The user has six wrong guesses, but as long as he guesses right he can have more depending on the length of the word, does this affect what you said?

Actually, yes :). Instead of an array, you should use a std::vector.

so how exactly do you store stuff in an array and check for past guesses?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#include <vector>
#include <iostream>
using namespace std;

int main()
{
     vector<char> pastGuesses;

     //Let's say the user is on guess 4     
     pastGuesses.push_back('a'); //guess 1
     pastGuesses.push_back('e'); //guess 2
     pastGuesses.push_back('i'); //guess 3

     char currentGuess = 'e'; //guess 4

     for(vector<char>::iterator itr=pastGuesses.begin(); itr != pastGuesses.end(); itr++)
     {
          //"itr" points to the current char
          if(*itr == currentGuess) //might want to check for capitalization as well
          {
               //user already guessed this letter
          }
     }
     return 0;
}
Is there a way to do this with arrays or function? haha cuz I have not learned about vectors yet so... I kinda dont understand it much. Unless vectors are much easier and I could learn them fast
With arrays, you would have to use dynamic memory allocation. You could also do this with a linked list. Vectors are easier, though. I would still recommend creating a dynamic array using dynamic memory allocation as an exercise.

Is there a way to do this with ... function[s]?

Yes. You could put any code into a function. You could write a function that takes in the vector and the char and returns a bool saying whether or not the char is in the vector.

Edit: Actually, you could use a static char array for the guesses: char guesses[26]; since there are only 26 letters in the alphabet to choose from.
Last edited on
could you make an example code for the static char array? I get the idea but I still dont understand how to store the guesses and check weather or not the user has already guessed that
http://www.cplusplus.com/doc/tutorial/arrays/

Storing the guesses means simply placing the current guessed char in the array. If it's the first turn, it would be placed in position 0, if it's the second turn it would be placed in position 1, etc. To check if the user already guessed a char, you should loop over the array and check if the char is already in it.
Ok this is what I tried... The code is not working because of the attempt to store and check the guesses... What am I doing wrong??


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
#include<iostream>
#include<conio.h>
using namespace std;

int main()
{
   char storeguess[26];
   int newlife=0;
   char letter;
   bool yes;
   char solution[100]={0};
   char newW[100]={0};
   int LENGTH;
  
   cout<<"Write a word: ";

   cin>>solution;
  
   LENGTH=strlen(solution);
    cout<<"you have six lives to guess the unknown word, it has" <<endl<<LENGTH<<endl<< "letters";

   while ( newlife <6 && strcmp(newW, solution) != 0)
   
   {
	yes=0;
	cout<<endl<<"Guess a letter: ";
	cin>>letter;

	for(int n=0; n<100; n++) {   // This is my attempt to store and check the user's guess... 
	letter=storeguess[n]; 
	if(storeguess[n] == letter){
		cout<<"You already guessed that!";} 
	}
	
	for(int n=0; n<100; n++) {
	
	if(solution[n] == letter){
		letter=solution[n];
	    newW[n]=solution[n]; 
	    yes=(1);
	cout<<"nice!"<<"You got this letter!" <<endl<<newW<<endl;} 
	}
	if (yes<0){ 
	cout<<"Sorry please try again."<<endl; 
	newlife=(newlife+1);
	cout << "you lost this many lifes: "<<newlife<<endl;
	cout<<"please continue: "<<endl<<newW;
	}
	
   if (newlife==1) {
	   cout<<endl<<"Head";}
    if (newlife==2) {
   cout<<endl<<"Head-Body"; }
	 if (newlife==3) {
   cout<<endl<<"Head-Body-RightArm"; }
	  if (newlife==4) {
   cout<<endl<<"Head-Body-RightArm-LeftArm"; }
	   if (newlife==5) {
   cout<<endl<<"Head-Body-RightArm-LeftArm-RightLeg"; }
	   if (newlife==6) {
		   cout<<endl<<"Head-Body-RightArm-LeftArm-RightLeg-LeftLeg"; 
		   cout<<endl<<"Sorry you lost! HANGMAN!!"<<endl<<endl;
		   

	   }}
   cout<<"YOU WIN!!";
   system("pause");
   
   getch();
   return 0;
}

1
2
3
4
5
for(int n=0; n<100; n++) {   // This is my attempt to store and check the user's guess... 
	letter=storeguess[n]; 
	if(storeguess[n] == letter){
		cout<<"You already guessed that!";} 
	}


Here and on the lines above, you are looping through this section of the code 100 times.
Say, on the 30th iteration, it is going to check in storeguess[30] is equal to letter.
But storeguess has only 25 elements. Hence it will go out of bounds. Set condition to n < 26
That and you should be assigning letter to storeguess[n] (not the other way around) only once per guess, provided letter is not in the array already. Assigning it 100 times per guess does not make any sense.
Pages: 12