-2

Im making a hangman game in C, and two of its functions dont seem to be working. The code is below, the troublemakers are int check_guess and int hidden_word the others seem to work fine on their own. For some reason the check_guess function doesnt determine if a guess is correct or not and the hidden_word function barely works.

    int main(int argc, char **argv)
    {char wordfile[256], option, temp[256] ;
    char wordlist[MAX_WORDS][MAX_WORD_LENGTH] ;
    int num_words, result ;
    Game g ;`

    // seed the rand() function first
    srand ( time(NULL));

    // check to see if command line argument was given, if so use it as the filename for the words
    if ( argc > 1 ){
        strcpy ( wordfile, argv[1] ) ;
    } else {
        strcpy ( wordfile, "wordlist.txt" ) ;
    }

    // now read word file
    num_words = read_words ( wordfile, wordlist ) ;

    if ( num_words == 0 ){
        printf ( "No words were read from file, exiting\n") ;
        exit ( -1 ) ;
    }
    printf ( "Read %d words from file\n", num_words ) ;

    do {
        setup_game ( &g, wordlist, num_words ) ;
        result = play_game ( &g ) ;
        printf ( "Would you like to play again (y/n)? " ) ;
        scanf ( " %c", &option ) ;
        fgets ( temp, 256, stdin ) ; // read the rest of the line to get rid of it from stdin
    } while ( option == 'y' || option == 'Y' ) ;
    return 0 ;
}


int draw_man ( int misses ){



     char *platform[]={


                    "      ===\n",

                     "        |\n"
                     "        |\n"
                     "        |\n"
                     "       ===\n",

                     "   =====|\n"
                     "        |\n"
                     "        |\n"
                     "        |\n"
                     "       ===\n",

                     "  |=====|\n"
                     "        |\n"
                     "        |\n"
                     "        |\n"
                     "       ===\n",

                     "  |=====|\n"
                     "  O     |\n"
                     "        |\n"
                     "        |\n"
                     "       ===\n",

                     "  |=====|\n"
                     "  O     |\n"
                     "  |     |\n"
                     "        |\n"
                     "       ===\n",

                     "  |=====|\n"
                     "  O     |\n"
                     "  |-    |\n"
                     "        |\n"
                     "       ===\n",

                     "  |=====|\n"
                     "  O     |\n"
                     " -|-    |\n"
                     "        |\n"
                     "       ===\n",

                     "  |=====|\n"
                     "  O     |\n"
                     " -|-    |\n"
                     "  |     |\n"
                     "       ===\n",

                     "   |=====|\n"
                     "   O     |\n"
                     "  -|-    |\n"
                     "  //     |\n"
                     "       ===\n"

    };

    switch(misses)
    {
    case 0:
        printf("\n\n%s\n", platform[0]);
        break;
    case 1:
        printf("\n\n%s\n", platform[1]);
        break;
    case 2:
        printf("\n\n%s\n", platform[2]);
        break;
    case 3:
        printf("\n\n%s\n", platform[3]);
        break;
    case 4:
        printf("\n\n%s\n", platform[4]);
        break;
    case 5:
        printf("\n\n%s\n", platform[5]);
        break;
    case 6:
        printf("\n\n%s\n", platform[6]);
        break;
    case 7:
        printf("\n\n%s\n", platform[7]);
        break;
    case 8:
        printf("\n\n%s\n", platform[8]);
        break;
    case 9:
        printf("\n\n%s\n", platform[9]);
        break;
    }
}

int display_guesses( unsigned char guesses[] ){


for(int j=0;j<26;j++){
int i = j + 'A';
char c = (char)i;
if(guesses[j] == 1)
//printf("%d ", j);
printf("%c ", c);
}

printf("\n");
}


char read_guess ( unsigned char guesses[] ){
char c;
while(1){
printf("Enter a valid character: ");
scanf("\n%c",&c);
// printf("hi");
if(c>='a'&& c<='z'&& guesses[(int)(c-'a')] ==0)
return (char)(c-'a') +'A' ;
if(c>='A'&& c<='Z'&& guesses[(int)(c-'A')] ==0)
return c;


printf("\n Invalid Character!!\n");
}

}


// WEEK 2 FUNCTIONS
// add_guess()
// Adds the given guess to the guesses array, making the relevant entry 1. For exmpale, if guess is 'a' or 'A',
// element 0 of the guesses array is set to 1. If 'z' or 'Z' is input, then element 25 is set to 1. Your function
// should check that the character is a valid letter and return -1 if it is not.
// Returns 0 if successful, or -1 if an invalid character is entered.
int add_guess ( char guess, unsigned char guesses[] ){

    if ((guess >= 'a' && guess <= 'z') || (guess >= 'A' && guess <= 'Z')) {
        if (guess >= 'a' && guess <= 'z') {
            guesses[guess - 'a'] = 1;
        } else {
            guesses[guess - 'A'] = 1;
        }
        return 0;
    }
    return -1;
}



// check_guess()
// Checks if the given character 'guess' is contained within the string 'word'.
// Returns 1 if it is, 0 otherwise
int check_guess ( char word[], char guess ){
    
 
    int length = strlen(word); 
    int i;
    for (i = 0; i < length; ++i) {
        if (guess == word[i])
            return 1;
    }
    return 0;
}




// hidden_word()
// Creates the word that is displayed to the user, with all the correctly guessed letters
// shown, and the rest displayed as underscores.  Any non-letters (punctuation, etc) are displayed.
// The function takes two strings as inputs.  word[] is the word that the player is trying to guess,
// and display_word[] is the output string to be displayed to the player.  The guesses array is a binary
// array of size 26 indicating whether each letter (a-z) has been guessed yet or not.
// Returns 0 if successful, -1 otherwise.
int hidden_word ( char display_word[], char word[], unsigned char guesses[26] ){

  int l = strlen(display_word);
    if (l != strlen(word))
        return -1;

    //printf("%d", l);

    int i;
    for (i = 0; i < l; ++i) {
        char c1 = (display_word[i] >= 'A' && display_word[i] <= 'Z') ? display_word[i] + 32 : display_word[i];
        char c2 = (word[i] >= 'A' && word[i] <= 'Z') ? word[i] + 32 : word[i];

        if (c1 == '_') {
            if (guesses[c2 - 97] == 1)
                return -1;
            else {
                guesses[c2 - 97] = 1;
            }
        }
        else if ((c1 >= 'a' && c1 <= 'z') || (c1 >= 'A' && c1 <= 'Z')) {
            if (c2 != c1)
                return -1;
        }

    }

    return 0;

}`

john
  • 85,011
  • 4
  • 57
  • 81
  • C is not C++, tag removed – john Sep 10 '20 at 17:29
  • 1
    yo'ure not calling `check_guess`. But I see no glaring errors in it, probably something wrong with the `word` you're passing in. – yano Sep 10 '20 at 17:38
  • 1
    Have you tried running your code line by line in a debugger while monitoring the values of all variables, in order to find out at which point your program starts to not behave as intended? If you did not try this, then you may want to read this: [What is a debugger and how can it help me diagnose problems?](https://stackoverflow.com/q/25385173/12149471) You may also want to read this: [How to debug small programs?](https://ericlippert.com/2014/03/05/how-to-debug-small-programs/) The information you obtain should help you create a [mre] of your problem. – Andreas Wenzel Sep 10 '20 at 18:38

1 Answers1

0

Your function check_guess seems to work correct. I don't understand what you are doing in hidden_word.

I wrote a small test program for these functions and a modified (working) function hidden_word_2 to replace the non-working implementation in hidden_word.

#include <stdio.h>
#include <string.h>
#include <ctype.h>

int check_guess ( char word[], char guess );
int hidden_word ( char display_word[], char word[], unsigned char guesses[26] );
int hidden_word_2 ( char display_word[], char word[], unsigned char guesses[26] );

int main()
{
    char word[] = "foobarBAZ";
    char display_word[] = "_________";

    char guess[] = "abcefgzdABCDZ* or";

    char guesses[26];
    
    memset(guesses, 0, sizeof(guesses));
    
    printf("\ntest check_guess:\n\n");
    for(int i = 0; guess[i] != '\0'; i++)
    {
        int check = check_guess(word, guess[i]);
        printf("<%c> %s %d\n", guess[i], word, check);
    }

    printf("\ntest hidden_word:\n\n");
    for(int i = 0; guess[i] != '\0'; i++)
    {
        if(isalpha(guess[i]))
        {
            guesses[tolower(guess[i]) - 'a'] = 1;
        }
        int result = hidden_word ( display_word, word, guesses ); // does not work
        printf("<%c> %s %d\n", guess[i], display_word, result);
    }

    printf("\ntest hidden_word_2:\n\n");
    memset(guesses, 0, sizeof(guesses));
    for(int i = 0; guess[i] != '\0'; i++)
    {
        if(isalpha(guess[i]))
        {
            guesses[tolower(guess[i]) - 'a'] = 1;
        }
        int result = hidden_word_2 ( display_word, word, guesses );
        printf("<%c> %s %d\n", guess[i], display_word, result);
    }

    return 0;
}

int check_guess ( char word[], char guess ){
    
 
    int length = strlen(word); 
    int i;
    for (i = 0; i < length; ++i) {
        if (guess == word[i])
            return 1;
    }
    return 0;
}

// hidden_word()
// Creates the word that is displayed to the user, with all the correctly guessed letters
// shown, and the rest displayed as underscores.  Any non-letters (punctuation, etc) are displayed.
// The function takes two strings as inputs.  word[] is the word that the player is trying to guess,
// and display_word[] is the output string to be displayed to the player.  The guesses array is a binary
// array of size 26 indicating whether each letter (a-z) has been guessed yet or not.
// Returns 0 if successful, -1 otherwise.
int hidden_word ( char display_word[], char word[], unsigned char guesses[26] ){

  int l = strlen(display_word);
    if (l != strlen(word))
        return -1;

    //printf("%d", l);

    int i;
    for (i = 0; i < l; ++i) {
        char c1 = (display_word[i] >= 'A' && display_word[i] <= 'Z') ? display_word[i] + 32 : display_word[i];
        char c2 = (word[i] >= 'A' && word[i] <= 'Z') ? word[i] + 32 : word[i];

        if (c1 == '_') {
            if (guesses[c2 - 97] == 1)
                return -1;
            else {
                guesses[c2 - 97] = 1;
            }
        }
        else if ((c1 >= 'a' && c1 <= 'z') || (c1 >= 'A' && c1 <= 'Z')) {
            if (c2 != c1)
                return -1;
        }

    }

    return 0;

}


int hidden_word_2 ( char display_word[], char word[], unsigned char guesses[26] ){

  int result = 0;
  
  int l = strlen(display_word);
    if (l != strlen(word))
        return -1;

    //printf("%d", l);

    int i;
    for (i = 0; i < l; ++i) {
        char c2 = (word[i] >= 'A' && word[i] <= 'Z') ? word[i] + 32 : word[i];

        if (guesses[c2 - 97] == 1)
        {
            display_word[i] = word[i];
        }
        else
        {
            display_word[i] = '_';
            result = -1;
        }
    }

    return result;

}

You can run or debug it here: https://onlinegdb.com/r1hDWe_Ew

The result is

test check_guess:

<a> foobarBAZ 1
<b> foobarBAZ 1
<c> foobarBAZ 0
<e> foobarBAZ 0
<f> foobarBAZ 1
<g> foobarBAZ 0
<z> foobarBAZ 0
<d> foobarBAZ 0
<A> foobarBAZ 1
<B> foobarBAZ 1
<C> foobarBAZ 0
<D> foobarBAZ 0
<Z> foobarBAZ 1
<*> foobarBAZ 0
< > foobarBAZ 0
<o> foobarBAZ 1
<r> foobarBAZ 1

test hidden_word:

<a> _________ -1
<b> _________ -1
<c> _________ -1
<e> _________ -1
<f> _________ -1
<g> _________ -1
<z> _________ -1
<d> _________ -1
<A> _________ -1
<B> _________ -1
<C> _________ -1
<D> _________ -1
<Z> _________ -1
<*> _________ -1
< > _________ -1
<o> _________ -1
<r> _________ -1

test hidden_word_2:

<a> ____a__A_ -1
<b> ___ba_BA_ -1
<c> ___ba_BA_ -1
<e> ___ba_BA_ -1
<f> f__ba_BA_ -1
<g> f__ba_BA_ -1
<z> f__ba_BAZ -1
<d> f__ba_BAZ -1
<A> f__ba_BAZ -1
<B> f__ba_BAZ -1
<C> f__ba_BAZ -1
<D> f__ba_BAZ -1
<Z> f__ba_BAZ -1
<*> f__ba_BAZ -1
< > f__ba_BAZ -1
<o> fooba_BAZ -1
<r> foobarBAZ 0

You can simplify your checks for upper case letters and conversion to lowercase with functions isupper, tolower etc. from #include <ctype.h>, for example in hidden_word you can use:

        char c2 = tolower(word[i]);
Bodo
  • 9,287
  • 1
  • 13
  • 29