Hangman Game

T

tigrfire

So I'm trying to write a hangman game and the output is coming out a
little strange. Here's my code thus far:


#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>

int hangman()
{
char input;
char temp[10];
char word[][20] = {"literature","scholar", "enormous", "influence",
"publication", "pioneer", "reshape", "catalyst", "leader", "member",
"final", "phonograph", "executed",
"oldest", "people", "requiring", "screwdriver", "buckshot",
"different", "striking"};

int k = rand()%20;
int i = 0;
int r = 0;

char b[]= "____________";

int length = strlen(word[k]);
int turn = length, dummy = 0, decide = 0, z = 0;

for(i=0; i < length; i++)
{
printf("%c", b);
}

while(turn != 0)
{
if (strcmp(temp,word[k]) == 0)
{
printf("You have guessed");
}

printf("\nTurns left: ");
printf("%d", turn);

printf("\nEnter a letter to guess: ");
scanf("%c", &input);

for(r = 0; r < length; r++)
{
if(input == word[k][r] && b[r] == '_')
{
decide = 1;
turn = length - dummy;
}
else
{
decide = 0;
}
}

if(decide == 0)
{
dummy++;
turn = length - dummy;
}

for(r = 0; r < length; r++)
{
if(input == word[k][r])
{
b[r] = word[k][r];
temp[r] = word[k][r];
temp[length] = '\0';

printf("%c", b[r]);
}
z++;
}
}

if(strcmp(temp, word[k]) != 0)
{
printf("Sorry, no more turns left. The secret word was %s.",
word[k]);
}
else
{
printf("Congratulations!\nYou guessed the secret word: %s",
word[k]);
}

return 0;
}



int main()
{
char response;

do
{
hangman();

printf("Do you want to continue (y or n): ");
scanf("%c", &response);
}
while(response == 'y');

return 0;
}

This produces an output similar to this:
_________
Turns left: 9
Enter a letter to guess: b

Turns left: 8
Enter a letter to guess:
Turns left: 7
Enter a letter to guess: e
ee
Turns left: 7
Enter a letter to guess:
Turns left: 6
Enter a letter to guess:

(note: the output would have continued but I suspended it)

Here's my problem, I am trying to get the program to read the strlen
and output one * for each 'hidden' letter of the word, that doesn't
seem so bad. My real problem is that I want those asteriscks to stay
there and get replaced by the correct letter when guessed. Also, I
don't really know why it subtracts two turns away each time or
sometimes none at all. Any help?
 
A

August Karlstrom

tigrfire said:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>

int hangman()
{
char input;
char temp[10];
char word[][20] = {"literature","scholar", "enormous", "influence",
"publication", "pioneer", "reshape", "catalyst", "leader", "member",
"final", "phonograph", "executed",
"oldest", "people", "requiring", "screwdriver", "buckshot",
"different", "striking"};

int k = rand()%20;
int i = 0;
int r = 0;

char b[]= "____________";

int length = strlen(word[k]);
int turn = length, dummy = 0, decide = 0, z = 0;

for(i=0; i < length; i++)
{
printf("%c", b);
}

while(turn != 0)
{
if (strcmp(temp,word[k]) == 0)


`temp' is undefined here on the first turn.


August
 
W

Walter Roberson

So I'm trying to write a hangman game and the output is coming out a
little strange. Here's my code thus far:

printf("\nEnter a letter to guess: ");
scanf("%c", &input);

You are making a common mistake here. scanf with "%c" reads -exactly-
one character... but the user is entering *two* characters, namely
the letter they want and then the newline character. The newline
is left in the buffer to be read by the next scanf("%c").
for(r = 0; r < length; r++)
{
if(input == word[k][r] && b[r] == '_')
{
decide = 1;
turn = length - dummy;
}
else
{
decide = 0;
}
}

You don't break out of the loop when you get a match, so the
value of the variable decide will be whatever it is upon the
last iteration of the loop, at r == length-1
if(decide == 0)
{
dummy++;
turn = length - dummy;
}

Your logic about turn and decide and dummy is not obvious.
You start out by getting as many turns as there are letters in
the word, but each time you guess a letter you get an extra
turn??

for(r = 0; r < length; r++)
{
if(input == word[k][r])
{
b[r] = word[k][r];
temp[r] = word[k][r];
temp[length] = '\0';

printf("%c", b[r]);
}
z++;
}

You aren't printing a \n at the end of the line, before
going back to prompt and read another letter. You do have a \n
printed first before the "You have ... turns" output, but...
if(strcmp(temp, word[k]) != 0)
{
printf("Sorry, no more turns left. The secret word was %s.",
word[k]);
}
else
{
printf("Congratulations!\nYou guessed the secret word: %s",
word[k]);
}

In those two cases you don't put out the missing \n before the
final message, and you don't output a \n at the end of the
final message.
My real problem is that I want those asteriscks to stay
there and get replaced by the correct letter when guessed.

Your code contains no asterisks, just underscores. Supposing
that you mean underscore instead of asterisk, you will pretty
much find replacing the characters in-place to be impossible to do
in a portable manner. If it happens to be a mandatory feature
of the program, then you should look at the "curses" library
(which is not part of standard C itself.)
 
B

Barry Schwarz

So I'm trying to write a hangman game and the output is coming out a
little strange. Here's my code thus far:


#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>

int hangman()

If the function does not accept arguments, state it specifically:
int hangman(void)
{
char input;
char temp[10];

tempt is uninitialized. It also needs to be at least 12 long to hold
"publication".
char word[][20] = {"literature","scholar", "enormous", "influence",
"publication", "pioneer", "reshape", "catalyst", "leader", "member",
"final", "phonograph", "executed",
"oldest", "people", "requiring", "screwdriver", "buckshot",
"different", "striking"};

int k = rand()%20;

The 20 here is based on the first dimension of word, not the second.
If you ever change the number of strings in the initialization clause,
this will be wrong. You might want to compute the number of entries
in word with code like
int ent = sizeof word/sizeof *word;

You never seed the rand function.
int i = 0;
int r = 0;

char b[]= "____________";

int length = strlen(word[k]);
int turn = length, dummy = 0, decide = 0, z = 0;

for(i=0; i < length; i++)
{
printf("%c", b);
}

while(turn != 0)
{
if (strcmp(temp,word[k]) == 0)


This invokes undefined behavior because temp is indeterminate.
{
printf("You have guessed");
}

printf("\nTurns left: ");
printf("%d", turn);

If you want insure the output appears to the user, terminate it with
\n.
printf("\nEnter a letter to guess: ");
scanf("%c", &input);

Here is the problem you ask about. You read one character. However,
you have to type two: the character being guessed and the ENTER key.
The ENTER keys sits in the input buffer until you execute this
statement again and then it gets processed. Neither scanf nor
getchar() are particularly user friendly in this regard. Recommend
using fgets.
for(r = 0; r < length; r++)
{

The single easiest thing you can do to make your programs more
readable is adopt a consistent style of indenting, preferably at least
three characters.
if(input == word[k][r] && b[r] == '_')

Do you really expect the single character in input to equal all the
characters in word[k]?
{
decide = 1;
turn = length - dummy;
}
else
{
decide = 0;
}
}

if(decide == 0)
{
dummy++;
turn = length - dummy;
}

for(r = 0; r < length; r++)
{
if(input == word[k][r])
{
b[r] = word[k][r];
temp[r] = word[k][r];

Undefined behavior when word[k] has 11 characters or more.
temp[length] = '\0';

printf("%c", b[r]);
}
z++;
}
}

if(strcmp(temp, word[k]) != 0)
{
printf("Sorry, no more turns left. The secret word was %s.",
word[k]);
}
else
{
printf("Congratulations!\nYou guessed the secret word: %s",
word[k]);
}

return 0;
}



int main()
{
char response;

do
{
hangman();

printf("Do you want to continue (y or n): ");
scanf("%c", &response);
}
while(response == 'y');

return 0;
}

This produces an output similar to this:
_________
Turns left: 9
Enter a letter to guess: b

Turns left: 8
Enter a letter to guess:
Turns left: 7
Enter a letter to guess: e
ee
Turns left: 7
Enter a letter to guess:
Turns left: 6
Enter a letter to guess:

(note: the output would have continued but I suspended it)

Here's my problem, I am trying to get the program to read the strlen
and output one * for each 'hidden' letter of the word, that doesn't
seem so bad. My real problem is that I want those asteriscks to stay
there and get replaced by the correct letter when guessed. Also, I
don't really know why it subtracts two turns away each time or
sometimes none at all. Any help?


<<Remove the del for email>>
 
T

tigrfire

Barry said:
So I'm trying to write a hangman game and the output is coming out a
little strange. Here's my code thus far:


#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>

int hangman()

If the function does not accept arguments, state it specifically:
int hangman(void)
{
char input;
char temp[10];

tempt is uninitialized. It also needs to be at least 12 long to hold
"publication".
char word[][20] = {"literature","scholar", "enormous", "influence",
"publication", "pioneer", "reshape", "catalyst", "leader", "member",
"final", "phonograph", "executed",
"oldest", "people", "requiring", "screwdriver", "buckshot",
"different", "striking"};

int k = rand()%20;

The 20 here is based on the first dimension of word, not the second.
If you ever change the number of strings in the initialization clause,
this will be wrong. You might want to compute the number of entries
in word with code like
int ent = sizeof word/sizeof *word;

You never seed the rand function.
int i = 0;
int r = 0;

char b[]= "____________";

int length = strlen(word[k]);
int turn = length, dummy = 0, decide = 0, z = 0;

for(i=0; i < length; i++)
{
printf("%c", b);
}

while(turn != 0)
{
if (strcmp(temp,word[k]) == 0)


This invokes undefined behavior because temp is indeterminate.
{
printf("You have guessed");
}

printf("\nTurns left: ");
printf("%d", turn);

If you want insure the output appears to the user, terminate it with
\n.
printf("\nEnter a letter to guess: ");
scanf("%c", &input);

Here is the problem you ask about. You read one character. However,
you have to type two: the character being guessed and the ENTER key.
The ENTER keys sits in the input buffer until you execute this
statement again and then it gets processed. Neither scanf nor
getchar() are particularly user friendly in this regard. Recommend
using fgets.
for(r = 0; r < length; r++)
{

The single easiest thing you can do to make your programs more
readable is adopt a consistent style of indenting, preferably at least
three characters.
if(input == word[k][r] && b[r] == '_')

Do you really expect the single character in input to equal all the
characters in word[k]?
{
decide = 1;
turn = length - dummy;
}
else
{
decide = 0;
}
}

if(decide == 0)
{
dummy++;
turn = length - dummy;
}

for(r = 0; r < length; r++)
{
if(input == word[k][r])
{
b[r] = word[k][r];
temp[r] = word[k][r];

Undefined behavior when word[k] has 11 characters or more.
temp[length] = '\0';

printf("%c", b[r]);
}
z++;
}
}

if(strcmp(temp, word[k]) != 0)
{
printf("Sorry, no more turns left. The secret word was %s.",
word[k]);
}
else
{
printf("Congratulations!\nYou guessed the secret word: %s",
word[k]);
}

return 0;
}



int main()
{
char response;

do
{
hangman();

printf("Do you want to continue (y or n): ");
scanf("%c", &response);
}
while(response == 'y');

return 0;
}

This produces an output similar to this:
_________
Turns left: 9
Enter a letter to guess: b

Turns left: 8
Enter a letter to guess:
Turns left: 7
Enter a letter to guess: e
ee
Turns left: 7
Enter a letter to guess:
Turns left: 6
Enter a letter to guess:

(note: the output would have continued but I suspended it)

Here's my problem, I am trying to get the program to read the strlen
and output one * for each 'hidden' letter of the word, that doesn't
seem so bad. My real problem is that I want those asteriscks to stay
there and get replaced by the correct letter when guessed. Also, I
don't really know why it subtracts two turns away each time or
sometimes none at all. Any help?


<<Remove the del for email>>


I've worked a bit more on the program since a week ago, and I think
I've made some significant progress, but there're still a few things I
either don't understand how to do, or am doing wrong. With that said,
here's the new source:

int hangman()
{
char input;
char temp[12];
char word[][20] = {"literature","scholar", "enormous", "influence",
"publication", "pioneer", "reshape", "catalyst", "leader", "member",
"final", "phonograph", "executed",
"oldest", "people", "requiring", "screwdriver", "buckshot",
"different", "striking"};

srand((unsigned)time(NULL)); /* Provide a seed to rand() */
int k = (rand() % 20);
int i = 0;
int r = 0;

char b[]= "*******";

int length = strlen(word[k]);
int turn = 7;
int dummy = 0;
int decide = 0;

printf("\nSorry, no more turns left. The secret word was %s.\n",
word[k]);

for(i = 0; i < length; i++)
{
printf("%c", b);
}

while(turn != 0)
{
printf("\nTurns left: ");
printf("%d", turn);

printf("\nEnter a letter to guess: ");
input = getchar();
while(getchar() != '\n');

for(r = 0; r < length; r++)
{
if(input == word[k][r] && b[r] == '*')
{
decide = 1;
turn = length;
}
else
{
decide = 0;
}
}

if(decide == 0)
{
dummy++;
turn = length - dummy;
}

for(r = 0; r < length; r++)
{
if(input == word[k][r])
{
b[r] = word[k][r];
temp[r] = word[k][r];
temp[length] = '\0';

printf("%c", b[r]);
}
}
}

if(strcmp(temp, word[k]) != 0)
{
printf("\nSorry, no more turns left. The secret word was %s.\n",
word[k]);
}
else
{
printf("\nCongratulations!\nYou guessed the secret word: %s\n",
word[k]);
}

return 0;
}



int main()
{

printf(" Welcome to HANGMAN\n\n");

printf("You will be asked to guess the computer's secret word.\n");
printf("The word will be displayed as a number of *'s. Every
time\n");
printf("you guess a letter correctly, that letter will be shown in
its\n");
printf("correct position in the word. If you guess incorrectly,
the\n");
printf("number of tries you have left will be decremented. You
will be\n");
printf("given a maximum of 7 incorrect guesses.\n\n");

hangman();

return 0;
}

So, my issue, is that I need to display the current status of the
player's guesses in a format like ***.. (where * = strlen) and have it
update per guess by replacing. So if someone guesses a and it's in the
word twice it'd be like *a**a.. and so on. I also don't know what I'm
doing wrong with the guess number. If someone guesses right I don't
want guess number to change, but if wrong, just subtract one..this
isn't working either.
 
B

Barry Schwarz

snip 170+ lines of irrelevant code form previous version

Please trim your posts to include only what is relevant to your
response.
I've worked a bit more on the program since a week ago, and I think
I've made some significant progress, but there're still a few things I
either don't understand how to do, or am doing wrong. With that said,
here's the new source:

int hangman()

int hangman(void)
{
char input;
char temp[12];
char word[][20] = {"literature","scholar", "enormous", "influence",
"publication", "pioneer", "reshape", "catalyst", "leader", "member",
"final", "phonograph", "executed",
"oldest", "people", "requiring", "screwdriver", "buckshot",
"different", "striking"};

srand((unsigned)time(NULL)); /* Provide a seed to rand() */

Many pre-C99 compilers object to definitions appearing after
executable statements. Seeding rand() should be performed in main
only once before calling this function.
int k = (rand() % 20);

This 20 is based on the number of elements in word. It should not be
hardcoded. It can be computed as (sizeof word / sizeof *word).
int i = 0;
int r = 0;

char b[]= "*******";

int length = strlen(word[k]);
int turn = 7;
int dummy = 0;
int decide = 0;

printf("\nSorry, no more turns left. The secret word was %s.\n",
word[k]);

Is this really the first thing you want to print when entering the
function? While failure should be an option, it should not be
guaranteed.
for(i = 0; i < length; i++)
{
printf("%c", b);


b only contains 8 elements. This loop may try to print as many as 11.
This causes undefined behavior.
}

while(turn != 0)
{
printf("\nTurns left: ");
printf("%d", turn);

You could combine these two.
printf("\nEnter a letter to guess: ");
input = getchar();

getchar returns an int. input is a char. You need to handle
getchar() failures also.
while(getchar() != '\n');

for(r = 0; r < length; r++)
{
if(input == word[k][r] && b[r] == '*')
{
decide = 1;
turn = length;

The only change you should make to turn is to subtract one after each
guess has been process, regardless of whether the guess is correct or
not. With this code, it could change from 1 to 11.
}
else
{
decide = 0;
}
}

At the end of this loop, all the results from the first length-1
iterations are discarded and the only result that remains is the one
when r = length-1.
if(decide == 0)
{
dummy++;
turn = length - dummy;

PLEASE learn to indent.
}

for(r = 0; r < length; r++)
{
if(input == word[k][r])
{
b[r] = word[k][r];
temp[r] = word[k][r];
temp[length] = '\0';

You only need to do this once, not once per guess.
printf("%c", b[r]);
}
}
}

if(strcmp(temp, word[k]) != 0)
{
printf("\nSorry, no more turns left. The secret word was %s.\n",
word[k]);
}
else
{
printf("\nCongratulations!\nYou guessed the secret word: %s\n",
word[k]);
}

return 0;
}



int main()

int main(void)
{

printf(" Welcome to HANGMAN\n\n");

printf("You will be asked to guess the computer's secret word.\n");
printf("The word will be displayed as a number of *'s. Every
time\n");
printf("you guess a letter correctly, that letter will be shown in
its\n");
printf("correct position in the word. If you guess incorrectly,
the\n");
printf("number of tries you have left will be decremented. You
will be\n");
printf("given a maximum of 7 incorrect guesses.\n\n");

hangman();

return 0;
}

So, my issue, is that I need to display the current status of the
player's guesses in a format like ***.. (where * = strlen) and have it
update per guess by replacing. So if someone guesses a and it's in the
word twice it'd be like *a**a.. and so on. I also don't know what I'm

Forget temp. Update b as you go and print it with %s. Also compare b
with word[k].
doing wrong with the guess number. If someone guesses right I don't
want guess number to change, but if wrong, just subtract one..this
isn't working either.


<<Remove the del for email>>
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,764
Messages
2,569,566
Members
45,041
Latest member
RomeoFarnh

Latest Threads

Top