Solucionado (ver solução)
Solucionado
(ver solução)
2
respostas

Usando Array para verificar outro Array

Antes de fazer a solução dos videos eu tentei fazer sozinho, utilizando algumas lógicas que vi no curso de Python, bom, eu utilizei um array (palavrasAcertadas) para receber a letra que está no indice de outro array (palavrasecreta) quando percorrido pelo for, ele só recebe a letra quando a condição de comparação if dele com o chute é verdadeira, quando isso acontece eu quebro o loop for e entro em outro loop que compara os dois arrays de chars índice a índice passando por um if e um else para quando for verdadeira imprimir o char e quando não for imprimir o underscore.

Até ai tudo bem, só que quando o tamanho de palavrasAcertadas fica igual ao de palavrasecreta, lógicamente o jogo acaba, pois o jogador já descobriu todos os números. O problema foi que o tamanho do array palavrasAcertadas sempre fica maior do que o array palavrasecreta no final do código.

Cheguei a fazer uns testes imprimindo o tamanho do array palavrasAcertadas a cada passagem e vi que quando eu acerto uma letra, o strlen() dele retorna o valor 3, quando eu acerto as demais, ele sempre fica estático com o valor 4, e quando completo a palavra ele retorna o valor 9. Eu não armazenei o valor dele em uma variavel, pela minha lógica o valor teria de ser atualizado sempre quando passasse pela função strlen().

Minhas duvidas são:

Porque esses valores específicos na hora que acrescento chars a esse array?

Existe uma forma de colocar o '\0' no final? Ele resolveria?

A função strlen() está sendo utilizada de forma correta a favor da minha lógica?

Que erros cometi ao utilizar essa solução para o problema?

Bom, vou deixar o código abaixo, to curtindo muito o curso.

Estou no aguardo, abraço!

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

int main(){
    printf("***************************\n\n");
    printf("Bem vindo ao Jogo da Forca!\n\n");
    printf("***************************\n\n");
    char palavrasecreta[20];

    sprintf(palavrasecreta, "MELANCIA");

    printf(" _______\n");        
    printf(" |/      |\n");      
    printf(" |      (_)\n");  
    printf(" |      \\|/\n");  
    printf(" |       |\n");    
    printf(" |      / \\ \n");   
    printf(" |       \n");           
    printf("_|___\n\n\n\n");

    printf("A palavra possui %d letras! Voce sabe qual eh a palavra?\n\n", strlen(palavrasecreta));

    char palavrasAcertadas[20];
    int acertou = 0;
    int enforcou = 0;
    int i;
    for(i = 0; i < strlen(palavrasecreta); i++){
        printf("_ ");
    }

    printf("\n\n");
    do{
        //comecar o jogo!!

        printf("Qual o seu chute?\n\n");
        char chute;
        scanf("%c", &chute);

        for(i = 0; i < strlen(palavrasecreta); i++){
            if(chute == palavrasecreta[i]){
                printf("A posicao %d tem essa letra \n", i);
                palavrasAcertadas[i] = palavrasecreta[i];
            }
        }
        for(i = 0; i < strlen(palavrasecreta); i++){
            if(palavrasecreta[i] == palavrasAcertadas[i]){
                printf("%c ",palavrasAcertadas[i]);
            }else{
                printf("_ ");
            }
        }

        printf("\n\n");
        printf("O tamanho da variavel palavrasAcertadas eh %d",strlen(palavrasAcertadas));
        printf("\n\n");
        if(strlen(palavrasAcertadas) > strlen(palavrasecreta)){
            break;
        }

    }while(!acertou && !enforcou);
    printf("Fim de JOGO!");

}
2 respostas

Olá Nicholas,

O array palavrasAcertadas não deveria ser inicializado ? Por exemplo, cada posição sendo um caracter nao letra ('?') ou um dígito (supondo que as palavras não terão números) ou ainda, via uma 'string' de tamanho 19 (exemplo, "_", ou seja, 19x o underline)?

Talvez o srtlen de "MELANCIA" dê 9 por conta de a palavra ter 8 letras e ele considerar o '\0' na contagem. Então, contar um caracter a menos pode ser uma boa (ou, se inicializar tudo com _, por exemplo, contar todos os carcteres diferentes de _).

Existe sim um modo de colocar o '\0' no final. Aí ele seria o terminador da cadeia de caracteres.

Vendo a documentacao do strlen (http://www.cplusplus.com/reference/cstring/strlen/), há atribuições ao array de chars como se fosse uma string. Então, pode-se pensar nisso para facilitar a manipulação de string até a palavra final (string contendo letras e underlines, por exemplo "MELAN__A").

Avisa aí se ajudou em algo tais explicações. Vou tentar compilar e rodar o código. Se eu tiver mais novidades, posto aqui também.

Abraço.

solução!

Olá de novo Nicholas,

Estava um pouco enferrujado no C, mas com o tempo relembrei algumas coisas. Usei esse site para rodar o código e fazer algumas alterações:

http://rextester.com/l/c_online_compiler_gcc

Tomando como base seu código, fiz algumas alterações. Além disso, incluí alguns comentários do que entendi do seu código e comentei umas implementações a mais que fiz. Não está tão modular e o main tem bastante coisa. Mesmo assim, espero que ajude:

#include <stdio.h>
#include <string.h>
#define TAMANHO_MAX 20 // Tamanho maximo dos arrays

// assinatura de funcao auxiliar
int tamLetrasCertas(char* palavrasAcertadas, int tamPalavraSecreta); 

int main(){
    printf("***************************\n\n");
    printf("Bem vindo ao Jogo da Forca!\n\n");
    printf("***************************\n\n");

    // array que guardara palavra a descobrir
    char palavrasecreta[TAMANHO_MAX];  

    // popula o array com a palavra a ser descoberta 
    sprintf(palavrasecreta, "MELANCIA"); 

    // desenha o boneco na forca :)
    printf(" _______\n");        
    printf(" |/      |\n");      
    printf(" |      (_)\n");  
    printf(" |      \\|/\n");  
    printf(" |       |\n");    
    printf(" |      / \\ \n");   
    printf(" |       \n");           
    printf("_|___\n\n\n\n");

    // como o strlen eh bastante usado, p/ haver só 1 chamada de funcao    
    int tamPalavraSecreta = strlen(palavrasecreta);

    printf("A palavra possui %d letras! Voce sabe qual eh a palavra?\n\n", tamPalavraSecreta);

    // guarda c/ letra digitada por quem esta tentando advinhar a palavra
    char palavrasAcertadas[TAMANHO_MAX]; 
    int acertou = 0;
    int enforcou = 0;
    int i;

    for(i = 0; i < tamPalavraSecreta; i++){
        printf("_ ");
    }
    // populando array dos chutes do usuario
    for(i = 0; i < TAMANHO_MAX; i++) { 
        palavrasAcertadas[i] = '0';
    }

    printf("\n\n");
    char chute = '0';

    // variavel auxiliar, para as iteracoes intermediarias
    int tamLetrasCertas = 0; 

    //comecar o jogo!!
    // se nao acertou e se ainda nao foi enforcado
    while(!acertou && enforcou < tamPalavraSecreta) { 
        printf("\nQual o seu chute?\n");

        acertou = 0;
        chute = getchar();

        printf("Chute = %c\n\n",chute);

        // verifica se o chute corresponde a ao menos uma letra da palavra secreta
        for(i = 0; i < tamPalavraSecreta; i++){
        // só recebe a letra quando o chute é verdadeiro.
            if(chute == palavrasecreta[i]){ 
                // i+1 = melhora indice da letra escrita na tela
                printf("A posicao %d tem essa letra\n", i+1); 
                palavrasAcertadas[i] = palavrasecreta[i];
                acertou = 1;
            } 
        }
        // se nao acertou o chute, maior chance de ser enforcado
        if(!acertou) { 
            enforcou++;
        }

        for(i = 0; i < tamPalavraSecreta; i++){
            if(palavrasecreta[i] == palavrasAcertadas[i]){
                printf("%c ",palavrasAcertadas[i]);
            }else{
                printf("_ ");
            }
        }

        tamLetrasCertas = tamArrayLetrasCertas(palavrasAcertadas, tamPalavraSecreta);

        printf("\n");
        printf("\nO tamanho da variavel palavrasAcertadas eh %d", tamLetrasCertas);
        printf("\nChances para nao ser enforcado: %d",(tamPalavraSecreta-enforcou));
        printf("\n\n======================================\n");

      // igual se 'palavras acertadas é igual a palavra secreta'  
      if(tamLetrasCertas >= tamPalavraSecreta){ 
            acertou = 1;
        } else {
            // limpa varivel que pode ter sido mudada antes e continuar o loop
            acertou = 0; 
        }
    }
    printf("\n\nFim de JOGO!\n");
    if(enforcou >= tamPalavraSecreta) {
        printf("Nao deu! Voce foi enforcado e perdeu!");
    } else if(acertou) {
        printf("Parabens! Voce venceu o jogo!");
    }
}

// funcao auxiliar para calcular mais facilmente o numero de letras ja acertadas pelo usuario.
int tamArrayLetrasCertas(char* palavrasAcertadas, int tamPalavraSecreta) {
    int tam = 0;
    for(int i = 0; i < tamPalavraSecreta; i++) {
        if(palavrasAcertadas[i] != '0')
            tam++;
    }
    return tam;
}

Casos de teste que usei no site que mencionei acima:

// caso de falha: ZXCVBNLKJHGF

// caso de sucesso 1: MELANCI

// caso de sucesso 2: CIAMLEN

// caso de sucesso 3: CIAMSWELN

Sinta-se à vontade para alterar e usar tal código. Se ainda tiver dúvidas, responda aí.

Se resolver, pode marcar o tópico como resolvido? :D

Abraço.