Sua função que está quebrando o loop do while no momento que o jogador acerta o primeiro caractere é a
bool nao_acertou() {
for(char letra : palavra_secreta) {
if(!chutou[letra]) {
return true;
}
return false;
}
}
no laço de repetição "for" você definiu que quando o jogador acertar um caractere, a função "nao_acertou" automaticamente retornará falso e irá quebrar o loop, a gente quer que só retorne falso caso todos os caracteres da palavra secreta sejam iguais ao caracteres já chutados, para isso é só fazer o seguinte...
bool nao_acertou() {
for(char letra : palavra_secreta) {
if(!chutou[letra]) {
return true;
}
}
return false;
}
apenas deixar o carinha que quebra o loop do jogo, do lado de fora do laço de repetição. Assim quando ele encontrar uma letra faltando, ele irá quebrar o laço retornando true, e não irá quebrar o loop principal do jogo(o while) retornando falso para a função "nao_acertou", só irá retornar false caso o laço FOR não pare a execução de toda a função retornando true.
e o programa está retornando a palavra secreta porque você não colocou ela dentro da condição lá no final do código, que é caso o jogador perca