Thread: Need a little help with hangman

  1. #1
    Registered User
    Join Date
    Apr 2007
    Posts
    15

    Need a little help with hangman

    So, I've gotten the basic program down. Gotten the thing to run. It loads up the program, loads up the instructions, then puts the blanks properly with the corresponding word. Well, it asks you to guess a letter. I enter a letter (the word in the file I created is doggy) and when I press enter, it fails. Not sure why, I think that it's running perfectly. Any help would be much appriciated!

    Code:
      #include <stdio.h>
    #include <string.h>
    #include <ctype.h>
    
    #define MAX_SIZE = 20;
    #define MAX_LETTERS = 26;
    #define MAX_GUESS = 6;
    
    void instruct();
    int play_again();
    void initialize();
    int letter_check(char c);
    int won();
    
    
    char word_to_guess[20], word_in_prog[20], letters_guessed[26];
    int guess;
    
    int main()
    {
         int i;
         char c;
         FILE *in_file;
         
         in_file = fopen("wordlist.txt","r");
         
         do {
            if( feof(in_file) )
                rewind(in_file);
                
            fscanf(in_file, "%s", word_to_guess);
            
            for(i = 0; i < strlen(word_to_guess); i++) {
                  word_to_guess[i] = tolower(word_to_guess[i]);
            }
            
            initialize();
            instruct();
            do {
               printf("\n Number of tries left : %d", guess);
               printf("\n %s", letters_guessed);
               printf("\n Word to guess : ");
               
               for(i = 0; i<strlen(word_in_prog); i++)
                   printf("%c ", word_in_prog[i]);
                   
               printf("\n Please guess a letter : ");
               scanf("%c", c);
               c = tolower(c);
               letter_check(c);
               if( !letter_check(c) )
                  guess--;
                  
            } while( guess > 0 || won() );
            if( guess == 0 )
                printf("\n You LOSE!");
         } while(play_again());
         
         fclose(in_file);
    }
    
    void instruct()
    {
     printf("\n Hangman v6.9");
     printf("\n To play, guess a letter.  You get 6 wrong tries, then your man gets hung. Is that a bad thing?");
    }
    
    int play_again()
    {
        char c;
        
        printf("\n Would you like to play again? [y/n]");
        scanf("%c", &c);
        tolower(c);
        if(c == 'y')
             return 1;
        else
            return 0;
    }
    
    void initialize()
    {
         int i;
         
         guess = 6;
         
         for(i=0; i<26; i++) {
                  letters_guessed[i] = '-';
         }
         for(i=0; i<strlen(word_to_guess); i++) {
                   word_in_prog[i] = '_';
         }
    }
    
    int letter_check(char c)
    {
        int i, flag = 0;
        
        for(i = 0; i<strlen(word_to_guess); i++) {
              if(c == word_to_guess[i]) {
                   flag = 1;
                   word_in_prog[i] = c;
              }
        }
        return flag;
    }
    
    int won()
    {
        int flag = 0;
        
        if(strcmp(word_to_guess, word_in_prog)) {
            printf("\n You've WON! %s is the right answer!", word_in_prog);                     
            flag = 1;
        }
        return flag;
    }
    Again, any help on this would be awesome!

  2. #2
    Registered User
    Join Date
    Oct 2006
    Location
    Canada
    Posts
    1,243
    in the main do loop:
    Code:
               scanf("&#37;c", c);
    the 2nd argument has to be a pointer, so change 'c' to '&c'

  3. #3
    Registered User
    Join Date
    Apr 2007
    Posts
    15
    K, awesome, that solved that problem. Now, just having a problem when I guess a letter, if it's correct, it's not supposed to take away from Guesses. If it's wrong, it takes 1 away from guesses till it reaches 0. If it hits 0, it's supposed to say "you LOSE!" Well, when I've guessed the whole word, it's supposed to do the won() function. Any idea what I did wrong or any suggestion to make it do that cause I've guess the entire word and it's still asking me to guess a letter LOL

  4. #4
    Registered User
    Join Date
    Oct 2006
    Location
    Canada
    Posts
    1,243
    in your win function:
    Code:
        if(strcmp(word_to_guess, word_in_prog)) {
    strcmp will return 0 if the strings are equal, so change your if condition!

    also, look at your inner while loop condition:
    Code:
            } while( guess > 0 || won() );
    change it so the condition is: "while you have more than 0 guesses, and you havent won"

    in the play_again function, before the printf, i added: fflush(stdin);
    if it works for you without this then fine--safer to add it i think.

  5. #5
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    > safer to add it i think.
    Safer to ignore you for suggesting fflush(stdin);
    See the FAQ
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  6. #6
    Registered User
    Join Date
    Oct 2006
    Location
    Canada
    Posts
    1,243
    i ran the program and it does the printf and scanf, however so fast (because its reading left-over input) that the program just seems to exit.

  7. #7
    Gawking at stupidity
    Join Date
    Jul 2004
    Location
    Oregon, USA
    Posts
    3,218
    Salem just referenced the FAQ section. Maybe you should check it out.
    If you understand what you're doing, you're not learning anything.

  8. #8
    Registered User
    Join Date
    Oct 2006
    Location
    Canada
    Posts
    1,243
    ok i read the two entries, thanks both.

    can you post how he should rewrite his play_again function, using the safer method to clear the input buffer?

    im just confused about the mix of puts and fgets.. does this mean he has to change his previous input/outputs to puts and fgets?
    i dont get what exactly is clearing the buffer.. the while loop with getchar() right? is that the only way to do it?

    would it just be
    Code:
    int play_again()
    {
        char c;
        
        printf("\n Would you like to play again? [y/n]");
        // or do you need that while loop with getchar() here?
        if (fgets(&c, 1, stdin))
        {
           tolower(c);
           if(c == 'y')
              return 1;
           else
             return 0;
        }
    }
    Last edited by nadroj; 04-09-2007 at 08:57 AM.

  9. #9
    Gawking at stupidity
    Join Date
    Jul 2004
    Location
    Oregon, USA
    Posts
    3,218
    Personally, I would use getchar() to read one character from the input, then flush the input buffer. Here's the way I'd do it. Changes are in bold.
    Code:
    int play_again(void)  // If your function accepts 0 arguments, let the compiler know.
    {
      int c;  // getchar() returns an int
      int garbage;  // For flushing the input buffer
    
      printf("\n Would you like to play again? [y/N]"); // Common notation for showing a default choice
      fflush(stdout);  // Best to flush stdout after a prompt
      c = getchar();  // Get the user's choice
      while ((garbage = getchar()) != '\n' && garbage != EOF);  // Flush the input buffer
      c = tolower(c);  // Proper use of tolower(). It returns the new value; it doesn't modify it.
    
      return c == 'y';  // No need for the whole if/else construct. Will evaluate to 1 if true, 0 if false
    }
    Last edited by itsme86; 04-09-2007 at 09:41 AM.
    If you understand what you're doing, you're not learning anything.

  10. #10
    Registered User
    Join Date
    Oct 2006
    Location
    Canada
    Posts
    1,243
    Code:
    fflush(stdout);  // Best to flush stdout after a prompt
    or append "\n" in the print statement
    Code:
    while ((garbage = getchar()) != '\n' && garbage != EOF);  // Flush the input buffer
    the user will only have to press enter once still, not two times, right?

    the problem with scanf is that it reads the '\n' so it was carrying this over, in his code, and using the '\n' as input for the next scanf, correct?

    is there any other method to clear the input stream?

  11. #11
    Registered User
    Join Date
    Apr 2007
    Posts
    15
    Yes, any help on the subject would be awesome!

  12. #12
    Gawking at stupidity
    Join Date
    Jul 2004
    Location
    Oregon, USA
    Posts
    3,218
    the problem with scanf is that it reads the '\n' so it was carrying this over, in his code, and using the '\n' as input for the next scanf, correct?
    Actually, the problem with scanf() is that it wasn't reading the '\n'. When you type, the characters go into the input buffer. Then input functions pull from the input buffer. scanf() only reads (from the input buffer) what you tell it to. getchar() only grabs one character from the input buffer. fgets() reads one line from the input buffer, including the '\n'.

    Anything that your input function doesn't grab from the input buffer is left there and the next input function you use will start where the last one left off.

    is there any other method to clear the input stream?
    Sure, but none that are standard. The only standard method for clearing the input stream is to manually make sure you grab everything that's left in it.
    If you understand what you're doing, you're not learning anything.

  13. #13
    Registered User hamsteroid's Avatar
    Join Date
    Mar 2007
    Location
    Waterford, Ireland
    Posts
    62
    Quote Originally Posted by itsme86 View Post
    Personally, I would use getchar() to read one character from the input, then flush the input buffer. Here's the way I'd do it. Changes are in bold.
    Code:
    int play_again(void)  // If your function accepts 0 arguments, let the compiler know.
    {
      int c;  // getchar() returns an int
      int garbage;  // For flushing the input buffer
    
      printf("\n Would you like to play again? [y/N]"); // Common notation for showing a default choice
      fflush(stdout);  // Best to flush stdout after a prompt
      c = getchar();  // Get the user's choice
      while ((garbage = getchar()) != '\n' && garbage != EOF);  // Flush the input buffer
      c = tolower(c);  // Proper use of tolower(). It returns the new value; it doesn't modify it.
    
      return c == 'y';  // No need for the whole if/else construct. Will evaluate to 1 if true, 0 if false
    }
    I like that, I'm hitting that problem a lot - similar to my woe in tutorial practise of Simple Simon. Would be a good sticky if not in the faq already?

  14. #14
    Registered User
    Join Date
    Apr 2007
    Posts
    15
    Ok, changed the play_again() function but it's still not advancing once I've actually guess the letters in the word, it continues to ask me to guess a letter, even when the word is already guessed. Here's the code again, please, any help would be MUCH appriciated


    Code:
    #include <stdio.h>
    #include <string.h>
    #include <ctype.h>
    
    #define MAX_SIZE = 20;
    #define MAX_LETTERS = 26;
    #define MAX_GUESS = 6;
    
    void instruct();
    int play_again();
    void initialize();
    int letter_check(char c);
    int won();
    
    
    char word_to_guess[20], word_in_prog[20], letters_guessed[26];
    int guess;
    
    int main()
    {
         int i;
         char c;
         FILE *in_file;
         
         in_file = fopen("wordlist.txt","r");
         
         do {
            if( feof(in_file) )
                rewind(in_file);
                
            fscanf(in_file, "%s", word_to_guess);
            
            for(i = 0; i < strlen(word_to_guess); i++) {
                  word_to_guess[i] = tolower(word_to_guess[i]);
            }
            
            initialize();
            instruct();
            do {
               printf("\n Number of tries left : %d", guess);
               printf("\n %s", letters_guessed);
               printf("\n Word to guess : ");
               
               for(i = 0; i<strlen(word_in_prog); i++)
                   printf("%c ", word_in_prog[i]);
                   
               printf("\n Please guess a letter : ");
               scanf("%c", &c);
               c = tolower(c);
               if( !letter_check(c) )
                  guess--;
                  
            } while( guess > 0 || !won() );
            if( guess == 0 ) 
                printf("\n You LOSE!");
         } while(play_again());
         
         fclose(in_file);
    }
    
    void instruct()
    {
     printf("\n Hangman v6.9");
     printf("\n To play, guess a letter.  You get 6 wrong tries, then your man gets hung. Is that a bad thing?");
    }
    
    int play_again(void)  // If your function accepts 0 arguments, let the compiler know.
    {
      int c;  // getchar() returns an int
      int garbage;  // For flushing the input buffer
    
      printf("\n Would you like to play again? [y/N]"); // Common notation for showing a default choice
      fflush(stdout);  // Best to flush stdout after a prompt
      c = getchar();  // Get the user's choice
      while ((garbage = getchar()) != '\n' && garbage != EOF);  // Flush the input buffer
      c = tolower(c);  // Proper use of tolower(). It returns the new value; it doesn't modify it.
    
      return c == 'y';  // No need for the whole if/else construct. Will evaluate to 1 if true, 0 if false
    }
    
    void initialize()
    {
         int i;
         
         guess = 6;
         
         for(i=0; i<26; i++) {
                  letters_guessed[i] = '-';
         }
         for(i=0; i<strlen(word_to_guess); i++) {
                   word_in_prog[i] = '_';
         }
    }
    
    int letter_check(char c)
    {
        int i, flag = 0;
        
        for(i = 0; i<strlen(word_to_guess); i++) {
              if(c == word_to_guess[i]) {
                   flag = 1; 
                   word_in_prog[i] = c;
              }
        }
        return flag;
    }
    
    int won()
    { 
        int flag = 0;
        
        if(strcmp(word_to_guess, word_in_prog)) {
            printf("\n You've WON! %s is the right answer!", word_in_prog);                     
            flag = 1;
        }
        return flag;
    }

  15. #15
    Registered User hamsteroid's Avatar
    Join Date
    Mar 2007
    Location
    Waterford, Ireland
    Posts
    62
    Nice code Halios - I promise to look at it once I get onto arrays next - just finishing up on ifs, loops now... Looks like nice clean though.. I understand it for the most part. As you say it's hard to see from just looking at it. I guess you tried putting messages after each step to debug? Again, though, nice work.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Hangman Help - Code included
    By darren78 in forum C Programming
    Replies: 3
    Last Post: 02-17-2009, 09:35 AM
  2. Hangman Game Troubles
    By emerica240 in forum C Programming
    Replies: 9
    Last Post: 11-26-2008, 01:39 AM
  3. Hangman, Help me with the thinking
    By Livijn in forum C# Programming
    Replies: 14
    Last Post: 02-09-2008, 03:16 PM
  4. Help doing Hangman...
    By Kreative in forum C Programming
    Replies: 11
    Last Post: 08-18-2002, 09:22 PM
  5. Using 'if' with char arrays or string objects
    By c++_n00b in forum C++ Programming
    Replies: 36
    Last Post: 06-06-2002, 09:04 PM