Hangman Game

Discussion in 'C Programming' started by tigrfire, Nov 22, 2005.

  1. tigrfire

    tigrfire Guest

    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?
    tigrfire, Nov 22, 2005
    #1
    1. Advertising

  2. 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);
    > }
    >
    > 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.
    August Karlstrom, Nov 22, 2005
    #2
    1. Advertising

  3. In article <>,
    tigrfire <> 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
    Walter Roberson, Nov 22, 2005
    #3
  4. On 21 Nov 2005 17:25:25 -0800, "tigrfire" <> 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);
    > }
    >
    > 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>>
    Barry Schwarz, Nov 22, 2005
    #4
  5. tigrfire

    tigrfire Guest

    Barry Schwarz wrote:
    > On 21 Nov 2005 17:25:25 -0800, "tigrfire" <> 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);
    > > }
    > >
    > > 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.
    tigrfire, Nov 28, 2005
    #5
  6. On 28 Nov 2005 00:08:24 -0800, "tigrfire" <> 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);


    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>>
    Barry Schwarz, Nov 29, 2005
    #6
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Matthew
    Replies:
    2
    Views:
    454
  2. Salim

    hangman

    Salim, Mar 4, 2005, in forum: Java
    Replies:
    2
    Views:
    536
    Salim
    Mar 8, 2005
  3. Salim

    hangman

    Salim, Mar 7, 2005, in forum: Java
    Replies:
    1
    Views:
    418
    Joona I Palaste
    Mar 7, 2005
  4. Replies:
    3
    Views:
    283
    osmium
    Oct 16, 2007
  5. Ruby Quiz

    [QUIZ] Hangman (#130)

    Ruby Quiz, Jul 6, 2007, in forum: Ruby
    Replies:
    11
    Views:
    151
    James Edward Gray II
    Jul 11, 2007
Loading...

Share This Page