Возникли проблемы при создании игры про палача? (с язык)

Я все еще новичок в языке C, и я пытаюсь сделать игру с палачом, но мне не удается закончить игру, когда я выигрываю.

Вот код:

const int true = 1;
const int false = 0;

char words[][20] = {
    "hangman",
    "computer",
    "programming",
    "microsoft",
    "visual",
    "studio",
    "express",
    "learning"
};
    
int isletterinword(char word[], char letter)
{
    int i;    
    for (i = 0; i < strlen(word); i++) {
        if (word[i] == letter) {
            return true;
        }
    }
    return false;
}
    
int iswordcomplete(char secretword[], char rights[])
{
    int i;    
    for (i = 0; i < strlen(secretword); i++) {            
        if (rights[i] == secretword[i] ) {                
            return true;                
        }
    }    
    return false;
}
    
void printhangman(int numofwrongs)
{
    // Line 1
    printf("\t  ______\n");

    // Line 2
    printf("\t  |     |\n");

    // Line 3
    printf("\t  |     +\n");

    // Line 4 - left arm, head and right arm
    printf("\t  |");
    if (numofwrongs > 0) printf("    \\");
    if (numofwrongs > 1) printf("O");
    if (numofwrongs > 2) printf("/");
    printf("\n");

    // Line 5 - body
    printf("\t  |");
    if (numofwrongs > 3) printf("     |");
    printf("\n");

    // Line 6 - left leg and right leg
    printf("\t  |");
    if (numofwrongs > 4) printf("    /");
    if (numofwrongs > 5) printf(" \\");
    printf("\n");

    // Line 7
    printf("\t  |\n");

    // Line 8
    printf("\t__|__\n");
}

void printletters(char letters[])
{
    int i;    
    for (i = 0; i < strlen(letters); i++) {
        printf("%c ", letters[i]);
    }
}
    
void printscreen(char rights[], char wrongs[], char secretword[])
{
    int i;
    
    for (i = 0; i < 25; i++)
        printf("\n");
    
    printhangman(strlen(wrongs));
    printf("\n");

    printf("Correct guesses: ");
    printletters(rights);
    printf("\n");
    printf("Wrong guesses: ");
    printletters(wrongs);
    printf("\n\n\n");
      
    printf("\t");
    for (i = 0; i < strlen(secretword); i++) {
        if (isletterinword(rights, secretword[i])) {
            printf("%c ", secretword[i]);
        }
        else {
            printf("_ ");
        }
    }
    printf("\n\n");
}

int main()
{
    int i;        
    int secretwordindex;    
    char rights[20];    
    char wrongs[7];    
    char guess;        

    secretwordindex = 0;
   
    srand(time(0));
    secretwordindex = rand() % 8;

    for (i = 0; i < 20; i++) {
        rights[i] = '\0';
    }
 
    for (i = 0; i < 6; i++) {
        wrongs[i] = '\0';
    }

    while (strlen(wrongs) < 6) {
        
        printscreen(rights, wrongs, words[secretwordindex]);

        printf("\nPlease enter your guess: ");
        scanf(" %c", &guess);

        if (isletterinword(words[secretwordindex],guess)) {
            
            rights[strlen(rights)] = guess;
        }

        else {
            
            wrongs[strlen(wrongs)] = guess;
        }
       
    } 

    printscreen(rights, wrongs, words[secretwordindex]);

    if ( iswordcomplete(words[secretwordindex],rights[20])==true &&  strlen(wrongs) <= 6  ) { // The if condition here might be problematic.
        printf("You have won!\n");
    }
    else { 
        printf("You have lost!\n");
    }
}

Вот сообщение об ошибке:

main.c:197:48: предупреждение: передача аргумента 2 'iswordcomplete' делает указатель целочисленным без приведения [-Wint-преобразование]
main.c:55:5: примечание: ожидается 'char *' но аргумент имеет тип 'char'


person newer    schedule 17.01.2021    source источник
comment
if ( iswordcomplete(words[secretwordindex],rights)...) достаточно   -  person IrAM    schedule 17.01.2021
comment
спасибо за помощь, это действительно помогает. Но после того, как я исправил это предложение, я все еще не могу распечатать сообщение, когда выиграю. Есть ли другие проблемы в моем коде?   -  person newer    schedule 17.01.2021


Ответы (1)


Перво-наперво: ошибка компилятора вызвана тем, что вы передаете одиночный символ в свой вызов iswordcomplete(), а не массив символов. Итак, при проверке ближе к концу вашей функции main вам нужно передать rights (без прикрас) в качестве аргумента вместо rights[20] (который, кстати, является элементом массива за пределами границ). Кроме того, на этом этапе вам не нужна вторая проверка (подсчет количества ошибок – см. далее). Вот исправление для этой части кода:

//  if (iswordcomplete(words[secretwordindex], rights[20]) == true && strlen(wrongs) <= 6) { // The if condition here might be problematic.
    if (iswordcomplete(words[secretwordindex], rights)){// && strlen(wrongs) <= 6) { // Needs the whole string as an argument
        printf("You have won!\n");
    }

Теперь, чтобы решить пару других проблем, которые мешают вашему коду работать должным образом...

(1) Ваш основной цикл while не остановится, пока вы не ввели 6 "неправильных" букв, даже если вы угадали слово правильно. Таким образом, вам нужно добавить проверку iswordcomplete() к условию while (отменяя его с помощью !оператора), чтобы продолжать выполнение цикла только, если слово не является т завершено. Как это:

    while (strlen(wrongs) < 6 && !iswordcomplete(words[secretwordindex], rights)) { // Need to break loop if we win!!

        printscreen(rights, wrongs, words[secretwordindex]);
        //... 

(2) Логика вашей функции iswordcomplete ошибочна, поскольку она вернет значение true, как только найдет какое-либо совпадение. Вместо этого вам нужны два цикла, возвращающие false, если какая-либо из букв слова не найдена в списке «прав». Вот одна из возможных версий:

int iswordcomplete(char secretword[], char rights[])
{
    int i, j;
    for (i = 0; i < strlen(secretword); i++) {
        for (j = 0; j < strlen(rights); j++) {
            if (secretword[i] == rights[j]) break;
        }
        if (j >= strlen(rights)) return false; // Didn't find this letter
    }
    return true;
}

Пожалуйста, не стесняйтесь для любых дальнейших разъяснений и / или объяснений.


Если вы (пока) не знакомы с таким использованием оператора !, вы можете явно сравнить возвращаемое значение функции с константой false, если вам так удобнее, например:

while (strlen(wrongs) < 6 && iswordcomplete(words[secretwordindex], rights) == false) { // Break loop if we win!
person Adrian Mole    schedule 17.01.2021
comment
спасибо за вашу помощь ^^ Я многому научился из вашего ответа ^^. Но у меня все еще есть проблема, когда я использую онлайн-программу запуска c, она может работать нормально. Но когда я запускаю его в Visual Studio, я получаю неверные коды. Как я могу решить эту проблему? - person newer; 17.01.2021
comment
@newer Вы имеете в виду множество предупреждений о смешивании целых чисел со знаком и без знака? Если это все, то измените переменные int на unsigned int. (Я думаю, что вы можете сделать это для всех из них, но я не хотел бы клясться этим.) В качестве альтернативы (менее хорошей) вы можете преобразовать возвращаемые значения функции strlen в int, вот так: for (i = 0; i < (int)strlen(secretword); i++) {... - person Adrian Mole; 17.01.2021
comment
спасибо, это решает проблему ^^. Но у меня все еще есть вопрос, должен ли я всегда использовать целые числа без знака? - person newer; 17.01.2021