1
resposta

A função imprime_palavra parece estar com a lógica invertida

Pessoal, acompanhando o curso e tentando fazer por meios próprios a função imprime_palavra está imprimindo de cara a palavra secreta . Como não estou familiarizado com o c++ ainda precisa de um empurrãozinho. Poderiam me ajudar?

#include <iostream>
#include "imprime_palavra.hpp"

void imprime_palavra(std::string& palavra_secreta, const std::map<char, bool> chutou){
    for(char letra : palavra_secreta){
        if(chutou.find(letra) == chutou.end() || !chutou.at(letra)){
            std::cout << letra << " ";
        }
        else{
            std::cout << "_ ";
        }
    }
    std::cout << std::endl;
}

![](Insira aqui a descrição dessa imagem para ajudar na acessibilidade )

Como vocês podem ver, está imprimindo a palavra logo ao iniciar o programa, o que não está correto.

1 resposta

Oi Osmar, vamos lá! Se eu entendi direito, a seguinte instrução está sempre retornando uma condição verdadeira:

if( chutou.find(letra) == chutou.end() || !chutou.at(letra)) {

Destrinchando essa linha, a gente percebe o seguinte:

1) chutou.find(letra) == chutou.end()

Estamos procurando a letra da palavra secreta no objeto chutou. Se o método find de std::map encontrar a letra, ela retorna um iterator (um objeto que contém a key e o valor). Caso contrário, ela retorna iterator end (end é como se fosse um ponteiro que aponta para o próximo elemento depois do último elemento do objeto std::map - ou seja - o final dela).

Então, a instrução chutou.find(letra) pode retornar dois valores possíveis:

  1. Caso encontre a letra: iterator (um "apontador" para o objeto com chave e valor <char, bool> de chutou)
  2. Caso não encontre a letra: iterator end (um "apontador" para além do final de chutou)

Portanto, essa condição chutou.find(letra) == chutou.end() só vai ser verdadeira, caso a letra da palavra secreta não estiver no objeto chutou e falsa se a letra estiver no objeto chutou. Meio estranho, certo? Esse é o motivo principal dessa instrução IF estar sempre retornando verdadeiro.

Um ponto interessante é o operador OU ||. Ela avalia duas expressões lógicas começando sempre pela expressão à esquerda. Se a expressão à esquerda retornar VERDADEIRO, a segunda expressão nem é executada. Com isso, provavelmente você não está passando por um segundo problema que eu notei na expressão à direita.

2) !chutou.at(letra)

O método at retorna o valor da chave caso esta chave seja encontrada. Caso contrário, ela irá lançar uma exceção dizendo que a chave não existe. Uma curiosidade é que esse método at tem a mesma funcionalidade das chaves [ ] de um array por exemplo:

chutou.at(letra)
chutou[letra]

Vamos supor que a letra exista. Assim, ela irá retornar "true" ou "false". Quando você usa o operador !, ele inverte o valor retornado. Eu não entendi também o motivo disso. Se ela não existir, o programa irá parar a execução devido ao lançamento de uma exceção não tratada (não se assuste, isso é uma feature de c++ bem parecido com o que tem em Java) .

Enfim, espero que esses detalhes te ajude a resolver o seu problema.

DICA:

Use esse site para entender o que cada método de std::map faz:

https://en.cppreference.com/w/cpp/container/map

Você pode usar ele também para consultar outros tipos de dados de STD.

Até mais.