Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > Hangman Game

Reply
Thread Tools

Hangman Game

 
 
tigrfire
Guest
Posts: n/a
 
      11-22-2005
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[i]);
}

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?

 
Reply With Quote
 
 
 
 
August Karlstrom
Guest
Posts: n/a
 
      11-22-2005
tigrfire wrote:
> #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[i]);
> }
>
> while(turn != 0)
> {
> if (strcmp(temp,word[k]) == 0)


`temp' is undefined here on the first turn.


August

--
I am the "ILOVEGNU" signature virus. Just copy me to your
signature. This email was infected under the terms of the GNU
General Public License.
 
Reply With Quote
 
 
 
 
Walter Roberson
Guest
Posts: n/a
 
      11-22-2005
In article <(E-Mail Removed) .com>,
tigrfire <(E-Mail Removed)> wrote:
>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.)
--
If you lie to the compiler, it will get its revenge. -- Henry Spencer
 
Reply With Quote
 
Barry Schwarz
Guest
Posts: n/a
 
      11-22-2005
On 21 Nov 2005 17:25:25 -0800, "tigrfire" <(E-Mail Removed)> wrote:

>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[i]);
> }
>
> 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>>
 
Reply With Quote
 
tigrfire
Guest
Posts: n/a
 
      11-28-2005
Barry Schwarz wrote:
> On 21 Nov 2005 17:25:25 -0800, "tigrfire" <(E-Mail Removed)> wrote:
>
> >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[i]);
> > }
> >
> > 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[i]);
}

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.

 
Reply With Quote
 
Barry Schwarz
Guest
Posts: n/a
 
      11-29-2005
On 28 Nov 2005 00:08:24 -0800, "tigrfire" <(E-Mail Removed)> wrote:

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[i]);


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>>
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
hangman program stuck.. nid help. kaka_hunter@hotmail.com C++ 3 10-16-2007 07:13 PM
[QUIZ] Hangman (#130) Ruby Quiz Ruby 11 07-11-2007 09:01 PM
hangman Salim Java 2 03-08-2005 09:28 AM
hangman Salim Java 1 03-07-2005 06:22 PM
ServletExec hangman.jsp example problem Matthew Java 2 12-08-2004 09:22 PM



Advertisments