سؤال

I've been working on a hangman game for a class course and I'm almost done. However, I've stumbled upon a problem that I can't seem to fix.

First, the computer choose a random word from a text file, takes the lenght of that word and with that length creates a masked copy of the original word. Then the game start. The player types in letters and if the word is completed before he/she fails six times, he wins. Otherwise, he/she loose. I think the problem with my code is when I create my mask of the word chosen by the computer, but I'm not sure.

If I run the program it looks something like this:

Chosen word: strand (first control of word chosen by computer)

Chosen word: strand (second control to see if the same word is copied from the function to the string in the main)

Chosen word: monster (this is printed by the free() function. for some reason it's one word higher)

Chosen word: strand (third control is done before the lenght of the word is copied, in order to see if it's the right word being copied, which it is)

Wordlenght: 6 (control to see if the lenght matches the word, which it does)

Mask: _ _ _ _ _ _ N (ignore the spaces between the underscores, they are only there to make it easier to see. this is where i think the problem is, because of the extra character added in the end, the "N" in this case. the number of underscores match the number of letters which is good)

Mask: _ _ _ _ _ _ N (printed by the second free() function)

Then the actual game starts. Everything else works fine (if the player aborts or looses and if the player wants or doesn't want to play again). I checked if the actual strcmp() in the int resultat (char* word, char* mask, int count) function worked, and it did. So the fault has be with the strings being compared. I think it's when I get the lenght of the chosen word with strlen(). When I get the length, I subtract with one because otherwise I would get a lenght which is too long(for example, paper would give a lenght of 6, but when I subtract with one I get 5).

If someone could help me or maybe give me some hints I would be very grateful!

#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>
#include<string.h>
#include<time.h>

#define MAX_WORD_LEN 20

char* datorns_val();
int ordlengd(char* word);
char* datorns_val_mask(char* word, int len);
int spel(char* word, char* mask, int len, int count, int result);
int resultat (char* word, char* mask, int count);
char get_user_choice();
void hangman(int count, int result);

const int MAX_GUESS = 6;
const char ABORT_CH = '0';
const int LOOSE = 0;
const int WIN = 1;
const int ABORTED = 2;

/************************************************************
 *
 *                       MAIN
 *
 *
 ************************************************************/

int main ()
{
    char word[MAX_WORD_LEN];
    char mask[MAX_WORD_LEN];
    int ch;
    int len;
    int result;
    int count;

    /*   -------------------- Programstart  -----------------*/

    srand(time(NULL));

    while (true) 
    { 
          result = 5;
          count = 0; 
          strcpy(word,datorns_val());
          printf("Valt ord 2: %s", word);
          free(datorns_val());
          len = ordlengd(word);
          strcpy(mask,datorns_val_mask(word,len));
          printf("\nMask 2: %s <-----", mask);
          free(datorns_val_mask(word,len));

          printf( "\nV\x84lkommen till HANGMAN 2014!\n");
          printf( "Du har %d gissningar p\x86 dig (avbryt med 0)\n", MAX_GUESS );
          printf( "Datorn har nu valt ett ord p\x86 %d bokst\x84ver\n", len );

          /* GAME MAIN LOOP */

          while (count < 6)
          {
                count=spel(word,mask,len,count,result);
                result=resultat(word,mask,count);
                hangman(count,result);
          }

          /* END MAIN GAME LOOP */

          if( result == WIN )
          {
              printf("\nGrattis du vann!\n");
          }
          else if( result == LOOSE )
          {
              printf("\nTyv\x84rr du f\x94rlorade! Ordet var: %s\n", word);
          }
          else
          {
              printf("Avbrutet\n");
          }     
          printf("Vill du spela igen? (j/n)");
          ch = get_user_choice();
          if (ch == 'n' || ch == 'N')
          {
                 break;
          }
    }
}
/***********************************************************
 *
 *  ---------        Funktionsdefinitioner ----------------
 *
 ***********************************************************/
char get_user_choice()
{
                  char tkn;
                  scanf(" %c", &tkn);
                  return tkn;
}
char* datorns_val()
{
    char ordlista[20];
    char* valt_ord = malloc(20);
    int random;
    int raknare = 0;
    random = rand()%4+1;
    FILE *ptr_file;
    ptr_file =fopen("hangman.dat","r");
    if (!ptr_file)
    {
                  printf("Filen kunde inte öppnas!");
    }
    while (fgets(ordlista,20, ptr_file)!= NULL)
    {
          if (raknare == random)
          {
                      strcpy(valt_ord, ordlista);
                      break;
          }
          raknare=raknare+1;
    }
    printf("Valt ord 1: %s",valt_ord);
    fclose(ptr_file);
    return valt_ord;
}
int ordlengd(char* word)
{
    printf("Valt ord 3: %s", word);
    int ordlengd;
    ordlengd=strlen(word)-1;
    printf("Ordlengd 1: %i", ordlengd);
    return ordlengd;
}
char* datorns_val_mask(char* word, int len)
{
     int j;
     char* gissning = malloc(20);
     for (j=0; j<len; j++)
     {
         gissning[j]='_';
     }
     printf("\nMask 1: %s <----", gissning);
     return gissning;
}
int spel(char* word, char* mask, int len, int count, int result)
{
     int j;
     char bokstav;
     int ratt = 0;
     printf("\nSkriv en bokstav: ");
     scanf(" %c", &bokstav);
     for(j=0; j<len; j++)
     {
              if(bokstav==word[j])
              {
                                  mask[j]=bokstav;
                                  ratt = 1;
              }
              else if(bokstav=='0')
              {
                   count = 7;
                   return count;
              }

     }
     if (ratt == 0)
     {
                    printf("\nBokstaven finns inte i ordet!\n");
                    count=count+1;
     }
     printf("Antal fel: %i\n\n", count);
     ratt = 0;
     for (j=0; j<len; j++)
     {
         printf("%c", mask[j]);
         printf(" ");
     }
     return count;
}
void hangman(int count, int result)
{
     const char* str[20]; 
     int j;   
     str[0]="\n_______ \n";
     str[1]="  | \n";
     str[2]="  O \n";
     str[3]="//|\\\\\n";
     str[4]="  | \n";
     str[5]="// \\\\\n";

     if(result != ABORTED)
     {
               for (j=0; j<count; j++)
               {
                   printf("%s", str[j]);
               }
     }
}
int resultat (char* word, char* mask, int count)
{
    char* a = "Hej";
    char* b = "Hej";
       if (count == 6)
       {
            return LOOSE;
       }
       else if (count < 6 && strcmp(mask,word) == 0)
       {
            return WIN;
       }
       else if (count == 7)
       {
           return ABORTED;
       }
}
هل كانت مفيدة؟

المحلول

There are some things around the code:

1) The first free() call in pointless:

free(datorns_val());

This reserves memory for a string and deletes it without making any use of it. So get rid of it.

2) Using fgets() to read strings from a file stores also the '\n' character at the end of the line into your string, so you must get rid of it. As a hint, I have used this sentence:

while(fscanf(ptr_file,"%s", ordlista) >0)

that does not store '\n' characters.

3) In ordlengd(char* word) function, you had problem with an extra character (the above mentioned '\n') so the length is the same as the one returned by strlen(), not the

strlen(word) - 1 

you had written.

4) You have think about another condition to end the while loop of the main function. I would suggest to add

else return 5;

at the end of resultat() function and the check this value en the while loop of the main function

while (count < 6 && result == 5)

Hope it helps

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top