Thread: Getting HangMan to accept lowercase letters and print them in uppercase

  1. #1
    Registered User
    Join Date
    Apr 2018
    Posts
    41

    Getting HangMan to accept lowercase letters and print them in uppercase

    I wrote a very simple Hangman game that requests user input then makes the user guess up to six times.

    The first letter of the word is always shown and if the user inputs the same letter that has already been uncovered it is not seen as a mistake,

    I want to improve my code to make it accept lowercase input if the hangman string consists of Uppercase letters.

    For example if the input string is "HELLO" and the user sees this H_____ on the console and he inputs lowercase 'e' then the letter should be uncovered and printed as a capital letter as the input string.

    So after the user inputs e the output should look like this HE___

    However with the way I implemented it just converts all uppercase Letters to lowercase Letters.







    How can I make the code accept lowercase userinput and print out Uppercase user input if a Uppercase letter is in the string?
    Code:
    
    
     int main(void)
        {
            char hangmanWord[100], tempWord[100];      
            char hangmanOutput[100];                    
            int wrongTry = 6 , matchFound = 0;         
            int tries = 0;                             
            int counter = 0 , position = 0, winner, length , i;
            char alphabetFromUser;
            scanf("%s",hangmanWord);
            
            getchar();
            length = strlen(hangmanWord);
            
             for( i = 0; i < length ; i++)
            {   
                hangmanOutput[i] = '_';
                hangmanOutput[length] = '\0';
            }
            
            for(i = 0 ; i < length ; i++)
            
            {   
                
                if(i==0){
                printf("%c",hangmanWord[0]);
                
                }
                
                printf("%c",hangmanOutput[i]);  //line output 
                 
                 if(i==length-1){
                     printf("(%d)",tries);
                 }
                 
            }
            
            while(wrongTry != 0)                        /**while loop for exiting the program when no try left**/
            {
                matchFound = 0;
                putchar('\n');
                printf("letter: ");
                scanf("%c",&alphabetFromUser);
                fflush(stdin);
                if (matchFound != 2)
            {
                for(counter=1;counter<length;counter++)    /**for loop to check whether player input alphabet exists or not in the word**/
                {
                
                    if(isupper(hangmanWord[counter])){
                         
                        hangmanWord[counter] = tolower(hangmanWord[counter]);
                         }
                  
                    if(alphabetFromUser==hangmanWord[counter])
                     {
                       matchFound = 1;
                             }//end of if()
                    }//end of
            
             if(matchFound == 0)                      /**in case of wrong guess**/
                {
                      wrongTry--;
                      tries++;
                }//en
            else
               {
                 for(counter = 0; counter < length; counter++)
                     {
                         matchFound = 0;
                         if(alphabetFromUser == hangmanWord[counter])
                      {
                          position = counter ;
                          matchFound = 1;
                      }//end of if
                      if(matchFound == 1)
                      {
                         for(i = 0 ; i < length ; i++)
                         {
                              if( i == position)
                                {
                                  hangmanOutput[i] = alphabetFromUser; /**Put the alphabet at right position**/
                              }
                              else if( hangmanOutput[i] >= 'a' && hangmanOutput[i] <= 'z' ) /** If the position already occupied
                                                                                          by same alphabet then no need to
                                                                                          fill again EASY!! and continue */
                              {
                                  continue;
                                }
        
                              else
                              {
                                  hangmanOutput[i] = '_';            /** Put a underscore at not guessed alphabet position **/
                              }
                        }
                        
                         tempWord[position] = alphabetFromUser;      /**put the alphabet in another char array to check with the original word**/
                        tempWord[length] = '\0';   
                                     /**put the NULL character at the end of the temp string**/
                        winner = strcmp(tempWord+1,hangmanWord+1);      /**upon True comparison it will return 0**/
        
                        if(winner == 0)                             /**if the player guessed the whole word right then he/she is the WINNER**/
                        {
                            for(i = 0 ; i < length ; i++)
            
            {   
                if(i==0){
                printf("%c",hangmanWord[0]);
                
                }
                
                printf("%c",hangmanOutput[i+1]);  //line output  
                 if(i==length-1){
                     printf("(%d)",tries);
                 }
            }     
                            getchar();
                            return 0;
                        }//end of inner if
                   }//end of outer if
                }//end of for loop
              }//end of else
            } // end of if(matchFound != 2) condition
       
        for(i = 0 ; i < length ; i++)
            {   
                if(i==0){
                printf("%c",hangmanWord[0]);
                
                }
            
                printf("%c",hangmanOutput[i+1]);  //line output  
                 if(i==length-1){
                     printf("(%d)",tries);
                 }
            }
            getchar();
            }
    
                  if(wrongTry <= 0)                                 /**if the player can not guess the whole word in 5 chaces**/
              {
                  putchar('\n');
                  printf("DEAD\n");
                  return 0;
              }
        getchar();
            return 0;
        }

  2. #2
    Registered User
    Join Date
    Apr 2018
    Posts
    41
    I am almost done with the code , it's just that I can't figure it out. I have been trying for hours and I would be really happy if someone could help me

  3. #3
    Registered User
    Join Date
    Dec 2017
    Posts
    952
    Your code is too much of a mess to fix.
    Scrap it and start anew.
    What you are trying to do is way simpler than you are making it.

    And you need to learn to use functions!
    And your indentation is crap!
    If you want the truth to stand clear before you, never be for or against. - Sent-ts'an

  4. #4
    Registered User
    Join Date
    Aug 2019
    Location
    inside a singularity
    Posts
    306
    Apart from everything that John points out (yep, it's crap), if all you want to do is print a lowercase letter in uppercase, subtract the value 32 from it and then print it.

    So, let's say, you have 'a' entered by the user in your alphabetfromuser, when printing it, instead of printing alphabetfromuser, print (alphabetfromuser - 32). It's a simple ASCII value hack.
    "Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the Universe trying to produce bigger and better idiots. So far, the Universe is winning." - Rick Cook, The Wizardry Compiled

  5. #5
    Registered User
    Join Date
    Dec 2017
    Posts
    952
    @zeus, It's better to use toupper.

    @obvious, Here's how I might do it, but it's not well-tested.

    Exposing the first letter is kind of strange. That's not usually how hangman works. Also, it would be useful to show the unguessed letters. And only allowing 6 guesses might not work for longer words!

    Modern style is to declare variables (and initialize them if possible) where they are first used, not all at the top of the function. In particular, loop indices should be declared in the for loop head.

    Your variable names are generally too long. It just makes things less readable. The rule of thumb (smack!) is, the larger the scope, the longer the name. So, all things being equal, i is better than index (or counter).

    For boolean values you can include <stdbool.h> and use bool, true, and false instead of int, 1, and 0.

    "end of ..." comments are just clutter.

    It is "undefined behaviour" to flush the input stream. It apparently works as you might expect in windows, which is very handy, but unfortunately it doesn't work in linux. It's best to try write the program so that it is not needed, and when it is needed, use getchar() in a loop until you read the newline.
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <stdbool.h>
    #include <string.h>
    #include <ctype.h>
     
    #define MAX_WORD 100
     
    int get_word(char *word, int size) {
        fgets(word, size, stdin);
        int len = strlen(word);
        if (len && word[len - 1] == '\n')
            word[--len] = '\0';
        for (int i = 0; i < len; ++i)
            if (isalpha(word[i]))
                word[i] = toupper(word[i]);
            else
                return -1;
        return len;
    }
     
    void create_output(char *output, int len) {
        for (int i = 0; i < len; ++i)
            output[i] = '_';
        output[len] = '\0';
    }
     
    void print_output(const char *output, const char *alpha, int tries) {
        printf("(%d)  ", tries);
        for (int i = 0; output[i]; ++i)
            printf("%c ", output[i]);
        printf("  %s\n", alpha);
    }
     
    bool play_game(const char *word, int len) {
        char alpha[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
        char output[MAX_WORD];
        create_output(output, len);
        int tries = 0, guessed = 0;
        while (tries < len && guessed < len) {  // using word length for number of tries (?!)
            print_output(output, alpha, tries);
            printf("Guess: ");
            char guess;
            scanf(" %c", &guess);
            guess = toupper(guess);
            if (alpha[guess - 'A'] != ' ') {
                for (int i = 0; i < len; ++i)
                    if (word[i] == guess && output[i] == '_') {
                        output[i] = word[i];
                        ++guessed;
                    }
                alpha[guess - 'A'] = ' ';
                ++tries;
            }
        }
        print_output(output, alpha, tries);
        return guessed == len;
    }
     
    int main() {
        printf("Enter word to guess: ");
        char word[MAX_WORD];
        int len = get_word(word, sizeof word);
        if (len == -1) {
            printf("The word cannot contain spaces.\n");
            return EXIT_FAILURE;
        }
        if (play_game(word, len))
            printf("You win!\n");
        else
            printf("You lose.\nThe word was %s.\n", word);
        return 0;
    }
    Last edited by john.c; 12-14-2019 at 03:41 PM.
    If you want the truth to stand clear before you, never be for or against. - Sent-ts'an

  6. #6
    Registered User
    Join Date
    Apr 2018
    Posts
    41
    Thank you for your answer. And I realized that I would probably have to start from scratch.
    But the problem I haven't been able to solve is the output.
    For example if the word that is Entered looks like this : GOodbyE
    and the user inputs lowercase o then the the uncovered letters should look like this : GOo____ so the characters should remain lowercase or uppercase when uncovered.
    I have been trying to come up with an algorithm to do that but I can't think of any

  7. #7
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    38,165
    Just maintain a parallel array of letters you've guessed correctly.
    Code:
    #include <stdio.h>
    #include <ctype.h>
    #include <string.h>
    
    void display(char *word, int *valid) {
      for ( int i = 0 ; word[i] != '\0' ; i++ ) {
        if ( valid[i] ) putchar(word[i]);
        else putchar('_');
      }
      putchar('\n');
    }
    
    void guess(char *word, int *valid, char guess) {
      for ( int i = 0 ; word[i] != '\0' ; i++ ) {
        if ( tolower(word[i]) == tolower(guess) ) {
          valid[i] = 1;
        }
      }
    }
    
    int main(void)
    {
      char hangmanWord[100] = "GOodbyE";
      int  matchFound[100] = { 1,1,1 };
      display(hangmanWord,matchFound);
      guess(hangmanWord,matchFound,'e');
      display(hangmanWord,matchFound);
      return 0;
    }
    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.

  8. #8
    Registered User
    Join Date
    Apr 2018
    Posts
    41
    hello
    Thank you for the answer

    I have one question
    How can I modify this code that it will count it as an error if the same wrong letter is inputed more than once?

  9. #9
    Registered User
    Join Date
    Aug 2019
    Location
    inside a singularity
    Posts
    306
    Have a temporary variable that stores the value of what the user enters in the previous iteration, add a check that if new input == value held by temporary variable then "Error"
    "Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the Universe trying to produce bigger and better idiots. So far, the Universe is winning." - Rick Cook, The Wizardry Compiled

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 6
    Last Post: 10-01-2014, 07:43 PM
  2. Replies: 2
    Last Post: 09-11-2013, 11:12 PM
  3. Find word with uppercase and lowercase letters
    By doia in forum C Programming
    Replies: 9
    Last Post: 07-15-2010, 08:51 PM
  4. Counting uppercase and lowercase letters in a text
    By Tintu in forum C Programming
    Replies: 2
    Last Post: 02-06-2008, 10:15 PM
  5. Uppercase & Lowercase
    By Dennis in forum C Programming
    Replies: 2
    Last Post: 11-14-2002, 08:07 AM

Tags for this Thread